简体   繁体   中英

Understanding specific UTC time format YYYY-MM-DDTHH:MM:SS.SSSZ

I have two related questions.

Assume a program running in BST generates a date time value for current time in UTC YYYY-MM-DDTHH:MM:SS.SSSZ format

Also assume current time in London is 2016-06-01 12:33:54

  1. if the current time given by the program is 2016-06-01T11:33:54.000Z , is the program wrong?

  2. how is summer offset for BST noted in the corresponding time format for YYYY-MM-DDTHH:MM:SS.SSSZ

I assume YYYY-MM-DDTHH:MM:SS+0001 Am I correct ?

Firstly please have a read of the iso8601 information. It's becoming more common place to deal with times in different time zones (eg server time zone and client time zone) and the standard is really useful.

In particular please read about UTC or "Zulu" time here .

  1. The program is correct, since the London time is one hour ahead of "UTC" time in summer

  2. The trailing 'Z' is a short notation for UTC (Zulu). You could also write "+00:00" instead of 'Z'. The SS.SSS refer to seconds and milliseconds - not related to the time zone. In devnull's comment he shows you how to apply an offset for summer.

Edit :

There's been some discussion in the comments about whether iso8601 timezone includes timezone or not, and whether timezone will in fact be printed out.

This depends completely on the date/time implementation. If we are using SimpleDateFormat then timezone is supported and will be printed.

Here's a code example to illustrate

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(formatter.format(new Date()));
formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println(formatter.format(new Date()));

Output

2016-06-02T12:53:14.924Z
2016-06-02T13:53:14.925+01:00

Naturally, if you are using a different date/time library such as joda-time , then the implentation details will be different.

Edit: As @DerrylThomas pointed out with SimpleDateFormat wise to use lower case y for years - unless it's intended to use week year - explained in a bit of detail in another answer to a similar question https://stackoverflow.com/a/56911450 .

if the current time given by the program is 2016-06-01T11:33:54.000Z , is the program wrong?

The format is correct and conforms to ISO 8601 but it does not represent Europe/London time. In London, in 2016 , the DST started at Sunday, March 27, 1:00 am and ended at Sunday, October 30, 2:00 am and therefore a date-time representation for Europe/London during this time should have a timezone offset of +01:00 hours. The Z at the end specifies Zulu time which is UTC time and thus has a timezone offset of +00:00 hours. The same instant can be represented for Europe/London as 2016-06-01T12:33:54+01:00 .

java.time

The java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to java.time , the modern date-time API * .

Even Joda-Time should not be used anymore. Notice the following note at the Home Page of Joda-Time

Joda-Time is the de facto standard date and time library for Java prior to Java SE 8. Users are now asked to migrate to java.time (JSR-310).

java.time API is based on ISO 8601 and the date-time string, 2016-06-01T11:33:54.000Z can be parsed into java.time.ZonedDateTime and java.time.OffsetDateTime without needing a date-time parsing/formatting type.

Demo:

import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zdt = ZonedDateTime.parse("2016-06-01T11:33:54.000Z");
        System.out.println(zdt);

        ZoneId zoneId = ZoneId.of("Europe/London");
        ZonedDateTime zdtInLondon = zdt.withZoneSameInstant(zoneId);
        System.out.println(zdtInLondon);
    }
}

Output:

2016-06-01T11:33:54Z
2016-06-01T12:33:54+01:00[Europe/London]

How to deal with Daylight Saving Time (DST)?

As mentioned earlier, the date-time string, 2016-06-01T11:33:54.000Z can also be parsed into java.time.OffsetDateTime without needing a date-time parsing/formatting type. However, OffsetDateTime has been designed to deal with a fixed timezone offset whereas ZonedDateTime has been designed to deal with a timezone and thus it take care of DST automatically. You can convert a ZonedDateTime to OffsetDateTime using ZonedDateTime#toOffsetDateTime if required.

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS z", Locale.ENGLISH);

        String strDateTime = "2016-03-01T11:33:54.000 Europe/London";
        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
        System.out.println(zdt);

        strDateTime = "2016-06-01T11:33:54.000 Europe/London";
        zdt = ZonedDateTime.parse(strDateTime, dtf);
        System.out.println(zdt);
    }
}

Output:

2016-03-01T11:33:54Z[Europe/London]
2016-06-01T11:33:54+01:00[Europe/London]

Notice how the timezone offset has automatically changed from Z to 01:00 to reflect DST change. On the other hand,

import java.time.OffsetDateTime;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2016-03-01T11:33:54.000+01:00";
        OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
        System.out.println(odt);

        strDateTime = "2016-06-01T11:33:54.000+01:00";
        odt = OffsetDateTime.parse(strDateTime);
        System.out.println(odt);
    }
}

Output:

2016-03-01T11:33:54+01:00
2016-06-01T11:33:54+01:00

In this case, you do not talk about a timezone (eg Europe/London); rather, you talk about a fixed timezone offset of +01:00 hours.

Learn more about the modern date-time API from Trail: Date Time .


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM