Java GregorianCalendar意外值
运行上述代码时的输出示例如下:Java GregorianCalendar意外值,java,gregorian-calendar,Java,Gregorian Calendar,运行上述代码时的输出示例如下: TimeZone utcTimezone_ = TimeZone.getTimeZone("UTC"); TimeZone _utc = TimeZone.getTimeZone("Zulu"); DateFormat _fo = new SimpleDateFormat("yyyy-MM-dd HH:mm"); _fo.setTimeZone(_utc); GregorianCalendar gc = new GregorianCalendar(_utc);
TimeZone utcTimezone_ = TimeZone.getTimeZone("UTC");
TimeZone _utc = TimeZone.getTimeZone("Zulu");
DateFormat _fo = new SimpleDateFormat("yyyy-MM-dd HH:mm");
_fo.setTimeZone(_utc);
GregorianCalendar gc = new GregorianCalendar(_utc);
System.out.println(gc.getTime());
System.out.println(gc.get(GregorianCalendar.MINUTE));
System.out.println(gc.get(GregorianCalendar.HOUR_OF_DAY));
在这种情况下,我期望分钟是40分钟(不是10分钟),小时是16分钟(不是7分钟)。
目前我对这一切有什么不理解的?
谢谢
编辑:
如果我将时区更改为CST(我的本地时区),则分钟和小时仍然不匹配:
Mon Sep 16 16:40:37 CST 2013
10
7
输出为:
TimeZone _utc = TimeZone.getTimeZone("CST");
DateFormat _fo = new SimpleDateFormat("yyyy-MM-dd HH:mm");
_fo.setTimeZone(_utc);
GregorianCalendar gc = new GregorianCalendar(_utc);
System.out.println(gc.getTime());
System.out.println(gc.get(GregorianCalendar.MINUTE));
System.out.println(gc.get(GregorianCalendar.HOUR_OF_DAY));
此行在计算机本地时区中打印日历(getTime()
返回一个Date
,其中包含自历元以来与时区无关的毫秒数,然后隐式调用toString()
使用本地时区打印日历)。根据结果,这是CST
System.out.println(gc.getTime());
这些行打印日历时区中的日历字段。根据你的密码是“祖鲁”
:
三字母时区ID
为了与JDK1.1.x兼容,有些
其他三个字母的时区ID(如“PST”、“CTT”、“AST”)为
也支持。但是,不推荐使用它们,因为相同的
缩写通常用于多个时区(例如,“CST”)
可能是美国“中央标准时间”和“中国标准时间”),以及
Java平台只能识别其中一个
System.out.println(gc.getTime());在本地时区(CST)中打印日期,同时将日历时区设置为GMT。避免传统日期时间类
gregorianalendar
是与最早版本的Java捆绑在一起的糟糕的日期时间类之一。现在通过采用JSR310被java.time类取代
ZoneDateTime
不要浪费时间试图理解gregoriacalendar
。该类被ZonedDateTime
专门替换
要与尚未更新为java.time的旧代码进行互操作,可以来回转换。查看添加到旧类的新方法
System.out.println(gc.get(GregorianCalendar.MINUTE));
System.out.println(gc.get(GregorianCalendar.HOUR_OF_DAY));
……还有
ZonedDateTime zdt = myGregCal.toZonedDateTime() ;
询问时间
捕捉在特定时区中看到的当前时刻
GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ;
或者,让我们使用您的具体示例:2013年9月16日星期一16:40:37 CST
ZoneId z = ZoneId.of( "America/Chicago" ) ; // CST is ambiguous, and not a real time zone. Use proper `Continent/Region` names.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
你说的伪区是指中国标准时间还是中央标准时间?我猜是第二个时区,比如America/Chicago
或America/Winnipeg
以大陆/地区
的格式指定,例如美国/蒙特利尔
,非洲/卡萨布兰卡
,或太平洋/奥克兰
。切勿使用2-4个字母的缩写,如EST
或CST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)
把它们放在一起决定一个时刻,一个时间线上的特定点
ZoneId z = ZoneId.of( "America/Chicago" ) ;
zdt.toString():2013-09-16T16:40:37-05:00[美国/芝加哥]
现在,我们已经准备好像你在问题中所做的那样,询问每天的时间部分
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
小时:16
分钟:40
要调整到UTC,请提取一个即时
对象。根据定义,始终以UTC为单位
int hourZdt = zdt.getHour() ;
int minuteZdt = zdt.getMinute() ;
instant.toString():2013-09-16T21:40:37Z
类是java.time的基本构建块,功能有限。为了更灵活,让我们转换为。通过指定常数,我们为其自身指定了与UTC的零小时分秒的偏移量
odt.toString():2013-09-16T21:40:37Z
询问时间部分
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
小时:21
分钟:40
看这个
设备的时间和小时是否正确?我从
gc.getTime
获取Mon-Sep 16 17:18:51 EST 2013
,18
从MINUTE
获取7
从hour\u DAY
获取。如果我使用\u fo.format(gc.getTime())
我得到了2013-09-16 07:18
…这似乎是匹配的…可能,日历忽略了时区…请参考:您能提供新的代码和结果输出吗?请参阅TimeZone javadoc:以了解与JDK 1.1.x的兼容性,一些其他三个字母的时区ID(例如“PST”、“CTT”、“AST”)也受支持。但是,不推荐使用它们,因为同一缩写通常用于多个时区(例如,“CST”可以是美国的“中央标准时间”和“中国标准时间”),Java平台只能识别其中一个。
int hourZdt = zdt.getHour() ;
int minuteZdt = zdt.getMinute() ;
Instant instant = zdt.toInstant() ;
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
int hourOdt = odt.getHour() ;
int minuteOdt = odt.getMinute() ;