8

I am supposed to send the current date and time in ISO format as given below:

'2018-02-09T13:30:00.000-05:00'

I have written the following code:

Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm");
SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.000'Z'");
System.out.println(formatter.format(date));
System.out.println(formatter1.format(date));

It prints in the following way:

2018-04-30T12:02
2018-04-30T12:02:58.000Z

But it is not printing as the format mentioned above. How can I get the -5:00 as shown in the format and what does it indicate?

azaveri7
  • 793
  • 3
  • 18
  • 48
  • 1
    Not an answer, but the `-05:00` indicates a time zone, relative to GMT time. – Tim Biegeleisen Apr 30 '18 at 06:42
  • so how to print this along with the current time? – azaveri7 Apr 30 '18 at 06:44
  • 3
    Seems that the pattern you're looking for is `"yyyy-MM-dd'T'HH:mm:ss.SXXX"` – ernest_k Apr 30 '18 at 06:46
  • 1
    Try it without single-quoting the Z in your second SimpleDateFormat. I think that'll do it, but I can't verify right now. When you single-quote it, you're asking for just a literal Z. – yshavit Apr 30 '18 at 06:47
  • See also [How to get current moment in ISO 8601 format with date, hour, and minute?](https://stackoverflow.com/questions/3914404/how-to-get-current-moment-in-iso-8601-format-with-date-hour-and-minute) – Ole V.V. Apr 30 '18 at 07:00
  • Possible duplicate of [in java I need define date in this format 1999-05-31T13:20:00-05:00](https://stackoverflow.com/questions/43659258/in-java-i-need-define-date-in-this-format-1999-05-31t132000-0500) – Ole V.V. Apr 30 '18 at 07:03

2 Answers2

14

In java 8 you can use the new java.time api:

OffsetDateTime now = OffsetDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
System.out.println(formatter.format(now)); // e.g. 2018-04-30T08:43:41.4746758+02:00

The above uses the standard ISO data time formatter. You can also truncate to milliseconds with:

OffsetDateTime now = OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS);

Which yields something like (only 3 digits after the dot):

2018-04-30T08:54:54.238+02:00
Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
  • I can't believe it's this simple, but then again this is why they did away with the old date API...it was just too hard for most people to use +1. – Tim Biegeleisen Apr 30 '18 at 06:45
  • Apart from the milliseconds been 3 digits (based on the OPs requirements), good answer – MadProgrammer Apr 30 '18 at 06:46
  • 1
    @MadProgrammer Ah, I didn't notice that, I think the first time I tested it just happened to have 3 digits by coincidence. This is the ISO date format constant though, so I hope this is an acceptable format too. – Jorn Vernee Apr 30 '18 at 06:52
  • @JornVernee From my point of view, it should be, assuming who ever is receiving the data is using an appropriate parser, but that would become their issue ;) – MadProgrammer Apr 30 '18 at 06:54
  • 1
    It complies with ISO 8601 no matter the number of decimals, so it will probably work where it is to be used anyway. – Ole V.V. Apr 30 '18 at 06:58
3

Easy solution:

    System.out.println(OffsetDateTime.now(ZoneId.of("America/Panama")).toString());

Just now I got this output:

2018-04-30T02:12:46.442185-05:00

To control that seconds are always printed with exactly three decimals:

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSXXX");
    OffsetDateTime now = OffsetDateTime.now(ZoneId.of("America/Panama"));
    System.out.println(now.format(formatter));

2018-04-30T02:12:46.442-05:00

The first, the easy version will print enough groups of three decimals to render the full precision. It will also leave out the seconds completely if they happen to be 0.0. Both are probably OK because all of this is allowed within the ISO 8601 format that you asked for. So whoever receives the string should be happy anyway.

Please fill in your desired time zone where I used America/Panama. It’s best to give explicit time zone for predictable output.

I am using and recommending java.time, the modern Java date and time API. The SimpleDateFormat that you used is not only long outdated, it is also notoriously troublesome. java.time is so much nicer to work with.

What does -05:00 indicate?

-05:00 is an offset from UTC (or GMT, it is nearly the same thing). So your example string is probably from eastern time zone in North America or some other place in Central or Southern America (Cuba, Bolivia, to mention a few that use this offset for some of the year). More precisely -05:00 means that we’re using a clock that is 5 hours (and 0 minutes) behind UTC. So 2:12:46-05:00 denotes the same point in time as 7:12:46 UTC. If we only knew the time was 2:12:46 and didn’t know a time zone or offset, it would be very ambiguous. An offset is perfect for turning the time into an unambiguous point in time.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161