3

What time is the start of a day, say 01/01/2010?

Is it 00:00:00:000 ? or is that midnight?

[edit]

It might be a stupid question but I'm confused because I used Calendar.set(Calendar.HOUR, 0) but this gives me a time of 12:00:00.

and now I've realised I should be using HOUR_OF_DAY

blank
  • 17,852
  • 20
  • 105
  • 159
  • For new readers to the question I recommend you don’t use `Calendar`. That class is poorly designed and long outdated and also the source of the confusion you are asking about. Instead use `ZonedDateTime` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. May 08 '21 at 00:27

3 Answers3

8

The start of the day isn't always midnight. It can depend on the time zone and date. (If the clock moves forward an hour at the start of the day, it will start at 1am.)

That's why Joda-Time has things like LocalDate.toDateTimeAtStartOfDay - and they're well worth using.

But yes, normally it's at 00:00:00 which is midnight. (This can also be formatted as "12am" depending on your locale etc.)

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Really? I had no idea there was a time zone dependence. Thanks for the heads up, Jon. I'm going to remove my (incorrect) answer. – duffymo Jan 02 '10 at 18:35
  • 2
    I wouldn't know either, if it hadn't bitten me before. I don't know how many time zones do "spring forward" at midnight - I believe there's one in South America that does though. – Jon Skeet Jan 02 '10 at 18:44
  • I don't think any current DST rules have a transition from midnight to 1AM, but many historical rules had. Using the Java calendar to set such a date to midnight causes the calendar to fallback to the first existing time on that actual date, just as Joda's toDateTimeAtStartOfDay. – jarnbjo Jan 02 '10 at 23:06
  • @jarnbjo: If there have been changes on that front they must have been pretty recent - I'm pretty sure I had an exception due to this case just last year. Will have a look some time. – Jon Skeet Jan 03 '10 at 08:41
  • @JonSkeet Did you mean `DateTime` rather than `LocalDate`? – Basil Bourque Jun 19 '14 at 16:02
  • FYI Joda-Time has some midnight-related classes and methods. But they were deprecated, supplanted by the `withTimeAtStartOfDay` method mentioned in the answer. – Basil Bourque Jun 19 '14 at 16:04
2

java.time

Normally, the start of the date is 00:00 hours but it may vary because of DST. Therefore, instead of assuming it to be 00:00 hours, the safest option is to use LocalDate#atStartOfDay(ZoneId zone).

Demo:

import java.time.LocalDate;
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) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/u", Locale.ENGLISH);
        LocalDate date = LocalDate.parse("01/01/2010", dtf);

        // In JVM's timezone
        ZonedDateTime startOfDay = date.atStartOfDay(ZoneId.systemDefault());
        System.out.println(startOfDay);

        // In custom timezone
        startOfDay = date.atStartOfDay(ZoneId.of("Africa/Johannesburg"));
        System.out.println(startOfDay);
    }
}

Output:

2010-01-01T00:00Z[Europe/London]
2010-01-01T00:00+02:00[Africa/Johannesburg]

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.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
1

ZonedDateTime from java.time

Like Arvind Kumar Avinash already does in a good answer, I recommend that you use java.time, the modern Java date and time API, for your date and time work.

If you had got a LocalDate or a string holding a date without time of day, that answer shows you how to get the start of the day (the first moment of the day). If you had already got a ZonedDateTime, you may simply use its truncatedTo method. Let’s take one of those interesting examples where the clocks are turned forward at 00:00 so the first moment of the day is 01:00:

    ZonedDateTime zdt = ZonedDateTime.of(
            2000, 9, 17, 15, 45, 56, 789000000, ZoneId.of("Asia/Dili"));
    System.out.println("We got date and time: " + zdt);

    ZonedDateTime startOfDay = zdt.truncatedTo(ChronoUnit.DAYS);
    System.out.println("Start of day is:      " + startOfDay);

Output:

We got date and time: 2000-09-17T15:45:56.789+09:00[Asia/Dili]
Start of day is:      2000-09-17T01:00+09:00[Asia/Dili]

What went wrong in your code?

You’ve already said it in an edit to the question, but it deserves to be mentioned in an answer too: Calendar.HOUR refers to, from the documentation:

Field number for get and set indicating the hour of the morning or afternoon. HOUR is used for the 12-hour clock (0 - 11). …

So if your Calendar was already holding a time in the afternoon (12 noon or later), setting HOUR to 0 gives you 12 noon (12:00 on a 24 hour clock), not 12 midnight (00:00 on a 24 hour clock). Except that the time of the hour may still be non-zero, so you may also get, for example, 12:34:45.567. The Calendar class was cumbersome to work with.

In any case the Calendar class was poorly designed and is long outdated, so you shouldn’t need to worry; just don’t use that class anymore.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161