为什么日历使用正确的时区返回错误的小时?

时间:2013-10-10 15:12:43

标签: java datetime calendar timezone


返回的时间和日期是正确的 除了 的小时,比它应该小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"));

...但是这些选项中的每一个都设置了我想要的时区。

<小时/> 这是我的尝试,我错误地向Calendar实例添加了1小时:

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! ( p.s。 - 我很遗憾无法使用Joda-Time

3 个答案:

答案 0 :(得分:3)

1)在SimpleDateFormat中设置TimeZone

2)使用UTC或“真实”时区(“奥地利/维也纳”);
(国家名称,TimeZone最大的城市,请务必查看)
EST(= UTC-5)不是非常适合计算目的的时区,因为它是没有夏令时的时间。

来自中欧的另一个例子:
在冬季,我们使用MEZ(CET),在夏季(夏令时)我们使用(MESZ = CEST)。
但是你想要你的计算机为你计算,所以不要使用它:

时区具有地理意义,因此需要国家名称 每个国家都可以决定在他们想要的时候改变它的时区(例如俄罗斯前一段时间,西班牙现在正在讨论。)

答案 1 :(得分:1)

日历不考虑夏令时。

根据这篇文章:How to tackle daylight savings using Timezone in java

  

应全心全意地避免使用3个字母的缩写,以支持TZDB区域ID。 EST是东部标准时间 - 标准时间从未观察到DST;它不是真正的全时区名称。它是用于部分时区的名称。 (不幸的是,我没有遇到这个“半时区”概念的好词。)

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

这是一个很好的起点:http://download.java.net/jdk8/docs/api/java/time/ZoneId.html

答案 2 :(得分:0)


对于后代,这是基于帖子&#34; How to tackle daylight savings using Timezone in java&#34;的改进代码:

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来自定义输出格式(不需要同时使用这两种格式)。