0

I set my Calendar instance to a UTC date at 00:00 however once i return the result its 1 hour ahead

Calendar cal = Calendar.getInstance(TIMEZONE_UTC, Locale.ENGLISH);
cal.set(2017, 12 - 1, 15);
cal.set(Calendar.AM_PM, Calendar.AM);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
System.out.println(cal.getTime());
// Fri Dec 15 01:00:00 CET 2017 but should be 00:00:00

I suppose there is the winter/summer offset but I didn't found any description in the Gregorian or Calendar Element to handle this issue

4
  • 1
    You are getting the correct time, 00:00:00 UTC. What is fooling you is that Date.toString() (implicitly called from System.out.println()) is converting the time to your own time zone (using the JVM time zone setting) for the string generated. Commented Dec 21, 2017 at 9:54
  • 1
    I recommend you stop using the long outdated Calendar class. java.time, the modern Java date and time API, is so much nicer to work with. And using a ZonedDateTime (or OffsetDateTime or Instant) from the modern API will solve your issue. Commented Dec 21, 2017 at 10:28
  • Are you expecting midnight on this date in UTC to also be midnight (00:00:00) in the CET time zone simultaneously? Not possible, as CET is an hour ahead of UTC on that date for that particular unidentified zone. I say unidentified because CET is not a time zone but the effect of a time zone such as Europe/London. Commented Dec 21, 2017 at 11:04
  • 1
    In fewer words: 00:00:00 UTC on that date is 01:00:00 CET. Commented Dec 21, 2017 at 11:14

2 Answers 2

4

I am getting the impression that you are really after just the date of December 15, 2017, and just wanted to make sure that there is no unexpected hour-of-day? If so, LocalDate from java.time, the modern Java date and time API, is made for you:

LocalDate ld = LocalDate.of(2017, Month.DECEMBER, 15);
System.out.println(ld);

This prints

2017-12-15

No hours, minutes or seconds to be concerned about.

If you do need a date-time at 00:00 UTC (the time I used to call midnight until Basil Bourque’s comment), there are several ways to obtain it. One of them is:

    OffsetDateTime utcDateTime = LocalDateTime.of(2017, Month.DECEMBER, 15, 0, 0)
            .atOffset(ZoneOffset.UTC);
    System.out.println(utcDateTime);

This prints

2017-12-15T00:00Z

The Z in the end means UTC or offset zero. You see that the time of day is 00:00 as you wanted.

The Calendar class that you used in the question is long outdated, so I recommend you don’t use it anymore. java.time, the modern Java date and time API also known as JSR-310, is so much nicer to work with.

What went wrong in your code?

While a Calendar does contain a time zone (you initialized it to TIMEZONE_UTC), a Date (another outdated class) doesn’t. So when you convert to Date using cal.getTime() you lose the information that you wanted the time to be in UTC. Next (and this confuses many), when you print the date, you implicitly call Date.toString(), and this method grabs your JVM’s time zone setting and produces a string with the time in this time zone. So apparently you are (like I am) in a time zone that is at UTC+01:00 in December. The following two date-times denote the same point on the timeline:

Fri Dec 15 01:00:00 CET 2017
Fri Dec 15 00:00:00 UTC 2017
Sign up to request clarification or add additional context in comments.

2 Comments

Good Answer, but I suggest using the phrase "first moment of the day" rather than "midnight". The "midnight" term is amorphous, meaning different things to different people in different contexts. Note that the Joda-Time project made a major breakthrough in dropping the concept(s) and the term, and deprecating several classes, instead going with a "start of day" concept in both the terminology and the classes.
Thx, @BasilBourque, edited.
1

The reason why you see local time printed is you're displaying it via an instance of Calendar using Date.toString() which uses the local timezone(implicitly use the system timezone).

1 Comment

This is incorrect, different semantics than the Question. The Question sets the Calendar object to 00:00:00 in UTC, then in calling Calendar::getTime instantiates a Date that carries no applicable time zone (always in UTC) but whose Date::toString dynamically applies the JVM’s current default time zone which must one of the zones an hour ahead of UTC. In contrast, this Answer sets the Calendar object to 00:00:00 in BST (London time), an entirely different moment, an hour earlier than the moment in the Question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.