Как справиться с летней экономией, используя TimeZone в Java

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

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

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

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

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

В этом и заключается проблема:

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

3-буквенные сокращения должны быть полностью исключены в пользу идентификаторов зоны TZDB. EST – Восточное стандартное время – и стандартное время никогда не соблюдает 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())); 

Другие ответы правильны, особенно тот, что был Джон Скит , но устарел.

java.time

Эти старые classы даты были вытеснены платформой java.time, встроенной в Java 8 и более поздние версии .

Если вам просто нужно текущее время в UTC, используйте class Instant .

 Instant now = Instant.now(); 

EST не является часовым поясом, как объясняется в правильном ответе Джона Скита . Такие 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 из первого. Рамка java.time использует неизменяемые объекты, а не изменяет (мутирует) существующие объекты.

 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 час
вы должны использовать объект Timezone и проверять дату, независимо от того, попадает ли она под 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 } 

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

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

образец кода:

 TimeZone est_timeZone = TimeZoneIDProvider.getTimeZoneID(TimeZoneID.US_EASTERN).getTimeZone(); Calendar enteredCalendar = Calendar.getInstance(); enteredCalendar.setTimeZone(est_timeZone); 
  • Часовой пояс с рельсами 3
  • Игнорирование часовых поясов в Rails и PostgreSQL
  • Как перевести между часовыми поясами Windows и IANA?
  • .NET DateTime.Now возвращает неправильное время, когда изменяется часовой пояс
  • Сопоставление почтового индекса США с часовым поясом
  • linux конвертировать время (для разных часовых поясов) в UTC
  • Драйвер JDBC MySQL 5.1.33 - Проблема с часовым поясом
  • Как использовать пользовательское время в браузере для проверки разницы во времени между клиентом и сервером
  • Как получить смещение часовой пояс в GMT (как GMT + 7: 00) с устройства Android?
  • Как преобразовать время в часовой пояс устройства iPhone?
  • Изменение часового пояса MySQL?
  • Interesting Posts
    Давайте будем гением компьютера.