I'm trying, using java, to parse a given string to DateTime, given that the string is in the following format:
YYYY-MM-DDTHH:mm:ss[.s+]Z
The milliseconds are optional and can be any nubmer of numbers after the decimal point.
How can it be done simply?

- 73
- 1
- 6
-
"and can be any nubmer of numbers after the decimal point" - do you really mean that? Does ".1" mean 100 milliseconds or 1 millisecond? What about ".3456"? – Jon Skeet Mar 07 '17 at 14:36
-
Had you tried? Please post your code. – freedev Mar 07 '17 at 14:38
-
1If milliseconds are optional than remove these from String before parsing – Sanjeev Mar 07 '17 at 14:44
-
http://stackoverflow.com/questions/1459656/how-to-get-the-current-time-in-yyyy-mm-dd-hhmisec-millisecond-format-in-java – jiveturkey Mar 07 '17 at 14:52
-
Do you need the milliseconds if they are present? – Ole V.V. Mar 07 '17 at 14:59
-
Sadly, I can't post my code online. First, I came to realize these aren't milliseconds. After the decimal point is 'sub-second', so .5 means half a second and not 5 milliseconds. Second, I would prefer not to remove these digits, since it will be considered as data lost in translation, and I try to minimize that. – Bruce Kent Mar 08 '17 at 15:23
2 Answers
First, your format string is wrong. Year and day should be in lowercase, i.e. yyyy
and dd
, and the T
is literal, so it should be quoted, i.e. 'T'
.
Assuming that by "any number of numbers after the decimal point" you're actually talking about between 0 and 9 digits, i.e. nanoseconds, the use of the word "milliseconds" is misleading. Fractional seconds would be the right way to say that.
To support varying number of fractional digits with Java 8 Time API, use DateTimeFormatterBuilder
like this:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("uuuu-MM-dd'T'HH:mm:ss")
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
.appendOffset("+HH:mm", "+00:00")
.toFormatter();
System.out.println(OffsetDateTime.parse("2017-03-07T09:47:15+01:00", fmt));
System.out.println(OffsetDateTime.parse("2017-03-07T09:47:15.123456789-02:00", fmt));
System.out.println(OffsetDateTime.parse("2017-03-07T09:47:15.42000-05:30", fmt));
System.out.println(OffsetDateTime.parse("2017-03-07T09:47:15.2468000-05:30", fmt));
Output
2017-03-07T09:47:15+01:00
2017-03-07T09:47:15.123456789-02:00
2017-03-07T09:47:15.420-05:30
2017-03-07T09:47:15.246800-05:30
As you can see, trailing zeroes are truncated in 3-block increments when the OffsetDateTime
value is printed, i.e. when toString()
is used to format the result.

- 154,647
- 11
- 152
- 247
OffsetDateTime.parse()
does this out of the box. Say we have:
String[] input = {
"2017-03-07T16:06:13+01:00",
"2017-03-07T16:06:13.1+01:00",
"2017-03-07T16:06:13.22+01:00",
"2017-03-07T16:06:13.333+01:00",
"2017-03-07T16:06:13.4444+01:00",
"2017-03-07T16:06:13.55555+01:00",
"2017-03-07T16:06:13.666666+01:00",
"2017-03-07T16:06:13.7777777+01:00",
"2017-03-07T16:06:13.88888888+01:00",
"2017-03-07T16:06:13.999999999+01:00"
};
for (String ips : input) {
OffsetDateTime dt = OffsetDateTime.parse(ips);
System.out.println(dt);
}
This prints:
2017-03-07T16:06:13+01:00
2017-03-07T16:06:13.100+01:00
2017-03-07T16:06:13.220+01:00
2017-03-07T16:06:13.333+01:00
2017-03-07T16:06:13.444400+01:00
2017-03-07T16:06:13.555550+01:00
2017-03-07T16:06:13.666666+01:00
2017-03-07T16:06:13.777777700+01:00
2017-03-07T16:06:13.888888880+01:00
2017-03-07T16:06:13.999999999+01:00
As Andreas noted in his answer, OffsetDateTime.toString()
prints as many groups of three decimals as necessary for full accuracy. You may of course do you own formatting, but I consider this outside the question.
You do get a DateTimeParseException
if you try to feed it 10 decimals (or more), though.