Я просматриваю сеть за последние несколько часов, чтобы получить дату и время в моем системном часовом поясе.
Когда я использую calendar.getTimezone.getDefaultName, он всегда возвращает мне GMT. (в идеале он должен вернуть мой текущий часовой пояс, который является IST)
Я пытаюсь преобразовать эту строку "2014-02-14T06: 04: 00: 00", которая находится в GMT в мой часовой пояс datetime.
Он всегда возвращает меня в то же время в GMT.
Все, что я вижу, это то, что все предлагают использовать Timezone. т.е.
Точка - мое приложение будет использоваться в разных географических точках. Я не могу установить его в определенный часовой пояс. Он должен быть установлен в системный часовой пояс, чтобы он отображался в зависимости от того, какой часовой пояс находится в настоящее время у пользователя
Ответ 2
Избегайте java.util.Date
и .Calendar
Эти классы, как известно, хлопотны. Sun/Oracle добавили пакет java.time в Java 8, чтобы вытеснить их. Этот пакет был вдохновлен Joda-Time.
Среди его проблем - это запутанное поведение. Хотя java.util.Date не имеет информации о часовом поясе, реализация toString
применяет текущий часовой пояс JVM, когда вы создаете String. Поэтому он вводит вас в заблуждение, если у вас есть часовой пояс, когда он этого не делает.
Joda времени
UPDATE: проект Joda-Time теперь находится в режиме обслуживания. Команда советует перейти на классы java.time. Перейдите к разделу java.time ниже в этом ответе.
Пакет Joda-Time имеет хорошую четкую поддержку часовых поясов. В отличие от java.util.Date, Joda-Time DateTime знает свой собственный назначенный часовой пояс. Если вы не указали часовой пояс, то часовой пояс JVM, текущий по умолчанию, неявно назначен.
DateTime dateTime = DateTime.now(); // Applies JVM’s default time zone implicitly.
Я рекомендую не полагаться на часовой пояс по умолчанию. Это приводит к путанице и ошибкам при работе с датой.
DateTime dateTime = DateTime.now( DateTimeZone.getDefault() ); // Explicitly using default time zone.
При необходимости вы можете назначить часовой пояс.
DateTime dateTimeKolkata = DateTime.now( DateTimeZone.forID( "Asia/Kolkata" ) ); // Specify a time zone.
Для работы на стороне сервера лучше всего использовать бизнес-логику и хранилище баз данных в UTC.
DateTime dateTimeUtc = DateTime.now( DateTimeZone.UTC ); // Assign UTC (GMT) time zone.
Вы можете конвертировать из назначенного часового пояса в другой, включая текущий часовой пояс по умолчанию JVM.
DateTime dateTime = dateTimeUtc.withZone( DateTimeZone.getDefault() );
Неизменное
Для обеспечения безопасности потоков Joda-Time использует неизменяемые объекты. Вместо изменения объекта такие методы, как withZone
, создают новый экземпляр на основе оригинала.
Строка анализа
Чтобы проанализировать String как DateTime, вы должны указать, включает ли String смещение от UTC и/или часового пояса. Твой нет. Поэтому вы должны указать часовой пояс, с помощью которого можно интерпретировать эту строку. Если вы не укажете, во время разбора будет использоваться текущий часовой пояс JVMs.
В вашем вопросе вы сказали, что String представляет дату-время в UTC (GMT).
DateTime dateTimeUtc = new DateTime( "2014-02-14T06:04:00:00", DateTimeZone.UTC );
После разбора можно при необходимости назначить другой часовой пояс. В тот же момент во временной шкале Вселенной, но показывает другое Wall-Clock time.
DateTime dateTimeDefaultZone = dateTimeUtc.withZone( DateTimeZone.getDefault() );
Итак, обратите внимание, что это был двухэтапный процесс. Сначала мы проанализировали вашу строку, используя наше внешнее знание этого временного пояса, заданного в String, потому что в нем не было внутреннего представления этого часового пояса или смещения. Во-вторых, мы изменили часовой пояс на другой (зона по умолчанию JVM).
Если ваша строка включала смещение +00:00
или обычного Z
, мы могли бы свернуть эти два шага в один.
DateTime dateTimeDefaultZone = new DateTime( "2014-02-14T06:04:00:00Z", DateTimeZone.getDefault() ); // Apply time zone adjustment *after* parsing.
Обратите внимание, что этот конструктор DateTime выглядит как выше, но на самом деле совсем другой. Этот один аргумент зоны времени применяется после разбора, а не во время разбора. Здесь аргумент часовой пояс используется для настройки уже обработанного DateTime. Это Z
на конце делает мир различий.
Источник часового пояса по умолчанию
JVM изначально получает свой часовой пояс по умолчанию из операционной системы хоста. Но имейте в виду, что программист может переопределить это:
Выполнение этого переопределения затрагивает все потоки всех приложений, запущенных в этой JVM. Таким образом, вы должны знать, что часовой пояс JVM по умолчанию обычно совпадает с операционной системой хоста, но не обязательно такой же.
java.time
Joda-Time послужила источником вдохновения для java.time, которая теперь встроена в Java 8 и более поздних версий. Хотя Joda-Time по-прежнему поддерживается активно, его разработчики говорят нам перейти на java.time, как только это будет удобно.
В этой теме java.time очень похож на Joda-Time. Мы можем неявно получить текущую дату-время в текущем часовом поясе JVM, используя простой вызов.
ZonedDateTime now = ZonedDateTime.now();
Я предлагаю всегда лучше говорить о часовом поясе. Даже если вы хотите использовать текущий по умолчанию, попросите явно указать это значение, чтобы сделать ваш код самозарегистрированным.
ZoneId zoneIdDefault = ZoneId.systemDefault();
Затем используйте этот объект часового пояса в получении текущего времени.
ZonedDateTime now = ZonedDateTime.now( zoneIdDefault );
Легко настраивается на другой часовой пояс.
ZoneId zoneIdKolkata = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime nowKolkata = now.withZoneSameInstant( zoneIdKolkata );
Если эта строка ввода представляет собой момент в UTC, добавьте Z
, чтобы обозначить этот факт, и проанализируйте его как Instant
. Instant
- это момент на временной шкале в UTC с разрешением наносекунды.
String input = "2014-02-14T06:04:00:00" + "Z";
Instant instant = Instant.parse( input );
Отрегулируйте Мгновенное действие в определенный часовой пояс.
ZonedDateTime zdtKolkata = ZonedDateTime.ofInstant ( instant , zoneIdKolkata ) ;