SimpleDateFormat cannot parse milliseconds with more than 4 digits

前端 未结 7 720
花落未央
花落未央 2020-12-06 13:20

I want to parse a timestamp, like this - \"2016-03-16 01:14:21.6739\". But when I use the SimpleDateFormat to parse it, I find that it outputs an i

7条回答
  •  既然无缘
    2020-12-06 13:47

    tl;dr

    LocalDateTime.parse(
        "2016-03-16 01:14:21.6739".replace( " " , "T" )  // Comply with ISO 8601 standard format.
    )
    

    Milliseconds versus Microseconds

    As others noted, java.util.Date has millisecond resolution. That means up to 3 digits of a decimal fraction of second.

    You have 4 digits in your input string, one too many. Your input value demands finer resolution such as microseconds or nanoseconds.

    java.time

    Instead of using the flawed, confusing, and troublesome java.util.Date/.Calendar classes, move on to their replacement: the java.time framework built into Java 8 and later.

    The java.time classes have a resolution of nanosecond, up to nine digits of decimal fraction of a second. For example:

    2016-03-17T05:19:24.123456789Z

    ISO 8601

    Your string input is almost in standard ISO 8601 format used by default in java.time when parsing/generating textual representations of date-time values. Replace that space in the middle with a T to comply with ISO 8601.

    String input = "2016-03-16 01:14:21.6739".replace( " " , "T" );
    

    Unzoned

    A LocalDateTime is an approximation of a date-time, without any time zone context. Not a moment on the timeline.

    LocalDateTime ldt = LocalDateTime.parse( input );
    

    UTC

    Make that LocalDateTime an actual moment on the timeline by applying the intended time zone. If meant for UTC, make an Instant.

    Instant instant = ldt.toInstant( ZoneOffset.UTC );
    

    Zoned

    If meant for a particular time zone, specify a ZoneId to get a ZoneDateTime.

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

提交回复
热议问题