Получение текущего времени в Java 8
Я изучаю новый java.time API Java 8. Я особенно стараюсь получить текущее время (мой текущий часовой пояс, другой часовой пояс и другое смещение).
Код:
public static void getCurrentLocalTime(){
LocalTime time = LocalTime.now();
System.out.println("Local Time Zone: "+ZoneId.systemDefault().toString());
System.out.println("Current local time : " + time);
}
public static void getCurrentTimeWithTimeZone(){
LocalDateTime localtDateAndTime = LocalDateTime.now();
ZoneId zoneId = ZoneId.of("America/Los_Angeles");
ZonedDateTime dateAndTimeInLA = ZonedDateTime.of(localtDateAndTime, zoneId);
String currentTimewithTimeZone =dateAndTimeInLA.getHour()+":"+dateAndTimeInLA.getMinute();
System.out.println("Current time in Los Angeles: " + currentTimewithTimeZone);
}
public static void getCurrentTimeWithZoneOffset(){
LocalTime localtTime = LocalTime.now();
ZoneOffset offset = ZoneOffset.of("-08:00");
OffsetTime offsetTime = OffsetTime.of(localtTime, offset);
String currentTimewithZoneOffset =offsetTime.getHour()+":"+offsetTime.getMinute();
System.out.println("Current time with offset -08:00: " + currentTimewithZoneOffset);
}
Но, когда я называю методы, я получаю одно и то же время суток (мое системное время), что явно не то, что я ожидаю.
Вывод метода вызывает:
Current time in Los Angeles: 19:59
Local Time Zone: Asia/Calcutta
Current local time : 19:59:20.477
Current time with offset -08:00: 19:59
Даже после установки другого часового пояса и смещения, почему я получаю одно и то же время?
Ответы
Ответ 1
LocalDateTime.now()
всегда возвращает текущую дату/время в вашем часовом поясе по умолчанию (например, 13 октября @11.20am в Лондоне). Когда вы создаете из него ZonedDateTime
или OffsetTime
с определенным ZoneId
или ZoneOffset
, вы получаете одинаковые дату и время, но в другом часовом поясе (например, 13 октября в 11.20am в Лос-Анджелесе) который представляет собой другой момент времени.
Возможно, вы ищете что-то вроде:
Instant now = Instant.now();
ZoneId zoneId = ZoneId.of("America/Los_Angeles");
ZonedDateTime dateAndTimeInLA = ZonedDateTime.ofInstant(now, zoneId);
Это рассчитает текущую дату и время в Лос-Анджелесе: 13 октября, 3.20 утра.
Ответ 2
Рассмотрим следующие фиксированные методы:
public static void getCurrentLocalTime() {
LocalTime time = LocalTime.now();
System.out.println("Local Time Zone: " + ZoneId.systemDefault().toString());
System.out.println("Current local time : " + time);
}
public static void getCurrentTimeWithTimeZone() {
LocalDateTime localDateAndTime = LocalDateTime.now(ZoneId.of("America/Los_Angeles"));
System.out.println("Current time in Los Angeles: " + localDateAndTime.toLocalTime());
}
public static void getCurrentTimeWithZoneOffset() {
LocalTime localTime = LocalTime.now(ZoneOffset.of("-08:00"));
System.out.println("Current time with offset -08:00: " + localTime);
}
Изменилось то, что вместо вызова now()
вызов выполняется now(zone)
. Это потому, что now()
всегда возвращает текущее системное время в вашей часовой пояс. Вызов atZone
, OffsetTime.of
или ZoneDateTime.of
не меняет дату/время, он только сообщает Java Time, что дата должна пониматься в дату/время в этом часовом поясе.
При вызове этих 3 методов здесь вывод на моей машине:
Local Time Zone: Europe/Paris
Current local time : 12:32:21.560
Current time in Los Angeles: 03:32:21.579
Current time with offset -08:00: 02:32:21.580
Чтобы сделать это очень ясно: вы находитесь в Европе и звоните LocalDateTime.now().atZone(ZoneId.of("America/Los_Angeles"))
- вы создаете дату/время, которое представляет собой текущее время в Европе, как если бы вы были в Лос-Анджелесе, поэтому вы создаете дату/время, которое на самом деле в будущем для жителей Лос-Анджелеса (8 или 9 часов в будущем, в зависимости от летнего времени).
Ответ 3
Существует также другой способ отображения времени в другой зоне с помощью withZoneSameInstant
:
// now, in current zone,
// 2016-04-13T14:24:57.618+02:00[Europe/Warsaw]
ZonedDateTime now = ZonedDateTime.now();
// 2016-04-13T05:24:57.618-07:00[America/Los_Angeles]
ZonedDateTime losAngelesDateTime = now.withZoneSameInstant(ZoneId.of("America/Los_Angeles"));