2013-10-10 2 views
8


Время и дата вернулись правильны кроме за час, что 1 час меньше, чем должно быть.

Я, кажется, установив все, что требуется, чтобы получить правильное время и дату:Почему Календар возвращает неправильный час с правильным часовым поясом?

- I'm using Calendar.getInstance(), instead of new Date() 
- I'm setting the timezone of the Calendar instance with Timezone.getTimeZone 
- I'm using DateFormat and SimpleDateFormat to format the output 


Мой часовой пояс является Eastern Standard Time, иначе UTC/GMT-5:00. Ни одна из этих линий не оказывают никакого эффекта:

- cal.setTimeZone(TimeZone.getTimeZone(cal.getTimeZone().getDisplayName())); 
- cal.setTimeZone(TimeZone.getTimeZone("EST")); 
- cal.setTimeZone(TimeZone.getTimeZone("UTC")); 
- cal.setTimeZone(TimeZone.getTimeZone("GMT")); 
- cal.setTimeZone(TimeZone.getTimeZone("GMT-5:00")); 

... но каждый из этих вариантов задает нужный мне часовой пояс.


Вот моя попытка, где я ошибочно добавляя 1 час к экземпляру Calendar:

PrintWriter output = null; 

try { 
    output = new PrintWriter(
    new BufferedWriter(new FileWriter("output.txt", true))); 

    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:ms MM/dd/yyyy"); 
    Calendar cal = Calendar.getInstance(); 

    // ...doesn't seem to be working: 
    cal.setTimeZone(TimeZone.getTimeZone(cal.getTimeZone().getDisplayName())); 

    /* 
    * adding an extra hour here, to make up for the incorrect hour value??? 
    * ...without this line, everything is correct except the hour = n - 1: 
    */ 
    //cal.setTimeInMillis(cal.getTimeInMillis() + (1000 * 60 * 60)); 

    // printing to console here: 
    System.out.println(dateFormat.format(cal.getTime())); 
    System.out.println(cal.getTimeZone().getDisplayName()); 

    // printing to the log-file here: 
    output.println(dateFormat.format(cal.getTime())); 
    output.println(cal.getTimeZone().getDisplayName()); 

} catch (IOException e) { 
    e.printStackTrace(); 

} finally { 
    if (output != null) { 
    output.close(); 
    } 
} 


Выход:

10:05:43:543 10/10/2013 
GMT-05:00 

НЕПРАВИЛЬНО - Это должно быть 11:05:43:543! (приписка - я, к сожалению, не может использовать Joda-Time)

+0

Летнее время? – John

+0

@ Джон - я не знаю, хороший вопрос ... дневной сберегательный период в этом году, по-видимому, начинается в воскресенье 10 марта и заканчивается в воскресенье 3 ноября. Могли ли «Календарь» и/или «Часовой пояс» * не учитывать это? –

+2

Существует ответ в ссылке: http://stackoverflow.com/questions/10545960/how-to-tackle-daylight-savings-using-timezone-in-java Надеюсь, что это будет полезно. – guanda

ответ

3

1) Установите TimeZone in SimpleDateFormat

2) Используйте либо UTC, либо «реальный» часовой пояс, как («Австрия/Вена»);
(Название страны и самый большой город в TimeZone).
EST (= UTC-5) не является часовым поясом, очень подходящим для вычислительного назначения, потому что это время без летнего времени.

Еще один пример из центральной Европы:
Зимой мы используем MEZ (CET), летом (летнее время) мы используем (MESZ = CEST).
Но вы хотите, чтобы ваш компьютер показывал это для вас, поэтому не используйте это:

TimeZones являются геологическими, поэтому требуется название страны. (. Например, в России некоторое время назад, и испания обсуждается сейчас)
Каждая страна может принять решение об изменении своего часового пояса, когда они хотят

+0

Спасибо @AlexWien, '' Америка/New_York'' работает в моем случае. Мне интересно, почему часовой пояс, такой как «EST», является приемлемым параметром, если он не учитывает летнее время? –

+1

Наверное, потому, что это часовой пояс, к сожалению, никто из вас не может пройти весь год. Также могут существовать страны, которые не используют летнее время. – AlexWien

1

Календарь не учитывает сбережения дневного света.

Согласно этому сообщению: How to tackle daylight savings using Timezone in java

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

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

Это хорошее место, чтобы начать: http://download.java.net/jdk8/docs/api/java/time/ZoneId.html

+0

Это возможный комментарий или лучше улучшить ваш ответ! –

0


Для потомков, вот мой улучшенный код, основанный на пост «How to tackle daylight savings using Timezone in java»:

PrintWriter output = null; 

try { 
    output = new PrintWriter(
     new BufferedWriter(new FileWriter("output.txt", true))); 

    // here are the relevant changes (a lot less code!): 
    TimeZone zone = TimeZone.getTimeZone("America/New_York"); 
    SimpleDateFormat simpleFormat = new SimpleDateFormat("HH:mm:ss:ms MM/dd/yyyy"); 
    simpleFormat.setTimeZone(zone); 

    // printing to console here: 
    System.out.println(simpleFormat.format(new Date())); 
    System.out.println(simpleFormat.getTimeZone().getDisplayName()); 

    // printing to the log-file here: 
    output.println(simpleFormat.format(new Date())); 
    output.println(simpleFormat.getTimeZone().getDisplayName()); 

} catch (IOException e) { 
    e.printStackTrace(); 

} finally { 
    if (output != null) { 
    output.close(); 
    } 
} 


Обратите внимание, что я использую SimpleDateFormatвместо из DateFormat, чтобы настроить формат вывода (не нужно использовать оба).

+1

На всякий случай кто-то сталкивается с этой проблемой, формат, используемый здесь для даты и времени (HH: mm: ss: ms MM/dd/yyyy), не всегда действителен. Это зависит от того, как и где вы храните это. Хранение в базе данных MySQL как datetime, которое вам нужно использовать (например, yyyy-MM-dd HH: mm: ss). Пример здесь - это просто вход в файл или консоль, чтобы использованный формат был в порядке. – Blizzardengle

Смежные вопросы