Как решить проблему перехода на летнее время с помощью часового пояса в Java


Я должен напечатать время EST в моем приложении Java. Я установил часовой пояс в EST, используя:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));

но когда переход на летнее время выполняется в этом часовом поясе, мой код не печатает правильное время (он печатает на 1 час меньше).

Как заставить код работать, чтобы всегда читать правильное время, независимо от того, наблюдается ли переход на летнее время или нет?

PS: Я попытался установить часовой пояс в EDT, но это не решает проблему проблема.

7   52   2012-05-11 09:37:10

7 ответов:

это проблема для начала:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));

3-буквенные сокращения следует полностью избегать в пользу идентификаторов зон TZDB. Есть Восточный стандартный время - и стандартный время никогда не наблюдает DST; это не совсем полное имя часового пояса. Это имя используется для часть часовой пояс. (К сожалению, я не нашел хорошего термина для этой концепции "половины часового пояса".)

вы хотите полное время имя зоны. Например, America/New_York находится в восточном часовом поясе:

TimeZone zone = TimeZone.getTimeZone("America/New_York");
DateFormat format = DateFormat.getDateTimeInstance();
format.setTimeZone(zone);

System.out.println(format.format(new Date()));

другие ответы верны, особенно the one by Jon Skeet, но устаревшая.

java.время

эти старые классы даты и времени были вытеснены java.время фреймворк, встроенный в Java 8 и более поздние версии.

если вы просто хотите текущее время в UTC, используйте Instant класса.

Instant now = Instant.now();

EST не является часовым поясом, как объясняется в правильный ответ от Jon скит. Таких 3-4 письма коды не являются ни стандартизированными, ни уникальными, и далее путаница с переходом на летнее время (DST). Использовать правильное название часового пояса в формате "страна/регион".

возможно, вы имели в виду Восточное стандартное время на восточном побережье Северной Америки? Или Египет Стандартное Время? Или Время Европейского Стандарта?

ZoneId zoneId = ZoneId.of( "America/New_York" );
ZoneId zoneId = ZoneId.of( "Africa/Cairo" );
ZoneId zoneId = ZoneId.of( "Europe/Lisbon" );

использование ZoneId объект, чтобы получить текущий момент, настроенный на определенный часовой пояс, чтобы произвести ZonedDateTime объект.

ZonedDateTime zdt = ZonedDateTime.now( zoneId ) ;

отрегулируйте этот ZonedDateTime в другой часовой пояс, создав другой объект ZonedDateTime из первого. Ява.временные рамки использует неизменяемые объекты вместо изменения (мутации) существующих объектов.

ZonedDateTime zdtGuam = zdt.withZoneSameInstant( ZoneId.of( "Pacific/Guam" ) ) ;

вместо ввода " EST "для часового пояса вы можете ввести" EST5EDT " как таковой. Как вы заметили, просто " EDT " не работает. Это будет учитывать проблему летнего времени. Строка кода выглядит так:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST5EDT"));

в этой ответ:

TimeZone tz = TimeZone.getTimeZone("EST");
boolean inDs = tz.inDaylightTime(new Date());
public static float calculateTimeZone(String deviceTimeZone) {
    float ONE_HOUR_MILLIS = 60 * 60 * 1000;

    // Current timezone and date
    TimeZone timeZone = TimeZone.getTimeZone(deviceTimeZone);
    Date nowDate = new Date();
    float offsetFromUtc = timeZone.getOffset(nowDate.getTime()) / ONE_HOUR_MILLIS;

    // Daylight Saving time
    if (timeZone.useDaylightTime()) {
        // DST is used
        // I'm saving this is preferences for later use

        // save the offset value to use it later
        float dstOffset = timeZone.getDSTSavings() / ONE_HOUR_MILLIS;
        // DstOffsetValue = dstOffset
        // I'm saving this is preferences for later use
        // save that now we are in DST mode
        if (timeZone.inDaylightTime(nowDate)) {
            Log.e(Utility.class.getName(), "in Daylight Time");
            return -(ONE_HOUR_MILLIS * dstOffset);
        } else {
            Log.e(Utility.class.getName(), "not in Daylight Time");
            return 0;
        }
    } else
        return 0;
}

в java DateFormatter по умолчанию использует DST, чтобы избежать экономии дневного света (DST), вам нужно вручную сделать трюк,
сначала вы должны получить смещение DST, т. е. на сколько миллисекунд DST применяется, например, где-то DST также в течение 45 минут, а в некоторых местах-в течение 30 минут
но в большинстве случаев DST составляет 1 час
вы должны использовать объект часового пояса и проверить с датой, попадает ли он под DST или нет, а затем вам нужно вручную добавить смещение DST в него. для например:

 TimeZone tz = TimeZone.getTimeZone("EST");
 boolean isDST = tz.inDaylightTime(yourDateObj);
 if(isDST){
 int sec= tz.getDSTSavings()/1000;// for no. of seconds
 Calendar cal= Calendar.getInstance();
 cal.setTime(yourDateObj);
 cal.add(Calendar.Seconds,sec);
 System.out.println(cal.getTime());// your Date with DST neglected
  }

реализация класса часового пояса для установки часового пояса в календарь обеспечивает переход на летнее время.

java.утиль.Часовой пояс представляет собой смещение часового пояса, а также вычисляет летнее время.

пример кода:

TimeZone est_timeZone = TimeZoneIDProvider.getTimeZoneID(TimeZoneID.US_EASTERN).getTimeZone();
Calendar enteredCalendar = Calendar.getInstance();
enteredCalendar.setTimeZone(est_timeZone);