Преобразование строки в соответствующую дату с помощью часового пояса java

у меня есть дата с часовым поясом, я хочу преобразовать его в другой часовой пояс, например. У меня есть дата '3/15/2013 3:01:53 PM', которая находится в часовом поясе 'GMT-06:00'. Я хочу преобразовать это в часовой пояс GMT-05:00. У меня много поиска, и я смущен тем, как на самом деле работает дата. Как применить часовой пояс на сегодняшний день. Я попробовал с SimpleDateFormat, календарем, а также со смещением.

DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss aaa XXX");
df.setTimeZone(TimeZone.getTimeZone("GMT")); 
Date dt = null;
try {
    dt = df.parse("3/15/2013 3:01:53 PM -06:00");
} catch (ParseException e) {
    e.printStackTrace();
} 
String newDateString = df.format(dt);
System.out.println(newDateString);

он возвращает выходные данные 03/15/2013 09:01:53 AM Z. Думаю, так и должно быть. 03/15/2013 09:01:53 PM Z, потому что время в 'GMT-06: 00' часовой пояс, поэтому он должен быть HH+6, чтобы получить время в GMT. Я хочу дату в формате "гггг-ММ-ДД чч: мм: СС", где чч находится в течение 24 часов.Пожалуйста, помогите мне с примером. Спасибо заранее.

EDIT:

я преобразую строку в дату с помощью SimpleDateFormat

DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss aaa");
    Date dt = null;
    try {
        dt = df.parse("3/15/2013 3:01:53 PM");
    } catch (ParseException e) {
        e.printStackTrace();
    }

теперь, как вы говорите, Я указываю на календарь, что моя дата принадлежит часовому поясу "GMT-06:00" и установите мою дату,

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-6"));
cal.setTime(dt);

теперь я говорю календарю, что я хочу дату в 'GMT'

cal.setTimeZone (TimeZone.getTimeZone("GMT"));

2 ответов


вам нужны два объекта формата, один для разбора и другой для печати, потому что вы используете два разных часовых пояса, см. здесь:

// h instead of H  because of AM/PM-format
DateFormat parseFormat = new SimpleDateFormat("M/dd/yyyy hh:mm:ss aaa XXX"); 
Date dt = null;
try {
  dt = parseFormat.parse("3/15/2013 3:01:53 PM -06:00");
}catch (ParseException e) {
  e.printStackTrace();
} 

DateFormat printFormat = new SimpleDateFormat("M/dd/yyyy hh:mm:ss aaa XXX"); 
printFormat.setTimeZone(TimeZone.getTimeZone("GMT-05")); 
String newDateString = printFormat.format(dt);
System.out.println(newDateString);

выход: 15.03.2013 04:01:53 PM -05: 00

если вы хотите HH: mm :ss (24-часовой формат), то вы просто замените

hh:mm:ss aaa 

by

HH:mm:ss

в printFormat-шаблон.


комментарий по другим аспектам вопроса:

A java.util.Date не имеет внутреннего часового пояса и всегда ссылается на UTC по спецификации. Вы не можете изменить его внутри этого объекта. Преобразование часового пояса возможно для форматированной строки, однако, как показано в моем примере кода (Вы хотели преобразовать в зону GMT-05).

затем вопрос переключается на новое требование для печати Date-объект в ISO-формате с использованием часового пояса UTC (символ Z). Это можно сделать в форматировании, заменив шаблон на "гггг-мм-дд'Т'ХХ: мм: ssXXX" и явно установив часовой пояс printFormat на GMT+00. Вы следует уточнить, что вы действительно хотите в качестве форматированного вывода.

о java.util.GregorianCalendar: установка часового пояса здесь изменяет объект calendar программным способом, поэтому он влияет на вызовы методов, такие как calendar.get(Calendar.HOUR_OF_DAY). Это не имеет ничего общего с форматированием!


tl; dr

OffsetDateTime.parse( 
    "3/15/2013 3:01:53 PM -06:00" , 
    DateTimeFormatter.ofPattern( "M/d/yyyy H:mm:ss a XXX" )
).withOffsetSameInstant( 
    ZoneOffset.of( -5 , 0 ) 
)

2013-03-15T15:01:53-06:00

java.время

на ответ Хохшильда - это правильно, но использует устаревшие классы. Хлопотные старые классы даты-времени в комплекте с самыми ранними версиями Java были вытеснены современным java.время классы.

проанализируйте входную строку как OffsetDateTime поскольку он содержит смещение от UTC, но не время зона.

String input = "3/15/2013 3:01:53 PM -06:00";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/yyyy h:mm:ss a XXX" );
OffsetDateTime odt = OffsetDateTime.parse( input , f );

odt.toString (): 2013-03-15T15:01:53-06: 00

Совет: сохраните себе некоторые хлопоты и используйте форматы ISO 8601 при обмене данными даты и времени в виде текста. Ява.классы времени используют эти стандартные форматы по умолчанию при анализе / генерации строк.

по-видимому, вы хотите увидеть тот же момент, что и люди в другом месте, используя другое смещение от UTC.

ZoneOffset offset = ZoneOffset.of( -5 , 0 ) ;
OffsetDateTime odt2 = odt.withOffsetSameInstant( offset ) ;

мы видим изменения смещения с 6 до 5, и час дня меняется соответственно с 15 до 16. Один и тот же момент, другое время настенных часов.

odt2.toString (): 2013-03-15T16:01:53-05: 00

генерация строки

Я хочу дату в формате" гггг-ММ-ДД чч:мм:СС", где чч находится в течение 24 часов.

я предлагаю вам всегда включать некоторые указания смещения или zoneunless вы абсолютно уверены, что пользователь понимает из более широкий контекст.

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

String output = odt2.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ).replace( "T" , " " ) ;

2013-03-15 16:01:53


о java.время

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

на Joda Времени, теперь режим обслуживания, советует миграцию в java.время классы.

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

С драйвер JDBC соответствии с JDBC 4.2 или позже вы можете обменять java.время объекты непосредственно с вашей базой данных. Нет необходимости в строках или java.язык SQL.* учебные занятия.

где получить java.время занятий?

  • Java SE 8, Java SE 9, и позже
    • встроенный.
    • часть стандартного API Java со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • большая часть java.функциональность времени обратно портирована на Java 6 & 7 в ThreeTen-Backport.
  • Android
    • более поздние версии Android bundle реализации java.классы время.
    • для более раннего Android,ThreeTenABP проект приспосабливается ThreeTen-Backport (упоминалось выше). См.как использовать ThreeTenABP....

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