0

I need to check if a Unix time-stamp (stored as a long) represents today (in my time zone). This is where I am at, but it doesn't seem very elegant:

Calendar tokenTimestamp = Calendar.getInstance();
tokenTimestamp.setTimeInMillis(foo.getDateTimeCreated());

Calendar now = Calendar.getInstance();

if (tokenTimestamp.get(Calendar.DAY_OF_MONTH) != now.get(Calendar.DAY_OF_MONTH)
        || tokenTimestamp.get(Calendar.MONTH) != now.get(Calendar.MONTH)
        || tokenTimestamp.get(Calendar.YEAR) != now.get(Calendar.YEAR)) {
    // Not today...
}

Is there a more correct and/or elegant way to do this?

user3352488
  • 281
  • 3
  • 15
  • 2
    Do you have to use `java.util.Calendar` rather than the `java.time` API? The latter would be considerably simpler... – Jon Skeet Jun 26 '17 at 15:16
  • I'm on Android so would have to be Java 7. – user3352488 Jun 26 '17 at 15:17
  • This is about codereview and should be ask at https://codereview.stackexchange.com – Jens Jun 26 '17 at 15:17
  • 1
    Simply put: no, there is no better way. You’re doing it the best way it can be done in Java 7. – VGR Jun 26 '17 at 15:19
  • 2
    Beg to differ, @VGR. There are more than one way I would consider better. – Ole V.V. Jun 26 '17 at 17:47
  • 3
    First off, “today” is a time zone dependent concept, so it would be better to give an explicit time zone to the operation so the reader is reminded that the time zone matters and knows which time zone you intended (rather than thinking you may have forgot to give one). – Ole V.V. Jun 26 '17 at 17:48
  • @OleV.V. Good point. Timezone differences can definitely corrupt the result. (I’ve actually seen that happen in commercially deployed applications.) – VGR Jun 26 '17 at 18:01

2 Answers2

1

In Java 7's Calendar, that's probably the best you can do. I'd add just a little detail, specify in what timezone you want the date (as pointed by @Ole V.V.'s comment):

// current date in system default timezone
Calendar.getInstance(TimeZone.getDefault());
// current date in Europe/London timezone
Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));

Also use IANA timezones names (always in the format Continent/City, like America/Sao_Paulo or Europe/Berlin). Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard.


The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.

For Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes, together with the ThreeTenABP (more on how to use it here).

All the classes below are under the org.threeten.bp package. As you're comparing just the date (day/month/year), I'm using the org.threeten.bp.LocalDate class. I also use org.threeten.bp.ZoneId to specify the timezone and the org.threeten.bp.Instant class to convert the long millis value to a date:

// millis value
long millis = 1498499869249L;

// get the date in system default timezone
LocalDate dt = Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault()).toLocalDate();
// check if it's equals to today
System.out.println(dt.equals(LocalDate.now(ZoneId.systemDefault())));

If you want a different timezone, replace ZoneId.systemDefault() by ZoneId.of("Europe/London") (or whatever timezone name you want - you can get a list of all available timezones by calling ZoneId.getAvailableZoneIds()).

And don't forget to use the same timezone in both lines, to make sure you're comparing the correct values.


If you want to compare the date and time (day/month/year and hour/minute/second), you can use a org.threeten.bp.LocalDateTime instead:

// get the date in system default timezone
LocalDateTime dt = Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault()).toLocalDateTime();
// check if it's equals to today
System.out.println(dt.equals(LocalDateTime.now(ZoneId.systemDefault())));
  • 2
    Good answer. In all the snippets I would want to store the time zone (either `TimeZone` or `ZoneId`) in a variable to make quite sure I use the same zone every time even if someone changes the default underway. Just to guard against this unlikely but potentially nasty corner case. – Ole V.V. Jun 26 '17 at 19:01
0

You can take the approach from here: You define a start date (today, at 0am) and an end date (today, 23:59pm). Then you can check if the time is in between with:

boolean isWithinToday(Date testDate) {
   return !(testDate.before(startTime) || testDate.after(endTime));
}
Patrick
  • 184
  • 1
  • 1
  • 12