В joda время, как преобразовать часовой пояс без изменения времени
Я получаю временную метку UTC из базы данных, которую я устанавливаю в экземпляр JodaTime DateTime
DateTime dt = new DateTime(timestamp.getTime());
Сохраняет время, отличное от 10:00 AM
, но с локальным часовым поясом. Например, я нахожусь в часовом поясе IST, который равен +5: 30 от UTC
Я пробовал много вещей для изменения часового пояса, но при каждой вещи он меняет время от 10:00 AM
на что-то другое, используя разность +5: 30
Есть ли способ, с помощью которого я могу изменить TimeZone, не влияя на текущее время
EDIT:
Если мое текущее время:
2013-09-25 11:27:34 AM UTC
Ниже приведен результат, когда я использую этот new DateTime(timestamp.getTime());
2013-09-25 11:27:34 AM Asia/Kolkata
И вот результат, когда я использую этот new DateTime(timestamp.getTime(), DateTimeZone.UTC)
;
2013-09-25 05:57:34 AM UTC
Ответы
Ответ 1
Вы можете использовать класс LocalDateTime
LocalDateTime dt = new LocalDateTime(t.getTime());
и преобразуйте LocalDateTime
в DateTime
DateTime dt = new LocalDateTime(timestamp.getTime()).toDateTime(DateTimeZone.UTC);
Joda DateTime
обрабатывает любое время в миллисекундах, например "миллис" с 1970-х годов в текущем часовом поясе ". Таким образом, при создании экземпляра DateTime
он создается с текущим часовым поясом.
Ответ 2
Вы можете использовать метод withZoneRetainFields()
DateTime
, чтобы изменить часовой пояс, не изменяя цифры в дате.
Ответ 3
Если ваша временная метка:
2015-01-01T00: 00: 00.000-0500
(это местное время [для меня])
Попробуйте следующее:
DateTime localDt = new DateTime(timestamp.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
2014-12-31T19: 00: 00.000-05: 00
Разрушение:
Это дает вам DateTime, соответствующий вашей метке, указав, что она находится в UTC:
new DateTime(timestamp.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
2015-01-01T00: 00: 00.000Z
Это дает вам DateTime, но со временем, преобразованным в ваше местное время:
new DateTime(timestamp.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
2014-12-31T19: 00: 00.000-05: 00
Ответ 4
Вот как я это делаю:
private DateTime convertLocalToUTC(DateTime eventDateTime) {
// get your local timezone
DateTimeZone localTZ = DateTimeZone.getDefault();
// convert the input local datetime to utc
long eventMillsInUTCTimeZone = localTZ.convertLocalToUTC(eventDateTime.getMillis(), false);
DateTime evenDateTimeInUTCTimeZone = new DateTime(eventMillsInUTCTimeZone);
return evenDateTimeInUTCTimeZone.toDate();
}
Ответ 5
У меня такая же проблема. Прочитав этот набор полезных ответов и учитывая мои конкретные потребности и доступные объекты, я решил эту проблему с помощью другого конструктора DateTime:
new DateTime("2012-04-23T18:25:46.511Z", DateTimeZone.UTC)
Ответ 6
Ни один из приведенных ответов фактически не объяснил проблему. Настоящая проблема в том, что первоначальные предположения были неверными. Временная метка из базы данных была создана с использованием локального часового пояса JVM Asia/Kolkata
а не UTC. Это поведение по умолчанию для JDBC, поэтому он по-прежнему рекомендует устанавливать часовой пояс JVM в UTC.
Если метка времени из базы данных была на самом деле:
2013-09-25 11:27:34 AM UTC
Или в формате ISO-8601:
2013-09-25T11:27:34Z // The trailing 'Z' means UTC
Тогда использование new DateTime(timestamp, DateTimeZone.UTC)
работает нормально. Посмотреть на себя:
Timestamp timestamp = new Timestamp(1380108454000L);
DateTime dt = new DateTime(timestamp.getTime(), DateTimeZone.UTC);
System.out.println(dt); // => 2013-09-25T11:27:34.000Z
Если вам интересно, откуда у меня 1380108454000L
, я просто использовал классы разбора Joda:
ISODateTimeFormat.dateTimeParser().parseMillis("2013-09-25T11:27:34Z")
В качестве альтернативы есть веб-сайты, где вы можете ввести дату, время и часовой пояс, и он возвращает значение эпохи в миллисекундах или наоборот. Это иногда хорошо, как проверка здравомыслия.
// https://www.epochconverter.com
Input: 1380108454000 Click: "Timestamp to Human Date"
Assuming that this timestamp is in milliseconds:
GMT: Wednesday, September 25, 2013 11:27:34 AM
Кроме того, имейте в виду, что класс java.sql.Timestamp
примерно соответствует классу Joda/Java 8+ Instant
. Иногда легче конвертировать между эквивалентными классами, чтобы обнаружить ошибки, как это раньше.
Ответ 7
Также у меня есть другой подход, который мне очень помог.
Я хотел, чтобы поток рабочего потока был временно изменен на определенный часовой пояс (сохраняя время), а затем, когда мой код заканчивается, я снова устанавливаю исходный часовой пояс.
Оказывается, когда вы используете библиотеки joda, выполните:
TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
TimeZone.setDefault(timeZone);
Этого недостаточно.
Нам также необходимо изменить TimeZone в DateTimeZone следующим образом:
@Before
public void setUp() throws Exception {
timeZone = TimeZone.getDefault();
dateTimeZone = DateTimeZone.getDefault();
}
@After
public void tearDown() throws Exception {
TimeZone.setDefault(timeZone);
DateTimeZone.setDefault(dateTimeZone);
}
@Test
public void myTest() throws Exception {
TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
DateTimeZone.setDefault(DateTimeZone.forID(myTempTimeZone));
//TODO
// my code with an specific timezone conserving time
}
Надеюсь, это поможет и кому-то другому.