This is the 12th day of my participation in Gwen Challenge


Common time format

  1. World Standard time, where T represents the beginning of a minute or second (or the interval between date and time), and Z indicates that it is a world standard time

The 2019-02-28 T01:47:07. 081 z

  1. Local time, also called time without time zone information, has no Z at the end

The 2019-02-28 T09:47:07. 153

  1. Time with time zone information, +08:00 indicates that the time is obtained by adding 8 hours to UNIVERSAL standard time, and [Asia/Shanghai] indicates the time zone

The 2019-02-28 T09:47:07. 153 + 08:00 Asia/Shanghai

Time format in JDK8

There are four types of time: String, Instant, LocalDateTime, and ZonedDateTime.

String is the time after formatting, Instant is the timestamp, LocalDateTime is the time without time zone information, and ZonedDateTime is the time with time zone information.

1. String is equivalent to LocalDateTime

The best way to think of LocalDateTime is not to think of it as “local time,” it is simply “time without time zone information.” It only stores the year, month, day, hour, minute, and second. It doesn’t store any time zone information. With String completely equivalent, essentially is the parsing of String, but the year, month, day, minute and second formatting stored in the object, easy access.

public static void main(String[] args) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.JAPAN); LocalDateTime now = LocalDateTime.now(); System.out.println(now); System.out.println(formatter.format(now)); System.out.println(LocalDateTime.parse("2019-02-28 11:11:11", formatter)); /* "2019-02-28t19:41:55" 2019-02-28t11:55 */}Copy the code

2 Instant is equivalent to ZonedDateTime

Instant is a time stamp, which refers to the total number of seconds since 00:00 00:00 00:00 GMT on January 01, 1970. Instant itself actually specifies the time zone, time zone 0. ZonedDateTime is the time with the time zone information, essentially formatting Instant based on the time zone.

public static void main(String[] args) { ZonedDateTime defaultZonedTime = ZonedDateTime.ofInstant(Instant.now(), ZoneId.systemDefault()); System.out.println(defaultZonedTime); System.out.println(defaultZonedTime.toInstant()); System.out.println(defaultZonedTime.toLocalDateTime()); ZonedDateTime australiaZonedTime = ZonedDateTime.ofInstant(Instant.now(), ZoneId.of("Australia/Darwin")); System.out.println(australiaZonedTime); System.out.println(australiaZonedTime.toInstant()); System.out.println(australiaZonedTime.toLocalDateTime()); /* 2019-02-28T19:47:21.644+08:00[Asia/Shanghai] 2019-02-28T11:47:21.644z /* 2019-02-28T19:47:21.644+08:00[Asia/Shanghai] 2019-02-28T11:47:21.644z 2019-02-28t21:17:21.825 +09:30[Australia/Darwin] 2019-02-28t11:47:21.825z 2019-02-28t21:17:21.825 */}Copy the code

Constructing a time object

1. Call the of constructor

