Как установить часовой пояс 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.
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?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
- Java 9 brought some minor features and fixes.
- Java SE 6 and Java SE 7
- Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android (26+) bundle implementations of the java.time classes.
- For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
- If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
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