java 日历返回错误时区的日期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26678030/
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
Calendar returns date in wrong time zone
提问by Dónal
If I execute the following on a computer in the GMT timezone
如果我在 GMT 时区的计算机上执行以下操作
TimeZone timeZone = TimeZone.getTimeZone('IST'); // India Standard Time
Calendar calendar = Calendar.getInstance(timeZone);
System.out.println(calendar.getTime());
It prints
它打印
Fri Oct 31 15:18:22 GMT 2014
格林威治标准时间 2014 年 10 月 31 日星期五 15:18:22
Why is the date printed in the computer's default time zone, rather than the TimeZone
the Calendar
was constructed with?
为什么日期印在计算机的默认时区,而不是TimeZone
在Calendar
与构建?
采纳答案by Jigar Joshi
because Date
object doesn't have timezone as part of its state, You need SimpleDateFormat to format and print the date in your required timezone
因为Date
对象没有时区作为其状态的一部分,您需要 SimpleDateFormat 以您所需的时区格式化和打印日期
回答by Basil Bourque
The Answer by Joshiis correct but brief. I'll expand a bit, and show an alternative with modern classes.
Joshi的回答是正确但简短的。我将扩展一点,并展示现代类的替代方案。
Date
has no time zone
Date
没有时区
Your code calendar.getTime()
extracts a java.util.Date
object from the java.util.Calendar
object.
您的代码从对象中calendar.getTime()
提取一个对象。java.util.Date
java.util.Calendar
The java.util.Date
class has a well-intentioned but confusing feature where its toString
method applies the JVM's current default time zone while generating the string. This creates the illusion that the Date
class has a time zone when it does not. A Date
represents a moment on the timeline as a count of milliseconds since the epoch reference date of first moment of 1970 UTC (1970-01-01T00:00:00Z
). (Even more confusing, the Date
class actually doeshave a time zone nestled deep inside, but is unreachable and irrelevant to this discussion.)
该java.util.Date
班有一个善意的,但令人困惑的功能,使它的toString
方法适用于JVM的当前默认时区而产生的字符串。这会造成Date
班级有时区而没有时区的错觉。ADate
表示时间轴上的一个时刻,作为自 1970 UTC ( 1970-01-01T00:00:00Z
)的第一个时刻的纪元参考日期以来的毫秒计数。(更令人困惑的是,Date
该类实际上确实有一个位于内部深处的时区,但无法访问且与本次讨论无关。)
Avoid legacy date-time classes
避免遗留的日期时间类
The old date-time classes are now legacy, supplanted by the java.time classes. Instead use only the java.time classes.
旧的日期时间类现在是遗留的,被 java.time 类取代。而是仅使用 java.time 类。
Instant
Instant
For a moment in UTC, the equivalent to java.util.Date
, use the Instant
class. The Instant
class represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).
在 UTC 中,相当于java.util.Date
, 使用Instant
该类。该Instant
级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。
Instant instant = Instant.now(); // Current moment in UTC.
ZonedDateTime
ZonedDateTime
To view the same moment through the lens of a particular region's wall-clock time, apply a ZoneId
to get a ZonedDateTime
.
要通过特定区域挂钟时间的镜头查看同一时刻,请应用 aZoneId
以获取ZonedDateTime
.
Specify a proper time zone namein the format of continent/region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 3-4 letter abbreviation such as EST
or IST
as they are nottrue time zones, not standardized, and not even unique(!).
以、、 或等格式指定正确的时区名称。永远不要使用 3-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。continent/region
America/Montreal
Africa/Casablanca
Pacific/Auckland
EST
IST
ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = instant.atZone( z );
Search Stack Overflow for many other Questions and Answers on this topic. This Question is really a duplicate of many others.
在 Stack Overflow 上搜索有关此主题的许多其他问题和答案。这个问题实际上是许多其他问题的重复。
About java.time
关于 java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8and SE 9and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- The ThreeTenABPproject adapts ThreeTen-Backport(mentioned above) for Android specifically.
- See How to use ThreeTenABP….
- Java SE 8和SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 所述ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
回答by Barnesy
When converting the Calendar object to a Date object the timezone is lost. Calendar itself uses the timezone. The following prints to the specified timezone.
将 Calendar 对象转换为 Date 对象时,时区会丢失。日历本身使用时区。以下打印到指定的时区。
TimeZone timeZone = TimeZone.getTimeZone('IST'); // India Standard Time
Calendar calendar = Calendar.getInstance(timeZone);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH) + "/" +
(calendar.get(Calendar.MONTH)+1) + "/" + calendar.get(Calendar.YEAR) + " Time: " +
calendar.get(Calendar.HOUR_OF_DAY) + ":" + calendar.get(Calendar.MINUTE));
System.out.println(calendar.getTime());
(Note do not use the Calendar API like this, its very messy. Use the date formatting api)
(注意不要像这样使用日历 API,它非常混乱。使用日期格式 api)
The Date api has many issues (that's why its been completely redone in java 8).
Date api 有很多问题(这就是它在 java 8 中完全重做的原因)。
回答by prsutar
you have to apply timezone before you print the date/time
您必须在打印日期/时间之前应用时区
example: TimeZone.setDefault(TimeZone.getTimeZone("IST"));
示例: TimeZone.setDefault(TimeZone.getTimeZone("IST"));
(code not tested)
(代码未测试)
回答by SparkOn
Calendar#getTime()- Returns a Date object representing this Calendar's time value (millisecond offset from the Epoch.To be precise the value within a java.util.Date is the number of milliseconds since the Unix epoch, which occurred at midnight January 1st 1970, UTC. and java.util.Date is has no specific time zone.
Calendar#getTime()- 返回一个 Date 对象,表示这个 Calendar 的时间值(从纪元的毫秒偏移量。准确地说,java.util.Date 中的值是自 Unix 纪元以来的毫秒数,它发生在 1 月 1 日午夜1970 年,UTC. 和 java.util.Date 没有特定的时区。
on the other hand you can achieve what you are trying to do in this way also
另一方面,您也可以通过这种方式实现您想要做的事情
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
System.out.println(sdf.format(new Date()));