Преобразовать часовой пояс CST в необходимый часовой пояс Java - PullRequest
0 голосов
/ 06 ноября 2018

Мне нужно преобразовать дату в CST в нужный часовой пояс. Я получу Date as String, например "05.11.2008 12:54:20", который находится в часовом поясе CST. Я должен преобразовать это в часовой пояс, который передается в качестве параметра. предположим, давайте примем это как «GMT + 0530». Результат на вышеуказанную дату в идеале "06 ноября 2018 00:24:20"

Я пробовал приведенный ниже код, который возвращал пройденную дату (11/05/2018 12:54:20) как то же самое вместо (06 ноября 2018 00:24:20). Я выполнил это в системе с часовым поясом IST.

    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("GMT-0600"));
    SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("GMT+0530"));
    System.out.println(sdf2.format(sdf.parse("11/5/2018 12:54:20").getTime()));

Edit: Ответ:

    DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/uuuu HH:mm:ss" ) ;
    LocalDateTime ldt = LocalDateTime.parse( "11/5/2018 12:54:20" , f ) ;
    ZoneId z = ZoneId.of( "GMT-0600" ) ;
    ZonedDateTime zdt = ldt.atZone( z ) ;
    System.out.println(zdt);
    ZoneId zKolkata = ZoneId.of( "GMT+0530" ) ;
    ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;
    System.out.println(zdtKolkata);

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Вы устанавливаете часовой пояс sdf дважды и не устанавливаете часовой пояс sdf2 и, таким образом, получаете неверные результаты. Также вам не нужно вызывать getTime() при передаче объекта на DateFormat::format().

Вот исправленная версия вашего кода:

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
TimeZone cstTimeZone = TimeZone.getTimeZone("CST");
sdf.setTimeZone(cstTimeZone);

SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
sdf2.setTimeZone(TimeZone.getTimeZone("GMT+0530"));
System.out.println(sdf2.format(sdf.parse("11/5/2018 12:54:20")));

Обратите внимание, что используемые вами классы довольно старые, и начиная с версии 8 Java предоставляет новые API даты и времени .

0 голосов
/ 06 ноября 2018

ТЛ; др

LocalDateTime                                            // Represent a date and a time-of-day, without offset nor zone. So *not* a moment, *not* a point on the timeline.
.parse( 
    "11/5/2018 12:54:20" , 
    DateTimeFormatter.ofPattern( "d/M/uuuu HH:mm:ss" )   // Define a formatting pattern to match your input string.
)                                                        // Returns a `LocalDateTime`.
.atZone(                                                 // Assign a time zone, to give meaning to the `LocalDateTime` object, making it a `ZonedDateTime` object.
    ZoneId.of( "America/New_York" )                      // Define a time zone properly with `Continent/Region` naming, never 2-4 letter pseudo-zones such as CST or IST.
)                                                        // Returns a `ZonedDateTime` object.
.withZoneSameInstant(                                    // Adjust from New York time to Kolkata time. Some moment, different wall-clock time.
    ZoneId.of( "Asia/Kolkata" )
)                                                        // Returns another `ZonedDateTime` object rather than altering (“mutating”) the original, per Immutable Objects pattern.
.toString()                                              // Generate text in standard ISO 8601 format, wisely extended to append the name of the time zone in square brackets.

2018-05-11T22: 24: 20 + 05: 30 [Азия / Калькутта]

java.time

Вы используете ужасные старые классы, которые теперь заменены java.time классами.

Проанализируйте вашу входную строку как LocalDateTime, поскольку в ней отсутствуют какие-либо признаки смещения от UTC или часового пояса.

Определите шаблон форматирования, соответствующий вашему вводу.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "d/M/uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( "11/5/2018 12:54:20" , f ) ;

ldt.toString (): 2018-05-11T12: 54: 20

Вы говорите, что это было предназначено для CST. Вы имели в виду стандартное время Китая? Или центральное стандартное время в Северной Америке?

Укажите собственное имя часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 2-4 буквенные сокращения, такие как CST или EST или IST, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).

Полагаю, вы имели в виду что-то вроде нью-йоркского времени.

ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

zdt.toString (): 2018-05-11T12: 54: 20-04: 00 [America / New_York]

И, видимо, вы хотите увидеть этот же момент через призму настенных часов, используемых людьми другого региона, другого часового пояса. Под IST Вы подразумевали ирландское стандартное время? Или стандартное время Индии? Опять же, используйте зоны реального времени, а не псевдозоны из 2-4 символов.

ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;

zdtKolkata.toString (): 2018-05-11T22: 24: 20 + 05: 30 [Азия / Калькутта]

Чтобы увидеть тот же момент в UTC, извлеките Instant.

Instant instant = zdtKolkata.toInstant() ;

instant.toString (): 2018-05-11T16: 54: 20Z

Все три из них (zdt, zdtKolkata, instant) представляют один и тот же момент, одну и ту же точку на временной шкале.

Напротив, ldt как LocalDateTime объект не представляет момент, является не точкой на временной шкале. Это не имело никакого реального смысла, пока вы не назначили ему часовой пояс, чтобы придать ему контекст. До присвоения этой зоны мы не знаем, означает ли это полдень в Австралии, Африке или Америке. Это могло означать около 26-27 часов, диапазон часовых поясов по всему земному шару.

ISO 8601

Вместо того, чтобы придумывать свои собственные форматы для обмена значениями даты и времени в виде текста, используйте стандартные форматы ISO 8601 .

Классы java.time по умолчанию используют форматы ISO 8601 при генерации / разборе строк.


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует выполнить переход на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

...