public static void main(String[] args) { //@param epochMilli the number of milliseconds from 1970-01-01T00:00:00Z System.out.println(Instant.ofEpochMilli(System.currentTimeMillis())); System.out.println(LocalDateTime.of(2019, 2, 28, 10, 0, 0, 0)); System.out.println(ZonedDateTime.of(2019, 2, 28, 10, 0, 0, 0, ZoneId.systemDefault())); /* 2019-02-28T12:05:24.154z 2019-02-28T10:00+08:00[Asia/Shanghai] */}Copy the code

2, obtain the current system time now()

Public static void main(String[] args) {public static void main(String[] args) {public static void main(String[] args) { System.out.println(Instant.now()); Clock.systemDefaultZone() system.out.println (localDatetime.now ()); SystemDefaultZone () system.out.println (zonedDatetime.now ()); System.out.println(LocalDateTime.now(ZoneId.of("+00:00"))); System.out.println(zonedDatetime.now (zoneid.of ("+00:00"))); 2019-02-28T20:11:49.696z 2019-02-28T20:11:49.873 2019-02-28T20:11:49.875+08:00[Asia/Shanghai] The 2019-02-28 T12:11:49. 875, the 2019-02-28 T12:11:49. 875 z * /}Copy the code

Conversion between time objects

1. Conversion between Instant and LocalDateTime and ZonedDateTime

public static void main(String[] args) { Instant instant = Instant.now(); LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); System.out.println(instant); System.out.println(localDateTime); System.out.println(zonedDateTime); System.out.println(localDateTime.toInstant(ZoneOffset.UTC)); // Convert LocalDateTime to Instant System.out.println(localDateTime.toInstant(ZoneOffset. Of ("+08:00"))); System.out.println(zonedDateTime.toInstant()); /* 2019-02-28T20:20:32.101z 2019-02-28T20:20:32.101+08:00[Asia/Shanghai] 2019-02-28t20:20:32.101z 2019-02-28t20:20:32.101z */} 2019-02-28t20:20:32.101z */}Copy the code

2. Conversion between LocalDateTime and ZonedDateTime

public static void main(String[] args) { Instant instant = Instant.now(); LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); System.out.println(instant); System.out.println(localDateTime); System.out.println(zonedDateTime); System.out.println(ZonedDateTime.of(localDateTime, ZoneId.systemDefault())); / / LocalDateTime ZonedDateTime System. Out. Println (ZonedDateTime. ToLocalDateTime ()); //ZonedDateTime > LocalDateTime /* 2019-02-28t12:33:55.190z 2019-02-28t20:33:55.190 2019-02-28T20:33:55.190+08:00[Asia/Shanghai] 2019-02-28T20:33:55.190+08:00[Asia/Shanghai] 2019-02-28T20:33:55.190 */}Copy the code

Daylight saving time

Daylight Saving Time (DST), also known as Daylight Saving Time, is an artificial local Time system to save energy. The unified Time used during this system is called Daylight Saving Time. Generally in the early dawn of the summer artificial time to speed up an hour, can make the person early to sleep, reduce lighting, in order to make full use of lighting resources, thereby saving lighting electricity. Different countries adopt daylight saving time. Nearly 110 countries around the world currently observe daylight saving time every year.

Here are daylight saving time in several countries:

  1. Daylight Saving Time 2015 in the US will begin at 02:00 am local time on 09 March 2015 and end on 2 November 2015, when trading times in the US will be one hour earlier.

  2. European countries will begin 2015 daylight Saving Time at 01:00 GMT on 30 March and run until 26 October 2015.

  3. Australia’s 2015 Summer Time will start at 03:00 local time (01:00 BST) on April 6.

  4. New Zealand’s 2015 daylight saving Time will start at 03:00 local time on April 6, with trading hours extended by one hour.

Take 2015 DAYLIGHT saving time in the United States,

2015.03.09 01:59:59 seconds later, it will directly change to 2015.03.09 03:00:00, that is, one hour after the jump

2015.11.02 01:59:59 seconds later, it will become 2015.11.02 01:00:00 directly, that is, there will be two 1:00 to 2:00, one more hour

Conversion between time zones

1. The Time trap

There are two problems with the concept of time zones and daylight saving time:

  1. Users in different time zones have different understandings of time. The same time String in different time zones is not the same time.
  2. Servers in different time zones have different understandings of time. For example, the same program running on servers in different time zones returns different results when these programs call localDatetime.now () at the same time.
  3. The situation is even more complicated if the foreground and daemon are deployed on servers in different time zones. If the user, foreground, and background are not in the same time zone… .

2. Conversion scheme

When converting time zones, note that the time entered in the String type does not contain time zone information. Therefore, you need to manually resolve the time zone information. The parsing process is divided into two steps:

  1. First, analyze the user’s time zone based on the context and convert the time entered by the user into world Standard time.
  2. Convert universal standard time to the desired time zone.
  3. It is recommended to use time stamps (long data) uniformly in the system, including the front and back end transmission and database storage, and only in the display of time to convert into strings;
  4. To facilitate processing, you are advised to change all time zones to 0 for processing.

It’s the same for long time, and it’s the same for 0 time, okay

Java implementation

Date (long) in Java supports DAYLIGHT saving time (DST), but the original DST information will be lost during the operation. Therefore, you need to set the GMT time zone (0) before the DST conversion. If the GMT time zone is standard time, the information will not be lost:

1. Convert date to GMT.

public static String conver2GMTTime(Date dateTime) { if (CommonTool.isNullOrEmpty(dateTime)) { dateTime = new Date(); } SimpleDateFormat formatter = new SimpleDateFormat(" YYYY-MM-DD HH: MM :ss "); if (isSupportMultiZone()) { formatter.setTimeZone(TimeZone.getTimeZone("GMT")); } return formatter.format(dateTime); }Copy the code

2. Query database string to local time

public static String convert2ClientTime(String dateTime) { if (isStringNullOrEmpty(dateTime)) { return dateTime; } SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (isSupportMultiZoneOrDST()) { simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); } try {return string.valueof (simpleDateFormat.parse(dateTime).getTime()); } catch (Exception e) { logger.warn("Transfer GMT time to local time failed." + dateTime, e); return ""; }}Copy the code

The test method

1. UT test

Set the time zone in the lower right corner of Windows, find the DST time and DST time, and set the time zone test in UT

@Before public void setUp() throws Exception { TimeZone.setDefault(TimeZone.getTimeZone("America/New_York")); } @After public void tearDown() throws Exception { TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); } / / -- -- -- -- -- -- -- -- -- GMT to client time -- -- -- -- -- -- -- -- -- -- -- -- -- / / @ Test public void should_covert_gmt_2_local_time () throws Exception { String gmtTime = "2017-07-17 10:22:54"; String localTime = convertLocalTime(gmtTime); assertEquals("2017-07-17 06:22:54(UTC-05:00 DST+01:00)", localTime ); }Copy the code

2, manual test

Windows Set the time zone in the lower right corner of the system, find the time when daylight Saving time exists and the time when daylight Saving time enters, set the time zone of the Windows environment to this time zone, run the local test method or the main methodIn Linux, you can run the date -r command to view the current time zone. You can change the time zone on the CLI or in the /etc/sysconfig/clock configuration file