Вопрос-ответ

How to set time zone of a java.util.Date?

Как установить часовой пояс java.util.Date?

Я проанализировал a java.util.Date из a String, но он устанавливает местный часовой пояс в качестве часового пояса date объекта.

Часовой пояс не указан в том, String из которого Date выполняется синтаксический анализ. Я хочу установить конкретный часовой пояс для date объекта.

Как я могу это сделать?

Переведено автоматически
Ответ 1

Используйте DateFormat . Например,

SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");
Ответ 2

Имейте в виду, что java.util.Date объекты сами по себе не содержат никакой информации о часовом поясе - вы не можете установить часовой пояс для Date объекта. Единственное, что содержит Date объект, - это количество миллисекунд, прошедших с момента "эпохи" - 1 января 1970 года, 00:00:00 UTC.

Как показывает ZZ Coder, вы устанавливаете часовой пояс для DateFormat объекта, чтобы указать ему, в каком часовом поясе вы хотите отобразить дату и время.

Ответ 3

tl;dr


... проанализировано ... из строки ... часовой пояс не указан … Я хочу установить конкретный часовой пояс


LocalDateTime.parse( "2018-01-23T01:23:45.123456789" )  // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.

В j.u.Date нет часового пояса

Как указано в других правильных ответах, у java.util.Date нет часового пояса. Он представляет UTC / GMT (без смещения часового пояса). Очень запутанный, потому что его toString метод применяет часовой пояс JVM по умолчанию при генерации строкового представления.

Избегайте j.u.Date

По этой и многим другим причинам вам следует избегать использования встроенного java.util .Date & .Calendar & java.text.SimpleDateFormat . Они, как известно, доставляют много хлопот.

Вместо этого используйте пакет java.time, поставляемый в комплекте с Java 8.

java.time

Классы java.time могут представлять момент на временной шкале тремя способами:


  • UTC (Instant)

  • Со смещением (OffsetDateTime с ZoneOffset)

  • С указанием часового пояса (ZonedDateTime с ZoneId)

Instant

В java.time основным строительным блоком является Instant момент на временной шкале UTC. Используйте Instant объекты для большей части вашей бизнес-логики.

Instant instant = Instant.now();

OffsetDateTime

Примените смещение от UTC для настройки на время настенных часов в какой-либо местности.

Примените a ZoneOffset, чтобы получить OffsetDateTime.

ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );

ZonedDateTime

Лучше применить часовой пояс, смещение плюс правила обработки аномалий, таких как переход на летнее время (DST).

Примените a ZoneId к an Instant, чтобы получить a ZonedDateTime. Всегда указывайте правильное название часового пояса. Никогда не используйте 3-4 сокращения, такие как EST или IST, которые не являются ни уникальными, ни стандартизированными.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

LocalDateTime

Если во входной строке отсутствует какой-либо индикатор смещения или зоны, разберите как LocalDateTime.

Если вы уверены в предполагаемом часовом поясе, назначьте ZoneId для создания ZonedDateTime. Смотрите пример кода выше в разделе tl; dr вверху.

Форматированные строки

Вызовите toString метод в любом из этих трех классов, чтобы сгенерировать строку, представляющую значение даты и времени в стандартном формате ISO 8601. Класс ZonedDateTime расширяет стандартный формат, добавляя название часового пояса в скобках.

String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]

For other formats use the DateTimeFormatter class. Generally best to let that class generate localized formats using the user’s expected human language and cultural norms. Or you can specify a particular format.


Table of all date-time types in Java, both modern and legacy


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?


Joda-Time

Хотя Joda-Time все еще активно поддерживается, его создатели посоветовали нам перейти на java.time, как только это будет удобно. Я оставляю этот раздел нетронутым в качестве ссылки, но предлагаю вместо него использовать java.time раздел выше.

В Joda-Time объект date-time (DateTime) действительно знает назначенный ему часовой пояс. Это означает смещение от UTC и правил и истории перехода на летнее время в этом часовом поясе (DST) и других подобных аномалий.

String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );

Вызовите toString метод для генерации строки в формате ISO 8601.

String output = dateTimeIndia.toString();

Joda-Time также предлагает богатые возможности для генерации всех видов других строковых форматов.

При необходимости вы можете преобразовать из Joda-Time DateTime в java.util.Date.

Java.util.Date date = dateTimeIndia.toDate();

Найдите в StackOverflow "дату joda", чтобы найти еще много примеров, некоторые из которых довольно подробные.


На самом деле в java.util. есть часовой пояс, встроенный в .Date, используемый для некоторых внутренних функций (см. Комментарии к этому ответу). Но этот внутренний часовой пояс не отображается как свойство и не может быть установлен. Этот внутренний часовой пояс не используется toString методом при генерации строкового представления значения даты и времени; вместо этого текущий часовой пояс JVM по умолчанию применяется "на лету". Итак, в качестве сокращения мы часто говорим “у j.u.Date нет часового пояса”. Сбивает с толку? ДА. Еще одна причина избегать этих устаревших классов.

Ответ 4

Вы также можете установить часовой пояс на уровне JVM

Date date1 = new Date();
System.out.println(date1);

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
// or pass in a command line arg: -Duser.timezone="UTC"

Date date2 = new Date();
System.out.println(date2);

вывод:

Thu Sep 05 10:11:12 EDT 2013
Thu Sep 05 14:11:12 UTC 2013
java date