В joda время, как преобразовать часовой пояс без изменения времени - программирование
Подтвердить что ты не робот

В 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
4b9b3361

Ответ 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
}

Надеюсь, это поможет и кому-то другому.