Как установить часовой пояс java.утиль.Свидание?


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

8 164

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. Date

как указано в других правильных ответах, 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. Элемент 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.время

The java.время фреймворк встроен в Java 8 и более поздние версии. Эти классы вытесняют беспокойных старых наследие классы даты и времени, такие как java.util.Date,Calendar,& SimpleDateFormat.

в Joda-Time, теперь режим обслуживания, советует миграция в java.время классы.

дополнительные сведения см. В разделе элемент Oracle Tutorial. Поиск переполнения стека для многих примеров и объяснений. Спецификация является JSR 310.

вы можете обменять java.время объекты непосредственно с вашей базой данных. Используйте JDBC водитель соответствуют JDBC 4.2 или позже. Нет необходимости в строках, нет необходимости в java.sql.* классы.

где получить java.время занятий?

The ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательным полигоном для возможных будущих дополнений к java.время. Вы можете найти некоторые полезные классы, такие как Interval,YearWeek,YearQuarter и больше.


Joda Времени

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

на Joda-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.утиль.Дата.

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

Поиск StackOverflow для "Joda date", чтобы найти еще много примеров, некоторые довольно подробные.


на самом деле есть и часовой пояс, встроенный в 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 есть некоторые дополнительные варианты/утилиты, которые могут быть полезны. Edit записка Спонга напомнила мне, что я слышал действительно хорошие вещи о 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;
}

это post.

если кто-нибудь нуждается в этом, если вам нужно преобразовать 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);