How to calculate wall time with UTC + TimeZone ID?

I searched for this problem but could not find clear and definitive documentation.

Assuming I have UTC and the TimeZone identifier, how do I calculate the time on the wall (= UTC time + time zone offset + daylight saving time) in Java, knowing that daylight saving time changes throughout the year?

I am looking for an example of proven code. Thanks.

+4
source share
2 answers

When you say that you have time in UTC, I assume that you keep it in Calendar ( Date does not have a time zone concept, despite the misleading toString() ). If you have time, for example. in String you can easily parse it or a calendar instance, like here:

 Calendar summer = new GregorianCalendar(DateUtils.UTC_TIME_ZONE); summer.set(2011, Calendar.JUNE, 27, 9, 0, 0); 

summer is 9:00 UTC on June 27, 2011. Now you just need to change the time zone from UTC to Melbounre, Australia:

 summer.setTimeZone(TimeZone.getTimeZone("Australia/Melbourne")); 

I will use FastDateFormat to print the date correctly:

 final FastDateFormat formatter = FastDateFormat.getDateTimeInstance(FastDateFormat.SHORT, FastDateFormat.SHORT); System.out.println(formatter.format(summer)); 

The time in Melbourne is 19:00 (+10 hours). But change the date to winter:

 Calendar winter = new GregorianCalendar(DateUtils.UTC_TIME_ZONE); winter.set(2011, Calendar.DECEMBER, 27, 9, 0, 0); System.out.println(formatter.format(winter)); 

And suddenly the time in Melbourne is 20:00 (+11 hours).

The difference proves that changing the time zone to Calendar takes into account DST. Australia has a winter time in June at UTC in Australia, so they do not observe DST.

But in winter, UTC has summer in Australia - and they switch to DST, rearranging the clock for one hour. This is the reason why in winter the difference is +11 hours rather than +10 in summer UTC.


But wait! This becomes even more interesting when several time zones observing DST are taken into account. First I create the same date in the time zone of Europe / Oslo:

 Calendar winter = new GregorianCalendar(TimeZone.getTimeZone("Europe/Oslo")); winter.set(2011, Calendar.DECEMBER, 27, 9, 0, 0); 

9:00 in Oslo in winter - 8:00 UTC, but at 19:00 in Melbourne ( +10 hours ).

But at the same time in the summer:

 Calendar summer = new GregorianCalendar(TimeZone.getTimeZone("Europe/Oslo")); summer.set(2011, Calendar.JUNE, 27, 9, 0, 0); 

Actually 7:00 UTC and 17:00 in Melbourne! +8 hours !

Somehow, people assume that the difference between two time zones is always constant ("the difference between Oslo and Melbourne is always 10 hours) - this is not true, especially when different hemispheres are taken into account.

In fact, in winter in Oslo (no DST, UTC + 1), DST is observed in Melbourne (UTC + 11). On the other hand, while summer is observed in Oslo and DST (UTC + 2), this is not observed in Melbourne (UTC + 10). Now it becomes obvious why the difference varies from 8 to 10 hours depending on the day of the year.

Also remember that the first and last day of DST is not global, but is chosen arbitrarily for each time zone. This means that a difference of 9 hours is also possible (!), For example. Departure on April 1 of this year.

+4
source

When you use Date in java, it is always in UTC internally. And Timezone includes DST settings, so it's actually quite simple.

 public static void main(String[] args) throws ParseException { String stringAugust = "2011-08-01 12:00:00"; String stringNovember = "2011-11-01 12:00:00"; // Outputting the time in Stockholm and Santiago // Stockholm has DST in August and not in November // Santiago has DST in November and not in August SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // Parsing the Strings sdf.setTimeZone(TimeZone.getTimeZone("UTC")); Date dateAugust = sdf.parse(stringAugust); Date dateNovember = sdf.parse(stringNovember); // outputting the dates for Stockholm sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); sdf.setTimeZone(TimeZone.getTimeZone("Europe/Stockholm")); System.out.println(sdf.format(dateAugust)); System.out.println(sdf.format(dateNovember)); // outputting the dates for Santiago sdf.setTimeZone(TimeZone.getTimeZone("America/Santiago")); System.out.println(sdf.format(dateAugust)); System.out.println(sdf.format(dateNovember)); } 

exits

 2011-08-01 14:00:00 +0200 2011-11-01 13:00:00 +0100 2011-08-01 08:00:00 -0400 2011-11-01 09:00:00 -0300 
+3
source

Source: https://habr.com/ru/post/1383303/


All Articles