Search code examples
javajava-8jodatime

java format timestamps with "Z" instead of "+"


Using java I try to format the current date with the timezone using SimpleDateFormat

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSZ");
sdf.format(new Date());

This give me as results :

   2021-04-28T13:45:52:308+0300

I want to get the timezone format with the "Z" instead of "+"

wanted results : "2021-04-28T13:45:52:308Z03:00"

I writed the date output in a file log that will be parsed by telegraf plugin writed in Go language that expect date with time zone with the following format : json_time_format = "2006-01-02T15:04:05Z07:00"

Is there a pattern allows that ?


Solution

  • You misunderstood. 2006-01-02T15:04:05Z07:00 does not mean that you should have a Z instead of a plus (what would you put instead of a minus, then?) This way of specifying a date and time format approximates how the fixed example date and time of Mon Jan 2 15:04:05 MST 2006 would be formatted, but it’s only an approximation. Specifically when it comes to the offset from UTC, the format requires Z when the offset is zero and +hh:mm or -hh:mm when it is non-zero. In accordance with ISO 8601 and RFC-3339. You see immediately that just giving the correct formatting of the example date and time, 2006-01-02T15:04:05-07:00, would not tell the reader that offset 0 should be given as Z. Therefore this particular requirement is specified as Z07:00 in the format. According to Format a time or date [complete guide] (link at the bottom), your particular format, 2006-01-02T15:04:05-0700, denotes ISO 8601 or RFC-3339.

    So all you need to do is use DateTimeFormat.ISO_OFFSET_DATE_TIME or OffsetDateTime.toString().

    A couple of examples follow.

        String result = OffsetDateTime.now().toString();
        System.out.println(result);
    

    Output when running on Java 8 in my time zone just now:

    2021-04-29T17:00:55.716+02:00

    If the fraction of second is not allowed — well, according to ISO 8601 it is optional, so it should be, but if not:

        String result = OffsetDateTime.now().truncatedTo(ChronoUnit.SECONDS)
                .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    

    2021-04-29T17:00:55+02:00

    If you have got an old-fashioned Date object from legacy code, convert it before formatting:

        Date oldfashionedDate = new Date();
        String result = oldfashionedDate.toInstant()
                .atZone(ZoneId.systemDefault())
                .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    

    2021-04-29T17:00:55.739+02:00

    Links