Joda-Time DateTime - How to set fraction of a second to value bigger than 999?

StackOverflow https://stackoverflow.com/questions/22689875

  •  22-06-2023
  •  | 
  •  

Вопрос

Is there any possibility to properly set the fraction of a second, not milliseconds.

I tried to parse the date 2013.06.08 12:46:44.41234 using the pattern yyyy.MM.dd H:mm:ss.SSSSS and the output was: 2013.June.08 12:46:44:41200 : PM.

Это было полезно?

Решение

Joda-Time only stores date/time values down to the millisecond - just like java.util.Date and java.util.Calendar. So no, there's no way you can precisely represent 412340 microseconds within the second (which is what your text representation shows).

The java.time package in Java 8 has nanosecond granularity - if you can use that instead, you should be fine.

Другие советы

tl;dr

LocalDateTime ldt = 
    LocalDateTime.parse( "2013.06.08 12:46:44.123456789".replace( " " , "T" ) ) ;

java.time

As the correct accepted Answer by Jon Skeet says, the new java.time framework in Java 8 and later supports date-time values with up to nanosecond resolution. That means up to nine digits of fractional second.

Caveat: In Java 8 the default implementation of the Clock interface is the same old current time code used in the old date-time classes. That old implementation is limited to millisecond resolution. So in java.time you can store date-time values with nanoseconds but you can only get the current moment in milliseconds.

New Clock In Java 9

Java 9 has a new default Clock implementation with finer granularity. See the OpenJDK issue, Increase the precision of the implementation of java.time.Clock.systemUTC().

That issue is marked as fixed and resolved. Perhaps the new default Clock implementation might be active in the early pre-releases of Java 9 OpenJDK.

Hardware Clock

Remember that even with a new finer Clock implementation, your results may vary by computer. Java depends on the underlying computer hardware’s clock to know the current moment. The resolution and accuracy of such hardware clocks vary widely. For example, if a particular computer’s hardware clock supports only microseconds granularity, any generated date-time values will have only six digits of fractional second with the last three digits being zeros.

enter image description here

Parsing Example

Let’s parse the string given in the Question.

Note that in java.time a formatter coded parsing pattern string does not work for a variable number of fractional second digits. See this Question, JSR-310 - parsing seconds fraction with variable length for discussion.

The solution is to use a DateTimeFormatterBuilder object to say that we expect any number of zero, one, or more digits (up to nine) for a fractional second.

String input = "2013.06.08 12:46:44.41234";
DateTimeFormatter formatter = new DateTimeFormatterBuilder ()
        .appendPattern ( "yyyy.MM.dd HH:mm:ss" )
        .appendFraction ( ChronoField.NANO_OF_SECOND , 0 , 9 , true ) // Nanoseconds = 0-9 digits of fractional second.
        .toFormatter ();

Our input string has neither an offset-from-UTC nor a time zone. So we must parse it as a LocalDateTime which means any (or no particular) locality.

    LocalDateTime localDateTime = LocalDateTime.parse ( input , formatter );

A LocalDateTime has no real meaning. It is not an exact moment on the timeline. It is an idea about a moment. To nail it down as an exact moment, we must apply a time zone. We must apply the time zone that was intended by whomever generated that input string. In the case of this Question that intention goes unstated. So I arbitrarily choose Montréal as an example.

    ZoneId zoneId = ZoneId.of ( "America/Montreal" );
    ZonedDateTime zdt = localDateTime.atZone ( zoneId );

Dump to console.

System.out.println ( "input: " + input + " | localDateTime: " + localDateTime + " | zdt: " + zdt );

input: 2013.06.08 12:46:44.41234 | localDateTime: 2013-06-08T12:46:44.412340 | zdt: 2013-06-08T12:46:44.412340-04:00[America/Montreal]

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top