JAAD
JAAD

Reputation: 12379

How to compare Two date in android?

I have a date from server in the format yyyy-mm-dd HH:mm:ss .I have the current time in millis by System.currentTimeMillis(). I want to compare both dates and see if date received from server is future date and if it is so schedule an alarm for the future date. so my question how to compare this 2 different format dates and how to get remaining time (future- current) so as to schedule the alarm.

Edit: I already tried parsing the date in millis but it doesnt return value as same format as System.currentTimeMillis(). so it fails

Upvotes: 4

Views: 16069

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79075

I recommend you do it using the modern date-time API*.

A simple way to do it using the modern API is to parse the server's date-time string into ZonedDateTime using the server's timezone and convert the resulting object into Instant which you can compare with Instant#now.

Demo:

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // An arbitrary date for demo
        String strDateTime = "2021-05-09 10:20:30";

        // Replace JVM's default time zone, ZoneId.systemDefault() with applicable time
        // zone e.g. ZoneId.of("America/New_York")
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH)
                                    .withZone(ZoneId.systemDefault());

        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);

        Instant instantServer = zdt.toInstant();
        Instant now = Instant.now();

        if (instantServer.isBefore(now))
            System.out.println("The server time is before the current time.");
        else if (instantServer.isAfter(now))
            System.out.println("The server time is after the current time.");
        else
            System.out.println("The server time is the same as the current time.");
    }
}

Output when I run it now in my system:

The server time is before the current time.

Learn more about the the modern date-time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Upvotes: 2

user2340612
user2340612

Reputation: 10703

You can parse the yyyy-mm-dd HH:mm:ss date thanks to DateFormat class (e.g. the SimpleDateFormat class). This operation will return a Date object.

You can also create a Date object from current time in milliseconds.

When you have both objects you can compare them thanks to compareTo method.

For instance the following code:

try {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date parsed = sdf.parse("2016-03-10 22:05:20");

    Date now = new Date(System.currentTimeMillis()); // 2016-03-10 22:06:10

    System.out.println(parsed.compareTo(now));
} catch (Exception e) {
    e.printStackTrace();
}

will print -1, which means that parsed is before now.

EDIT:

Here it is the code of a simple but useless application that makes use of AlarmManager.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Log.d("TAG", "From intent: "+getIntent().getStringExtra("MyEXTRA"));
}

@Override
protected void onResume() {
    super.onResume();

    try {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long parsedMillis = sdf.parse("2016-03-10 22:54:30").getTime();
        long now = System.currentTimeMillis(); // 22:54:15

        if (parsedMillis > now) {
            Log.d("TAG", "In the future!");

            AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
            Intent intent = new Intent(this, MyActivity.class);
            intent.putExtra("MyEXTRA", "From alarm");
            PendingIntent broadcast = PendingIntent.getActivity(this, 0, intent, 0);
            am.setExact(AlarmManager.RTC_WAKEUP, parsedMillis, broadcast);

        } else {
            Log.d("TAG", "In the past...");
        }


    } catch (Exception e) {
        e.printStackTrace();
    }
}

In the LogCat you will see:

03-10 22:54:20.925    3946-3946/com.example.myapp D/TAG﹕ From intent: null
03-10 22:54:21.227    3946-3946/com.example.myapp D/TAG﹕ In the future!
03-10 22:54:30.513    3946-3946/com.example.myapp D/TAG﹕ From intent: From alarm
03-10 22:54:30.577    3946-3946/com.example.myapp D/TAG﹕ In the past...

The last line is printed because the alarm causes the activity to be relaunched, hence the onResume will be called another time and System.currentTimeMillis() will be greater than the hardcoded time. As you can see, however, the alarm is correctly fired at the scheduled time.

Moreover you should consider edge cases: if parsedMillis is greater than now by only a few milliseconds, you could set an alarm that will never be fired because it is set in the past. This happens because the OS needs some time to execute your code, so you should check that parsedMillis > now + DELTA, where DELTA is a reasonable amout of time that depends on the code you execute between System.currentTimeMillis() and am.setExact(...).

Upvotes: 8

Related Questions