Получение одного и того же ZonedDateTime для разных строк времени


Я использую нижеприведенную функцию для преобразования строки времени формата микросекунды в ZoneDateTime, чтобы я мог сделать сравнения позже.

public static ZonedDateTime createTimeFromString(String inputTime) {
    ZonedDateTime time;
    try {

        System.out.printf("Input time %s%n", inputTime);
        DateTimeFormatter formatter =
                DateTimeFormatter.ofPattern("yyyyMMdd-HH:mm:ss.SSSSSS");
        LocalDate date = LocalDate.parse(inputTime, formatter);
        time = date.atStartOfDay(ZoneId.systemDefault());

        System.out.printf("Formated time %s%n", time);
        return time;
    }
    catch (DateTimeParseException exc) {
        System.out.printf("%s is not parsable!%n", inputTime);
        throw exc;      // Rethrow the exception.
    }
}

Однако, какую бы временную строку я ни передал в функцию, я получаю один и тот же результат.

Например:

Input time 20171025-10:58:24.062151
Formated time 2017-10-25T00:00+05:30[Asia/Colombo]

Input time 20171025-10:58:25.446862
Formated time 2017-10-25T00:00+05:30[Asia/Colombo]

Я использую Java 8.

Не могли бы вы объяснить, что я делаю не так?
1 3

1 ответ:

Когда вы звоните LocalDate.parse, Вы получаете только часть даты (день, месяц и год) и отбрасываете остальное. A LocalDate не имеет полей времени (час, минута, секунды и доли секунды), поэтому они просто отбрасываются и теряются.

Затем вы вызываете atStartOfDay(ZoneId.systemDefault()), который устанавливает время на полночь в часовом поясе JVM по умолчанию.

Если вы хотите сохранить все (дату и время), разберите его на LocalDateTime, который является классом, содержащим все поля даты и времени. Тогда вы звоните метод atZone для преобразования его в ZonedDateTime:

String inputTime = "20171025-10:58:24.062151";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd-HH:mm:ss.SSSSSS");
// parse to a LocalDateTime (keeping all date and time fields)
LocalDateTime date = LocalDateTime.parse(inputTime, formatter);
// convert to ZonedDateTime
ZonedDateTime z = date.atZone(ZoneId.systemDefault());

ПС: ZoneId.systemDefault() возвращает часовой пояс JVM по умолчанию, но имейте в виду, что этот может быть изменен без уведомления, даже во время выполнения, поэтому лучше всегда указывать, какой из них вы используете.

API использует имена часовых поясовIANA (всегда в формате Region/City, например Asia/Colombo или Europe/Berlin). Избегайте использования 3-буквенных сокращений (таких как IST или CET), потому что они неоднозначны и не являются стандарт .

Вы можете получить список доступных часовых поясов (и выбрать тот, который лучше всего подходит вашей системе), позвонив по телефону ZoneId.getAvailableZoneIds(). Затем вызывается метод ZoneId.of() с именем зоны, например:
// using specific timezone instead of JVM's default
ZonedDateTime z = date.atZone(ZoneId.of("Asia/Colombo"));