1

I need to calculate 00:00 AM of today and 00:00 AM of tomorrow.

I'm trying to like this

private static void some(final Date now) {
    final Calendar calendar = Calendar.getInstance();
    calendar.setTime(now);
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    final Date min = calendar.getTime(); // 00:00 AM of today
    calendar.add(Calendar.DATE, 1);
    final Date max = calendar.getTime(); // 00:00 AM of tomorrow
}

Is there any nicer (or simply other) way for doing this?

Jin Kwon
  • 20,295
  • 14
  • 115
  • 184
  • Can you use the java time API (java 8)? – assylias Jul 27 '16 at 08:38
  • @JinKwon Do you want midnight in your local timezone? In UTC? – assylias Jul 27 '16 at 08:54
  • @assylias Yes!! I'm writing business codes working with the DB whose locale is same to AS. – Jin Kwon Jul 27 '16 at 09:07
  • @JinKwon (a) Don't confuse locale with time zone. Completely unrelated. Locale only matters when creating Strings to represent the date-time value. Locale determines two things: human language used for translating name of day & month, and cultural norms that control period vs comma and other such issues. (b) what did you mean by “AS”? – Basil Bourque Jul 27 '16 at 18:30

1 Answers1

3

There are a couple of problems with what you're trying to do.

Firstly, "today" is not a well-defined concept for a Date. Date is basically just a wrapper around number of milliseconds since Unix epoch: the calendar date corresponding to that instant is different, depending upon which timezone you are in.

For instance, the instant represented by new Date(1469584693000) was on 2016-07-27 in London; but it was on 2016-07-26 in NYC.

You can, of course, rely upon the JVM's default timezone, but this makes the behaviour of the code dependent upon the JVM's configuration.

Secondly, "midnight" isn't something that always exists: e.g. in the Asia/Gaza timezone, daylight savings starts at midnight, meaning that the clock jumps from 23:59:59 on one day to 01:00:00 on the next (see Ideone demo). This is why the Java 8 time API has methods called atStartOfDay, not atMidnight.

So, you can put this together, in Java 8, to:

private static void some(final Date now, ZoneId zone) {
  Instant instant = now.toInstant();  // Convert from old legacy class to modern java.time class.
  ZonedDateTime zdt = instant.atZone(zone);  // Apply a time zone to the UTC value.
  LocalDate today = zdt.toLocalDate();  // Extract a date-only value, without time-of-day and without time zone.

  ZonedDateTime startOfDayToday = today.atStartOfDay(zone);  // Determine first moment of the day.
  ZonedDateTime startOfDayTomorrow = today.plusDays(1).atStartOfDay(zone);

  // ...
}

Of course, you can directly pass in the Instant or ZonedDateTime to the method; and you can use an explicit constant ZoneId, e.g. ZoneId.of("UTC").

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Andy Turner
  • 137,514
  • 11
  • 162
  • 243