Как установить часовой пояс java.утиль.Дата?
Я проанализировал java.util.Date
с String
но он устанавливает локальный часовой пояс как часовой пояс
8 ответов
Использовать 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");
имейте в виду, что java.util.Date
объекты сами по себе не содержат никакой информации о часовом поясе - вы не можете установить часовой пояс на
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.Дата
как указано в других правильных ответах, java.утиль.Дата не имеет часового пояса†. Он представляет UTC / GMT (без смещения часового пояса). Очень запутанно, потому что его toString
метод применяет часовой пояс JVM по умолчанию при создании строкового представления.
избегайте j.u.Дата
по этой и многим другим причинам следует избегать использования встроенной java.утиль.Дата. & Календарь & java.текст.Класса simpledateformat. Они, как известно, хлопотное.
использовать java.пакет времени в комплекте с Java 8.
java.время
java.классы времени могут представлять момент на временной шкале тремя способами:
- UTC (
Instant
) - со смещением (
OffsetDateTime
СZoneOffset
) - с часовым поясом (
ZonedDateTime
СZoneId
)
Instant
на java.время, основной строительный блок Instant
, момент на временной линии в UTC. Использовать Instant
объекты для большей части вашей бизнес-логики.
Instant instant = Instant.now();
OffsetDateTime
применить смещение от-UTC приспособиться в некоторую местность времени.
применить ZoneOffset
для получения OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
лучше применить часовой пояс, смещение плюс правила обработки аномалий, таких как летнее время (DST).
применить ZoneId
до Instant
и ZonedDateTime
. Всегда указывайте правильное название часового пояса. Никогда не используйте 3-4 аббревиатуры, такие как EST
или IST
, которые не являются ни уникальными, ни стандартизированы.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
если входная строка не показатель смещения или зоны, разобрать как LocalDateTime
.
если вы уверены в предполагаемом часовом поясе, назначьте ZoneId
для производства ZonedDateTime
. См. пример кода выше в tl; dr. The 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]
для других форматов используйте DateTimeFormatter
класса. Обычно лучше всего позволить этому классу генерировать локализованные форматы с использованием ожидаемого пользователя языковые и культурные нормы. Или вы можете указать определенный формат.
о java.время
на java.время framework встроен в Java 8 и более поздние версии. Эти классы вытесняют беспокойных старых наследие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
в Joda Времени, теперь режим обслуживания, советует миграцию в java.время классы.
чтобы узнать больше, см. В Oracle Учебник. И search Stack Overflow для многих примеров и объяснений. Спецификация JSR 310.
вы можете обменять java.время объекты непосредственно с вашей базой данных. Используйте С JDBC водитель!--56--> соответствуют JDBC 4.2 или позже. Нет необходимости в строках, нет необходимости в java.sql.*
классы.
где получить java.время занятий?
-
Java SE 8, Java SE 9, Java SE 10, Java SE 11, и позже-часть стандартного API Java С связанным реализация.
- Java 9 добавляет некоторые незначительные функции и исправления.
-
Java SE 6 и Java SE 7
- большая часть java.функциональность времени обратно портирована на Java 6 & 7 в ThreeTen-Backport.
-
Android
- версии Android bundle реализации java.время классы.
- для более раннего Android (ThreeTenABP проект приспосабливается ThreeTen-Backport (упоминалось выше). См.как использовать ThreeTenABP....
на ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательной площадкой для возможных будущих дополнений к java.время. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и больше.
Joda Времени
пока Joda Времени по-прежнему активно поддерживается, его создатели сказали нам перейти на java.время, как только будет удобно. Я ухожу. этот раздел неповрежден в качестве ссылки, но я предлагаю использовать java.time
раздел выше вместо этого.
на Joda Времени, объект даты и времени (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.утиль.Дата.
Java.util.Date date = dateTimeIndia.toDate();
Поиск StackOverflow для "даты joda", чтобы найти еще много примеров, некоторые довольно подробные.
†на самом деле есть is часовой пояс, встроенный в java.утиль.Дата, используемая для некоторых внутренних функций (см. комментарии к этому ответу). Но этот внутренний часовой пояс не является свойством и не может быть установлен. Этот внутренний часовой пояс не используется toString
метод при генерации строкового представления значения даты-времени; вместо текущего часового пояса по умолчанию JVM применяется на лету. Поэтому, как стенография, мы часто говорим " j.u.Дата не имеет часового пояса". Толку? Да. Еще одна причина избегать этих усталых старых классов.
вы также можете установить часовой пояс на уровне 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.util.Calendar
- это обычный способ обработки часовых поясов, используя только классы JDK. Apache Commons есть некоторые дополнительные варианты/утилиты, которые могут быть полезны. редактировать записка Спонга напомнила мне, что я слышал действительно хорошие вещи о Joda Времени (хотя я сам не использовал его).
Если вы должны работать только со стандартными классами JDK, вы можете использовать это:
/**
* Converts the given <code>date</code> from the <code>fromTimeZone</code> to the
* <code>toTimeZone</code>. Since java.util.Date has does not really store time zome
* information, this actually converts the date to the date that it would be in the
* other time zone.
* @param date
* @param fromTimeZone
* @param toTimeZone
* @return
*/
public static Date convertTimeZone(Date date, TimeZone fromTimeZone, TimeZone toTimeZone)
{
long fromTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, fromTimeZone);
long toTimeZoneOffset = getTimeZoneUTCAndDSTOffset(date, toTimeZone);
return new Date(date.getTime() + (toTimeZoneOffset - fromTimeZoneOffset));
}
/**
* Calculates the offset of the <code>timeZone</code> from UTC, factoring in any
* additional offset due to the time zone being in daylight savings time as of
* the given <code>date</code>.
* @param date
* @param timeZone
* @return
*/
private static long getTimeZoneUTCAndDSTOffset(Date date, TimeZone timeZone)
{
long timeZoneDSTOffset = 0;
if(timeZone.inDaylightTime(date))
{
timeZoneDSTOffset = timeZone.getDSTSavings();
}
return timeZone.getRawOffset() + timeZoneDSTOffset;
}
это в должности.
если кому-то это нужно, если вам нужно преобразовать XMLGregorianCalendar
часовой пояс к текущему часовому поясу из UTC, то все, что вам нужно сделать, это установить часовой пояс в 0
, тогда звоните toGregorianCalendar()
- он останется тем же часовым поясом, но Date
умеет конвертировать его в ваш, так что вы можете получить данные оттуда.
XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(
((GregorianCalendar)GregorianCalendar.getInstance());
xmlStartTime.setTimezone(0);
GregorianCalendar startCalendar = xmlStartTime.toGregorianCalendar();
Date startDate = startCalendar.getTime();
XMLGregorianCalendar xmlStartTime = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(startCalendar);
xmlStartTime.setHour(startDate.getHours());
xmlStartTime.setDay(startDate.getDate());
xmlStartTime.setMinute(startDate.getMinutes());
xmlStartTime.setMonth(startDate.getMonth()+1);
xmlStartTime.setTimezone(-startDate.getTimezoneOffset());
xmlStartTime.setSecond(startDate.getSeconds());
xmlStartTime.setYear(startDate.getYear() + 1900);
System.out.println(xmlStartTime.toString());
результат:
2015-08-26T12:02:27.183Z
2015-08-26T14:02:27.183+02:00
преобразуйте дату в строку и сделайте это с помощью SimpleDateFormat.
SimpleDateFormat readFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
readFormat.setTimeZone(TimeZone.getTimeZone("GMT" + timezoneOffset));
String dateStr = readFormat.format(date);
SimpleDateFormat writeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = writeFormat.parse(dateStr);