简体   繁体   中英

Java 8 ZonedDateTime

I am trying to use ZonedDateTime.now(ZoneOffset.UTC).toString() to get the current time. It works well, but seems to cut off seconds / milliseconds when they are right on a rollover (00.000Z), or so it appears. Normally it wouldn't matter, but I am writing the data to ElasticSearch, which has a strict mapping for the date I am passing (acquired time).

I maybe am off in what I am thinking is happening, but want to try to make sure I can always provide a date/time with seconds and milliseconds.

Basic Code snippet (first pass was to add milliseconds, but appears seconds could also possibly be left out):

def utcDate = ZonedDateTime.now(ZoneOffset.UTC)
def utcDateStr = utcDate.toString()
utcDateStr = utcDateStr.contains(".") ? utcDateStr
        : utcDateStr.replace("Z","").concat(".000Z")

Want it to be in the format below, which it almost always is:

2016-06-16T05:43:07.624Z

Firstly, it sounds like you really want an Instant rather than a ZonedDateTime - that takes the time zone part out of the picture entirely. But either way, just use a DateTimeFormatter to format the value however you want.

It sounds like you want something like (in Java; adjust to Groovy appropriately):

DateTimeFormatter formatter = DateTimeFormatter
    .ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US)
    .withZone(ZoneOffset.UTC);
Instant now = Instant.now();
String text = formatter.format(now); 
System.out.println(text);

That will still output the milliseconds value even if it's 0.

(If you really want to use ZonedDateTime , you can do so with the same formatter. But conceptually, what I think you're trying to represent is just an instant in time, and Instant is the better fit for that.)

If you want to go the formatter route, you can build one like so:

DateTimeFormatter ES_ISO8601_FORMATTER = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(
                    new DateTimeFormatterBuilder()
                            .parseCaseInsensitive()
                            .append(ISO_LOCAL_DATE)
                            .appendLiteral('T')
                            .append(
                                    new DateTimeFormatterBuilder()
                                            .appendValue(HOUR_OF_DAY, 2)
                                            .appendLiteral(':')
                                            .appendValue(MINUTE_OF_HOUR, 2)
                                            .appendLiteral(':')
                                            .appendValue(SECOND_OF_MINUTE, 2)
                                            .appendFraction(NANO_OF_SECOND, 3, 9, true)
                                            .toFormatter()
                            )
                            .toFormatter()
            )
            .appendOffsetId()
            .toFormatter();

(That's cobbled together from the code in the DateTimeFormatter class in Java 8)

The change is basically giving

                                        .appendFraction(NANO_OF_SECOND, 3, 9, true)

a min width of 3, instead of 0 in the original ISO formatter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM