Как перевести дату из часового пояса GMT в часовой пояс IST и наоборот в Android
Я работаю над проектом, который извлекает дату / время из серверной части в IST
(индийское стандартное время), как показано "2013-01-09T19:32:49.103+05:30"
. Однако, когда я анализирую его, используя следующий DateFormat
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
с последующим синтаксическим анализом..
Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");
System.out.println("XYZ ==============>"+date);
его отображение даты в формате GMT в качестве выходных данных, т.е
Wed Jan 09 14:02:49 GMT+00:00 2013.
Я пробовал это, используя класс TimeZone как..
TimeZone timeZone=TimeZone.getTimeZone("IST");
sdf.setTimeZone(timeZone);
но никакого эффекта..
Как я мог бы получить Date
объект класса, имеющий дату в IST
формате вместо GMT...
Пожалуйста, предоставьте соответствующее решение..
Редактировать:
Вот как выглядит код:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
TimeZone timeZone=TimeZone.getTimeZone("IST");
sdf.setTimeZone(timeZone);
Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");
String formattedDate=sdf.format(date);
System.out.println("XYZ ==============>"+formattedDate);
Переведено автоматически
Ответ 1
Дата не имеет никакого часового пояса. Это всего лишь количество миллисекунд, прошедших с 1 января 1970 года, 00:00:00 по Гринвичу. Возьмите тот же формат даты, который вы использовали для синтаксического анализа, установите первый часовой пояс и отформатируйте дату, как в следующем примере
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date date = sdf.parse("2013-01-09T19:32:49.103+05:30");
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
System.out.println(sdf.format(date));
вывод
2013-01-09T19:32:49.103+05:30
Обратите внимание, что XX
шаблон X используется для часового пояса ISO 8601 (-08: 00) начиная с 1.7. Если вы находитесь в 1.6, попробуйте Z
. Смотрите SimpleDateFormat API для получения подробной информации о шаблонах форматирования
Ответ 2
Как я мог бы получить объект класса Date, имеющий дату в формате IST вместо GMT...
Вы не можете. Date
не имеет формата или часового пояса. Он просто представляет количество миллисекунд, прошедших с полуночи эпохи Unix 1 января 1970 года по UTC. Вместо этого Date.toString()
всегда используется часовой пояс по умолчанию.
Чтобы использовать определенный формат и часовой пояс, используйте DateFormat
вместо Date.toString()
. Вы можете установить часовой пояс с помощью DateFormat.setTimeZone()
, а затем преобразовать Date
в String
с помощью DateFormat.format()
. DateFormat
сам по себе имеет несколько заводских методов для создания, или вы можете использовать SimpleDateFormat
, если хотите указать конкретный шаблон.
Как говорит Абу, Joda Time является гораздо лучшим API для определения даты / времени, чем встроенный, хотя для простого форматирования даты / времени стандартная библиотека неплохо справляется. Просто обратите внимание, что DateFormat
и его подклассы, как правило, не потокобезопасны.
Ответ 3
tl; dr
OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" ) // Parsed.
.toInstant() // Adjusted to UTC.
Смотрите Текущий код в разделе IdeOne.com .
ISO 8601
Ваша входная строка 2013-01-09T19:32:49.103+05:30
случайно находится в стандартном формате ISO 8601. +05:30
В конце указывает на смещение от UTC на пять с половиной часов вперед, используемое в Индии.
java.time
Вы используете устаревшие классы даты и времени, которые теперь являются устаревшими и заменены классами java.time.
Классы java.time по умолчанию используют форматы ISO 8601 при анализе / генерации строк, представляющих значения даты и времени. Поэтому вообще не нужно указывать шаблон форматирования.
Поскольку ваш ввод представляет момент на временной шкале со смещением от UTC, мы анализируем его как OffsetDateTime
объект.
OffsetDateTime odt = OffsetDateTime.parse( "2013-01-09T19:32:49.103+05:30" );
odt.toString(): 2013-01-09T19:32:49.103+05:30
Чтобы получить простой объект со значением UTC, извлеките Instant
. Этот Instant
класс является базовым классом java.time. Instant
Класс представляет момент на временной шкале в UTC с разрешением в наносекунды (до девяти (9) цифр десятичной дроби).
Вы можете думать о OffsetDateTime
как о Instant
плюс a ZoneOffset
.
Instant instant = odt.toInstant(); // UTC.
При вызове toString
, String
объект генерируется в стандартном формате ISO 8601. Z
В конце является сокращением от Zulu
и означает UTC.
instant.toString(): 2013-01-09T14:02:49.103Z
An Instant
ограничен различными способами, например, при генерации строк в различных форматах. Таким образом, вы можете захотеть работать с OffsetDateTime
скорректированным на UTC смещением; другими словами, смещением на ноль. ZoneOffset
Класс содержит константу для UTC, ZoneOffset.UTC
.
OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC );
Вы также можете применить смещение (или часовой пояс) к Instant
. Вызовите atOffset
или atZone
.
Класс Instant
- это базовый класс строительных блоков java.time. Вероятно, он часто будет использоваться в вашем коде, поскольку лучше всего выполнять большую часть работы в UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.ofHoursMinutes( 5 , 30 ) );
Часовой пояс
Обратите внимание, что смещение от UTC не является часовым поясом. Часовой пояс - это смещение плюс набор правил, прошлых и настоящих, для обработки аномалий, таких как переход на летнее время (DST). Таким образом, часовой пояс всегда предпочтительнее простого смещения, если вы действительно уверены в правильной зоне.
Укажите правильное название часового пояса в формате continent/region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте 3-4-буквенные сокращения, такие как EST
или IST
, поскольку они не являются настоящими часовыми поясами, не стандартизированы и даже не уникальны (!).
Если вы знаете предполагаемый часовой пояс, примените ZoneId
для получения ZonedDateTime
объекта. Но никогда не предполагайте, не сверившись с источником ваших входных данных. У многих разных зон может быть общее определенное смещение. Например, в случае нашего ввода здесь смещение +05:30
сегодня используется как в Индии (Asia/Kolkata
), так и в Шри-Ланке (Asia/Colombo
). У этих двух часовых поясов могут быть разные правила для разных аномалий в их прошлом, настоящем или будущем.
ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = odt.atZoneSameInstant( z );
toString
Метод ZonedDateTime
разумным образом расширяет стандартный формат ISO 8601, добавляя название часового пояса в квадратных скобках. В данном случае, [Asia/Kolkata]
.
zdt.toString(): 2013-01-09T19:32:49.103+05:30[Азия / Калькутта]
О java.time
Платформа java.time встроена в Java 8 и более поздних версий. Эти классы заменяют старые, вызывающие беспокойство, устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Проект Joda-Time, который сейчас находится в режиме обслуживания, рекомендует перейти на java.time.
Чтобы узнать больше, ознакомьтесь с Руководством по Oracle. И найдите в Stack Overflow множество примеров и пояснений. Спецификация - JSR 310.
Где получить классы java.time?
- Java SE 8 и SE 9 и более поздних версий
- Встроенный.
- Часть стандартного Java API с комплексной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и SE 7
- Большая часть функций java.time обратно перенесена на Java 6 и 7 в ThreeTen-Backport.
- Android
- Проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше) специально для Android.
- Смотрите Как использовать ....
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является испытательным полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и больше.
Ответ 4
Вы можете сделать это просто с помощью класса Calender . Пожалуйста, проверьте приведенные ниже фрагменты:
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
calendar.setTimeInMillis(<--time stamp-->);
//calendar.setTime(<--date object of gmt date-->);
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy 'at' hh:mm a");
sdf.setTimeZone(TimeZone.getDefault());
String result=sdf.format(calendar.getTime());