Please make the distinction between a time zone and an offset. Your time zone is Europe/Kiev (English spelling of place names in time zone IDs is used where an English spelling exists). Europe/Kiev is at offset +02:00 here in January. It was at offset +03:00 until 27 October and will be again from 29 March because of summer time (daylight saving time, DST). And what may surprise some, it was on offset +03:00 permanently from 1944 through 1980. So at the epoch — Jan 1 1970 00:00 UTC — the time in Ukraine was 3:00. So for Ukraine this part of your output is correct.
In short: a time zone encompasses the historic, present and known future offsets from UTC/GMT used in that time zone. GMT+02:00 is an offset, it is not a time zone.
java.time and ThreeTenABP
Here is the modern way of obtaining what I think you were after:
ZonedDateTime epochInUkraine = Instant.EPOCH.atZone(ZoneId.of("Europe/Kiev"));
System.out.println(epochInUkraine);
Output from these lines is:
1970-01-01T03:00+03:00[Europe/Kiev]
If you want a printout similar to the one you got from printing an old-fashioned java.util.Date
object:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
System.out.println(epochInUkraine.format(formatter));
Thu Jan 01 03:00:00 EET 1970
You can probably find an output format that suits your audience still better, though. I am leaving that part to yourself.
What went wrong?
Why does Calendar.setTimeInMillis(0)
set incorrect time?
It does not. The Calendar
class and its subclasses are poorly designed and long outdated, but setTimeInMillis(0)
sets the correct time. You also already noticed that when your Calendar
is in UTC, its clock hour of the morning or afternoon (0 thorugh 11) is 0. How you got the output of 03:00:00 GMT+02:00
with the contradiction between 03:00 and +02:00? Possible explanations include:
- Most likely an error on your side. Either this didn’t come from the
Calendar
that you had set to 0, or your copied the output inaccurately when typing your question. If you check once more whether you can reproduce that output, I’d be curious to hear.
- Less likely a bug in
Date.toString()
, which gets called implicitly when you print the Date
that you get from cal.getTime()
.
- Still less likely a bug in
Calendar.getTime()
that gives you the wrong Date
object from the Calendar
.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from
org.threeten.bp
with subpackages.
Links