Перетворити LocalDateTime на LocalDateTime в UTC.
LocalDateTime convertToUtc(LocalDateTime date) {
//do conversion
}
Я шукав через мережу. Але рішення не отримав
Перетворити LocalDateTime на LocalDateTime в UTC.
LocalDateTime convertToUtc(LocalDateTime date) {
//do conversion
}
Я шукав через мережу. Але рішення не отримав
Відповіді:
Я особисто віддаю перевагу
LocalDateTime.now(ZoneOffset.UTC);
оскільки це найбільш читабельний варіант.
Є ще простіший спосіб
LocalDateTime.now(Clock.systemUTC())
LocalDateTime не містить інформації про зону. ZonedDatetime робить.
Якщо ви хочете перетворити LocalDateTime на UTC, вам потрібно обернути кулак ZonedDateTime.
Ви можете конвертувати, як показано нижче.
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt.toLocalTime());
ZonedDateTime ldtZoned = ldt.atZone(ZoneId.systemDefault());
ZonedDateTime utcZoned = ldtZoned.withZoneSameInstant(ZoneId.of("UTC"));
System.out.println(utcZoned.toLocalTime());
ldt.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC"))
в той час як стислий все ще передає значення, достатнє для того, щоб не потребувати зонованої змінної екземпляра.
ZoneOffset.UTC
є приємною заміноюZoneId.of("UTC")
OffsetDateTime
більше підходить, ніж ZonedDateTime
. Використання: OffsetDateTime.now( ZoneOffset.UTC )
абоmyInstant.atOffset( ZoneOffset.UTC )
Скористайтеся наведеним нижче. Він бере місцевий час і перетворює його у UTC, використовуючи часовий пояс. Вам не потрібно створювати його функцію.
ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(nowUTC.toString());
Якщо вам потрібно отримати частину LocalDateTime із ZonedDateTime, тоді ви можете використовувати наступне.
nowUTC.toLocalDateTime();
Ось статичний метод, який я використовую у своєму додатку, щоб вставити час UTC у mysql, оскільки я не можу додати значення UTC_TIMESTAMP за замовчуванням до стовпця дати та часу.
public static LocalDateTime getLocalDateTimeInUTC(){
ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
return nowUTC.toLocalDateTime();
}
Ось простий маленький клас утиліти, який ви можете використовувати для перетворення локального часу дати з зони в зону, включаючи метод утиліти безпосередньо для перетворення локального часу дати з поточної зони в UTC (з основним методом, щоб ви могли запустити його і побачити результати простого тесту):
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
public final class DateTimeUtil {
private DateTimeUtil() {
super();
}
public static void main(final String... args) {
final LocalDateTime now = LocalDateTime.now();
final LocalDateTime utc = DateTimeUtil.toUtc(now);
System.out.println("Now: " + now);
System.out.println("UTC: " + utc);
}
public static LocalDateTime toZone(final LocalDateTime time, final ZoneId fromZone, final ZoneId toZone) {
final ZonedDateTime zonedtime = time.atZone(fromZone);
final ZonedDateTime converted = zonedtime.withZoneSameInstant(toZone);
return converted.toLocalDateTime();
}
public static LocalDateTime toZone(final LocalDateTime time, final ZoneId toZone) {
return DateTimeUtil.toZone(time, ZoneId.systemDefault(), toZone);
}
public static LocalDateTime toUtc(final LocalDateTime time, final ZoneId fromZone) {
return DateTimeUtil.toZone(time, fromZone, ZoneOffset.UTC);
}
public static LocalDateTime toUtc(final LocalDateTime time) {
return DateTimeUtil.toUtc(time, ZoneId.systemDefault());
}
}
Дивлячись на відповіді та питання, здається, питання було істотно змінено. Отже, щоб відповісти на поточне питання:
Перетворити LocalDateTime на LocalDateTime в UTC.
LocalDateTime
не зберігає жодної інформації про часовий пояс, він просто зберігає значення року, місяця, дня, години, хвилини, секунди та менших одиниць. Тож важливе питання: який часовий пояс оригіналу LocalDateTime
? Це також може бути UTC, тому перетворення не повинно бути здійснено.
Враховуючи, що ви все-таки задали питання, ви, мабуть, мали на увазі, що оригінальний час перебуває у часовому поясі за замовчуванням у вашій системі, і ви хочете перевести його у UTC. Оскільки зазвичай LocalDateTime
об’єкт створюється за допомогою LocalDateTime.now()
якого повертає поточний час у часовому поясі за замовчуванням. У цьому випадку перетворення буде таким:
LocalDateTime convertToUtc(LocalDateTime time) {
return time.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}
Приклад процесу перетворення:
2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+1 // [atZone] converted to ZonedDateTime (system timezone is Madrid)
2019-02-25 10:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 10:39 // [toLocalDateTime] losing the timezone information
У будь-якому іншому випадку, коли ви чітко вказуєте часовий пояс часу для перетворення, перетворення буде таким:
LocalDateTime convertToUtc(LocalDateTime time, ZoneId zone) {
return time.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}
Приклад процесу перетворення:
2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+2 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2019-02-25 09:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 09:39 // [toLocalDateTime] losing the timezone information
atZone()
методРезультат atZone()
методу залежить від часу, переданого як аргумент, оскільки він враховує всі правила часового поясу, включаючи літній час. У прикладах час був 25 лютого, в Європі це означає зимовий час (без літнього часу).
Якби ми використовували іншу дату, скажімо, 25 серпня з минулого року, результат був би іншим, враховуючи літній час:
2018-08-25 11:39 // [time] original LocalDateTime without a timezone
2018-08-25 11:39 GMT+3 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2018-08-25 08:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2018-08-25 08:39 // [toLocalDateTime] losing the timezone information
Час GMT не змінюється. Тому зміщення в інших часових поясах коригується. У цьому прикладі літній час Естонії становить GMT + 3, а зимовий час GMT + 2.
Крім того, якщо ви вказали час у переході зміни годинника назад на одну годину. Наприклад, 28 жовтня 2018 р. 03:30 для Естонії це може означати два різні часи:
2018-10-28 03:30 GMT+3 // summer time [UTC 2018-10-28 00:30]
2018-10-28 04:00 GMT+3 // clocks are turned back 1 hour [UTC 2018-10-28 01:00]
2018-10-28 03:00 GMT+2 // same as above [UTC 2018-10-28 01:00]
2018-10-28 03:30 GMT+2 // winter time [UTC 2018-10-28 01:30]
Без зазначення зміщення вручну (GMT + 2 або GMT + 3), час 03:30
для часового поясу Europe/Tallinn
може означати два різні UTC-часи та два різні зміщення.
Як бачите, кінцевий результат залежить від часового поясу часу, переданого як аргумент. Оскільки часовий пояс не можна витягти з LocalDateTime
об’єкта, ви повинні знати самі, з якого часового поясу він походить, щоб перетворити його на UTC.
LocalDateTime does not store any information about the time-zone, it just basically holds the values of year, month, day, hour, minute, second, and smaller units.
tldr: просто неможливо це зробити; якщо ви намагаєтесь це зробити, ви помиляєтеся з LocalDateTime .
Причина полягає в тому, що LocalDateTime не записує часовий пояс після створення екземплярів. Ви не можете перетворити час дати без часового поясу на інший час дати на основі певного часового поясу.
Насправді LocalDateTime.now () ніколи не слід викликати у виробничому коді, якщо ваша мета - не випадкові результати. Коли ви створюєте екземпляр LocalDateTime таким чином, цей екземпляр містить ТІЛЬКИ дату на основі часового поясу поточного сервера, а це означає, що цей фрагмент коду буде генерувати різний результат, якщо він працює на сервері з іншою конфігурацією часового поясу.
LocalDateTime може спростити обчислення дати. Якщо ви хочете отримати справжній універсальний час передачі даних, використовуйте ZonedDateTime або OffsetDateTime: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html .
Спробуйте це за допомогою цього методу.
конвертувати LocalDateTime
To ZonedDateTime
, використовуючи з методу і передати часовий пояс системи по замовчуванням , або ви можете використовувати ZoneId вашої зони , якZoneId.of("Australia/Sydney");
LocalDateTime convertToUtc(LocalDateTime dateTime) {
ZonedDateTime dateTimeInMyZone = ZonedDateTime.
of(dateTime, ZoneId.systemDefault());
return dateTimeInMyZone
.withZoneSameInstant(ZoneOffset.UTC)
.toLocalDateTime();
}
Щоб перетворити назад у вашу місцеву дату, використовуйте час:
LocalDateTime convertFromUtc(LocalDateTime utcDateTime){
return ZonedDateTime.
of(utcDateTime, ZoneId.of("UTC"))
.toOffsetDateTime()
.atZoneSameInstant(ZoneId.systemDefault())
.toLocalDateTime();
}
ви можете реалізувати помічника, роблячи щось подібне:
public static LocalDateTime convertUTCFRtoUTCZ(LocalDateTime dateTime) {
ZoneId fr = ZoneId.of("Europe/Paris");
ZoneId utcZ = ZoneId.of("Z");
ZonedDateTime frZonedTime = ZonedDateTime.of(dateTime, fr);
ZonedDateTime utcZonedTime = frZonedTime.withZoneSameInstant(utcZ);
return utcZonedTime.toLocalDateTime();
}
public static String convertFromGmtToLocal(String gmtDtStr, String dtFormat, TimeZone lclTimeZone) throws Exception{
if (gmtDtStr == null || gmtDtStr.trim().equals("")) return null;
SimpleDateFormat format = new SimpleDateFormat(dtFormat);
format.setTimeZone(getGMTTimeZone());
Date dt = format.parse(gmtDtStr);
format.setTimeZone(lclTimeZone);
return
format.format (dt); }
SimpleDateFormat
заняттям. Принаймні не як перший варіант. І не без будь-яких застережень. Сьогодні у нас набагато кращий java.time
сучасний API дати та часу Java та його DateTimeFormatter
.