Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 755
QVSJ Avatar asked Jun 02 '16 10:06

QVSJ


People also ask

What is the format of UTC time?

Times are expressed in UTC (Coordinated Universal Time), with a special UTC designator ("Z"). Times are expressed in local time, together with a time zone offset in hours and minutes. A time zone offset of "+hh:mm" indicates that the date/time uses a local time zone which is "hh" hours and "mm" minutes ahead of UTC.

What is SSSZ date format?

Date formatting sss'Z'" if in UTC or "yyyy-MM-dd'T'hh:mm:ss. sss[+|-]hh:mm" otherwise. As said previously, it is possible to display or to hide the time zone and the milliseconds.

What is UTC timestamp example?

What is UTC Time in ISO-8601 Format? Current time: 13:31:38 UTC. UTC is replaced with Z that is the zero UTC offset. UTC time in ISO-8601 is 13:31:38Z.


2 Answers

Firstly please have a read of the iso8601 information. It's becoming more common place to deal with times in different time zones (e.g. 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.

like image 133
vikingsteve Avatar answered Oct 16 '22 15:10

vikingsteve


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 (e.g. 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.

like image 24
Arvind Kumar Avinash Avatar answered Oct 16 '22 16:10

Arvind Kumar Avinash