Получить дату в текущем часовом поясе в java

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

Когда я использую calendar.getTimezone.getDefaultName, он всегда возвращает мне GMT. (в идеале он должен вернуть мой текущий часовой пояс, который является IST) Я пытаюсь преобразовать эту строку "2014-02-14T06: 04: 00: 00", которая находится в GMT в мой часовой пояс datetime. Он всегда возвращает меня в то же время в GMT.

Все, что я вижу, это то, что все предлагают использовать Timezone. т.е.

dateFormatter.setTimezone("any_arbitary_timezone");

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

Ответы

Ответ 1

Вот способ получить идентификатор TimeZone, который соответствует вашему смещению системных часов,

Calendar cal = Calendar.getInstance();
long milliDiff = cal.get(Calendar.ZONE_OFFSET);
// Got local offset, now loop through available timezone id(s).
String [] ids = TimeZone.getAvailableIDs();
String name = null;
for (String id : ids) {
  TimeZone tz = TimeZone.getTimeZone(id);
  if (tz.getRawOffset() == milliDiff) {
    // Found a match.
    name = id;
    break;
  }
}
System.out.println(name);

Ответ 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 ) ;

Ответ 3

Я считаю, что вы ищете библиотеку Joda. Он имеет функциональность лучше, чем классы Calendar или Date, как указано в ответе здесь.

Эта функция должна быть особенно полезной.