Как анализировать дату с GMT TimeZone на IST TimeZone и наоборот в android
Я работаю над проектом, который извлекает Date/Time из backend в 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 в качестве выхода i.e
Wed Jan 09 14:02:49 GMT+00:00 2013.
Я пробовал его с помощью класса TimeZone, как..
TimeZone timeZone=TimeZone.getTimeZone("IST");
sdf.setTimeZone(timeZone);
но никакого эффекта.
Как я могу получить объект класса Date
, имеющий дату в формате IST
вместо GMT...
Пожалуйста, предоставьте соответствующее решение.
EDIT:
Вот как выглядит код:
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, который вы использовали для синтаксического анализа, установите часовой пояс IST и отформатируйте дату, как показано в следующем примере.
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
. См. API SimpleDateFormat для получения подробных сведений о шаблонах формата
Ответ 2
Как я могу получить объект класса Date с датой в формате IST вместо GMT...
Вы не можете. Date
не имеет формата или часового пояса. Он просто представляет собой несколько миллисекунд с эпохи Unix в полночь 1 января 1970 UTC. Вместо этого Date.toString()
всегда использует часовой пояс по умолчанию.
Чтобы использовать определенный формат и часовой пояс, используйте DateFormat
вместо Date.toString()
. Вы можете установить часовой пояс DateFormat.setTimeZone()
, а затем преобразовать Date
в String
с помощью DateFormat.format()
. DateFormat
сам имеет несколько методов factory для создания, или вы можете использовать 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
в конце указывает offset-from-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
плюс 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 и более поздних версий. Эти классы вытесняют неприятный старый legacy классы даты-времени, такие как java.util.Date
, Calendar
и SimpleDateFormat
.
Проект Joda-Time, теперь в режиме обслуживания, советует перейти на java.time.
Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация 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
Проект 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());