Получение одного и того же 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 ответ:
Когда вы звоните
LocalDate.parse
, Вы получаете только часть даты (день, месяц и год) и отбрасываете остальное. ALocalDate
не имеет полей времени (час, минута, секунды и доли секунды), поэтому они просто отбрасываются и теряются.Затем вы вызываете
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"));