3
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));

运行上述代码时的输出示例如下:

Mon Sep 16 16:40:37 CST 2013
10
7

在这种情况下,我预计分钟为 40(不是 10),小时为 16(不是 7)。我现在对这一切有什么不理解的?谢谢。

编辑:如果我将时区更改为我的本地时区 CST,则分钟和小时仍然不匹配:

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));

输出是:

Mon Sep 16 21:23:48 CST 2013
53
6
4

3 回答 3

2
System.out.println(gc.getTime());

此行在您的计算机本地时区打印日历(getTime()返回Date包含与时区无关的纪元以来的毫秒数,然后隐式toString()调用使用本地时区打印它)。根据结果​​是CST。

System.out.println(gc.get(GregorianCalendar.MINUTE));
System.out.println(gc.get(GregorianCalendar.HOUR_OF_DAY));

这些行打印日历时区中的日历字段。根据您的代码,它是“祖鲁”。

顺便说一句,强烈建议不要使用三个字母的时区

三个字母的时区 ID

为了与 JDK 1.1.x 兼容,还支持一些其他的三字母时区 ID(例如“PST”、“CTT”、“AST”)。但是,不推荐使用它们,因为相同的缩写通常用于多个时区(例如,“CST”可能是美国“中部标准时间”和“中国标准时间”),Java 平台只能识别其中之一他们。

于 2013-09-16T07:24:44.200 回答
1

System.out.println(gc.getTime()); 在本地时区打印日期 - CST,而您将日历时区设置为 GMT。

于 2013-09-16T07:26:09.103 回答
1

避免遗留的日期时间类

GregorianCalendar是与 Java 的最早版本捆绑在一起的可怕的日期时间类之一。现在被采用 JSR 310的java.time类所取代。

ZonedDateTime

不要浪费时间试图理解GregorianCalendar。该类被专门替换为ZonedDateTime.

要与尚未更新为java.time的旧代码互操作,您可以来回转换。查看添加到旧类的新方法。

ZonedDateTime zdt = myGregCal.toZonedDateTime() ;

……和……</p>

GregorianCalendar myGregCal = GregorianCalendar.from( zdt ) ;

Java 中的日期时间类型表,包括现代和传统

询问一天中的时间

捕捉在特定时区看到的当前时刻。

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 ) ;

或者,让我们使用您的具体示例:Mon Sep 16 16:40:37 CST 2013。

LocalDate ld = LocalDate.of( 2013 , Month.SEPTEMBER , 16 ) ;
LocalTime lt = LocalTime.of( 16 , 40 , 37 ) ;

伪区CST是指中国标准时间还是中央标准时间?我会猜第二个,所以是一个时区,例如America/Chicagoor America/Winnipeg

以、或等格式指定适当的时区名称。切勿使用 2-4 个字母的缩写,例如or或,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。Continent/RegionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTCSTIST

ZoneId z = ZoneId.of( "America/Chicago" ) ;

把它们放在一起来确定一个时刻,时间线上的一个特定点。

ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

zdt.toString(): 2013-09-16T16:40:37-05:00[美国/芝加哥]

现在我们准备好像您在问题中那样询问时间部分。

int hourZdt = zdt.getHour() ;
int minuteZdt = zdt.getMinute() ;

小时Zdt:16

分钟Zdt:40

要适应 UTC,请提取一个Instant对象。根据定义, AnInstant始终采用 UTC。

Instant instant = zdt.toInstant() ;

即时.toString(): 2013-09-16T21:40:37Z

该类是java.timeInstant的基本构建块,功能有限。让我们转换为更大的灵活性。我们通过指定常量来为UTC本身指定零时分秒的 UTC 偏移量。OffsetDateTimeZoneOffset.UTC

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

odt.toString(): 2013-09-16T21:40:37Z

询问时间部分。

int hourOdt = odt.getHour() ;
int minuteOdt = odt.getMinute() ;

小时:21

分钟Odt:40

请参阅在 IdeOne.com 上实时运行的代码


哪个 java.time 库与哪个版本的 Java 或 Android 一起使用的表

于 2019-10-02T21:02:51.103 回答