Java 为什么日历以正确的时区返回错误的小时?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19299659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is Calendar returning the wrong hour with the correct time-zone?
提问by Ian Campbell
The time and date returned are correct exceptfor the hour, which is 1 hour less than what it should be.
I seem to be setting everything that is required to get the correct time and date:
返回的时间和日期是正确的,除了小时,它比应有的时间少 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
My timezone is Eastern Standard Time
, aka UTC/GMT-5:00
. None of these lines are having any effect:
我的时区是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"));
...but each of these options sets my desired timezone.
...但这些选项中的每一个都设置了我想要的时区。
这是我的尝试,我错误地为
Calendar
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();
}
}
Output:
输出:
10:05:43:543 10/10/2013
GMT-05:00
WRONG-- It's supposed to be 11:05:43:543
! (p.s. -- I unfortunately can't use Joda-Time)
错误- 应该是11:05:43:543
!(ps - 不幸的是我不能使用Joda-Time)
采纳答案by AlexWien
1) Set the TimeZone in SimpleDateFormat
1) 在 SimpleDateFormat 中设置时区
2) Either use UTC, or a "real" Time Zone like ("Austria/Vienna");
(Country name, and biggest city in TimeZone look it up to be sure)
EST (=UTC-5) is not a time zone very suitable for computational purpose, because it is the time without daylight saving.
2)要么使用UTC,要么使用“真实”时区,如(“奥地利/维也纳”);
(国家名称和时区中最大的城市可以确定)
EST (=UTC-5) 不是一个非常适合计算目的的时区,因为它是没有夏令时的时间。
One more example from central europe:
In Winter we use MEZ (CET), in Summer (Daylight savings) we use (MESZ = CEST).
But you want that your computer caluclates that for you, so don't use that:
来自中欧的另一个例子:
在冬季我们使用 MEZ (CET),在夏季(夏令时)我们使用 (MESZ = CEST)。
但是您希望您的计算机为您计算,所以不要使用它:
TimeZones are geo poilitical, therfore the name of the country is needed.
Each country can decide to change its time zone when they want (e.g russia some time ago, and spain is discussing now.)
时区是地缘,因此需要国家名称。
每个国家都可以决定在他们想要的时候改变它的时区(例如俄罗斯前一段时间,西班牙现在正在讨论。)
回答by Anubian Noob
Calendar does not account for daylight savings.
日历不考虑夏令时。
According to this post: How to tackle daylight savings using Timezone in java
根据这篇文章:如何在 Java 中使用时区解决夏令时
The 3-letter abbreviations should be wholeheartedly avoided in favour of TZDB zone IDs. EST is Eastern Standard Time - and Standard time never observes DST; it's not really a full time zone name. It's the name used for part of a time zone. (Unfortunately I haven't come across a good term for this "half time zone" concept.)
应完全避免使用 3 个字母的缩写,以支持 TZDB 区域 ID。EST 是东部标准时间 - 标准时间从不遵守 DST;它并不是一个完整的时区名称。它是用于部分时区的名称。(不幸的是,我没有遇到过这个“半时区”概念的好词。)
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("EST"));
This is a good place to start: http://download.java.net/jdk8/docs/api/java/time/ZoneId.html
这是一个很好的起点:http: //download.java.net/jdk8/docs/api/java/time/ZoneId.html
回答by Ian Campbell
For posterity, here is my improved code based on the post "How to tackle daylight savings using Timezone in java":
对于后代,这是我基于帖子“如何在 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();
}
}
Note that I'm using SimpleDateFormat
insteadof DateFormat
, to customize the output format (don't need to use both).
请注意,我使用SimpleDateFormat
代替的DateFormat
,自定义输出格式(无需同时使用)。