Daylight saving time in java

please see if you can tell me how to handle the DST problem in my case.

Firstly, my application is a logistics system, and it is intended for a global user, therefore it is related to a time zone problem, I will process it as follows when you set a local reservation date:

1. When the user's login application, we can get the user’s time zone according to the login IP address, but it’s just an offset (I don’t remember this term), for example “GMT + 08” (BeiJing) or “GMT” -06 "(Chicago).

2. Before the user saves the reservation, we need to set the local booking date, since I cannot get a direct direct local date. So I get the server date (in my case, it’s BeiJing time), and then calculate the local date according to the server date and time zone of the user, for example, if the time zone of the user is “GMT-08”, the server date is 2013-08-29 17:45:00. the server’s time zone is "GMT + 08", then I will use the server date 8-8, and the result will be on 2013-08-29 01: 45: 00. but since I do not consider DST, the calculated local date will be different from the actual date.eg is now in San Francisco, the actual local date will be earlier than an hour than the result that I calculated using this method,

I found that java TimeZone already addressed the DST problem, but when creating TimeZone I need to provide a location name (e.g. US / Alaska, Pacific / Apia). while in my case, what can I get is just offset.so can you tell me how to fix the DST problem in my case?

+4
source share
3 answers

Yes, you should use Joda-Time or the new java.time package in Java 8 (inspired by Joda-Time).

The offset is the number of hours and minutes from UTC (GMT), which is represented by a specific date-time value. The west coast is -08: 00 (ignoring the pointlessness of daylight saving time), which means 8 hours behind UTC.

Beware that java.time in its original release has a small error where it cannot handle the offset of the entire hours (e.g. +08 ) without minutes (e.g. +08:00 ).

A time zone is an offset plus daylight saving time (DST) rules, a history of DST changes, and information about other anomalies.

Use the correct time zone names (mostly a city with a slash). Avoid 3 or 4 letter codes, such as EST, that are neither standardized nor unique.

Java.util.Date does not have a time zone, but a Joda-Time DateTime .

To get the time zone of a web browser, see this question . But often this does not work well. As you've probably seen, many websites ask users to select a time zone.

Your specific use case is confusing. As a rule, the best approach is to use date-time for UTC, and then, if necessary, adjust the user’s local time. It is usually best for your software to work and store date-time in UTC. Then specify the local date-time adjusted in accordance with the requirements of the user. In other words, think around the world (UTC) while locally (local time zone is set).

Typically, system administrators store their server computers in UTC (without a time zone offset). If your OS (e.g. Mac OS X) does not offer UTC, use Reykjavik , since Iceland uses UTC year-round without daylight saving time. Similarly, databases almost always convert date and time values ​​to UTC for storage.

Joda-Time offers the LocalDate class if you really don't like the time zone or time. But it is often better to use a date-to-date (DateTime instance) and format the date string only as needed.

Sample code in Joda-Time 2.3.

 DateTimeZone timeZoneChina = DateTimeZone.forID( "Asia/Shanghai" ); DateTime dateTimeChina = new DateTime( 2013, 8, 29, 17, 45, 00, timeZoneChina ); DateTime dateTimeUtc = dateTimeChina.withZone( DateTimeZone.UTC ); DateTime dateTimeParis = dateTimeChina.withZone( DateTimeZone.forID( "Europe/Paris" ) ); DateTimeZone timeZoneUsWestCoast = DateTimeZone.forID( "America/Los_Angeles" ); DateTime dateTimeUnitedStatesWestCoast = dateTimeChina.withZone( timeZoneUsWestCoast ); DateTimeFormatter formatter = ISODateTimeFormat.date(); String outputDateOnlyForUnitedStatesWestCoast = formatter.withZone( timeZoneUsWestCoast ).print( dateTimeUtc ); 

Dump for console ...

 System.out.println( "dateTimeChina: " + dateTimeChina ); System.out.println( "dateTimeUtc: " + dateTimeUtc ); System.out.println( "dateTimeParis: " + dateTimeParis ); System.out.println( "dateTimeUnitedStatesWestCoast: " + dateTimeUnitedStatesWestCoast ); System.out.println( "outputDateOnlyForUnitedStatesWestCoast: " + outputDateOnlyForUnitedStatesWestCoast ); 

At startup ...

 dateTimeChina: 2013-08-29T17:45:00.000+08:00 dateTimeUtc: 2013-08-29T09:45:00.000Z dateTimeParis: 2013-08-29T11:45:00.000+02:00 dateTimeUnitedStatesWestCoast: 2013-08-29T02:45:00.000-07:00 outputDateOnlyForUnitedStatesWestCoast: 2013-08-29 
+5
source

This is a common source of headache.

  • In my experience, the location by IP address is not always reliable, for example, when people use corporate VPNs.
  • You are right, regional time zones ("Europe / Paris", "CET") are preferable for the correct processing of DST.

I solved a similar problem with the following approach: You associate the exact time zone with each user in your server database. When the user fills out the reservation form, you show the TZ selector pre-populated with its default TZ. Thus, he can double check it (IMHO is much safer than guessing by IP) and on the server side, Dates can be safely converted from the local server to server time and vice versa.

+3
source

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


All Articles