GregorianCalendar不一致:
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
结果
946681200000, 946681200000, 946684800000
这分别代表GMT + 1,GMT + 1和UTC的2000-01-01午夜。我的时区相对于UTC为+1小时。
这里的问题是getTimeInMillis应该以UTC格式返回自1970-01-01以来的毫秒数。只有testCalThree是正确的。
另一个问题是setTimeZone似乎无法正常工作,具体取决于我之前是否调用过getTimeInMillis。
我的目标是从其他代码中获取我作为参数接收的日历,并获取UTC(java.util)日期以供进一步使用。
答案 0 :(得分:0)
我认为这是Calendar
实施中的一个错误。 time
已缓存,即如果您在重复使用后计算了它,除非某些内容发生变化。
但不知何故,设置时区不会被视为相关更改。
您可以通过明确更改或清除某些字段来强制重新计算时间(以毫秒为单位)。所以这个:
Calendar cal = new GregorianCalendar(2000, 0, 1);
long testCalOne = cal.getTimeInMillis();
cal.clear(Calendar.ZONE_OFFSET);
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalTwo = cal.getTimeInMillis();
Calendar cal2 = new GregorianCalendar(2000, 0, 1);
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
long testCalThree = cal2.getTimeInMillis();
System.out.println(testCalOne + ", " + testCalTwo + ", " + testCalThree);
给出:
946681200000, 946684800000, 946684800000
正如您所料。在设置时区之前,我唯一需要做的就是cal.clear(Calendar.ZONE_OFFSET)
。
无论如何,我想重复评论的建议。如果您重视自己的理智,请切换到JodaTime或Java8日期/时间。
答案 1 :(得分:0)
myGregCal.toZonedDateTime()
.toInstant()
...或...
java.util.Date.from(
myGregCal.toZonedDateTime()
.toInstant()
)
我的目标是从其他代码中获取我作为参数接收的日历,并获取UTC(java.util)日期以供进一步使用。
麻烦的旧日期时间类Calendar
和Date
现在已经遗留下来,取而代之的是java.time类。幸运的是,您可以通过在旧类上调用新方法来转换为/从java.time转换。
ZonedDateTime zdt = myGregCal.toZonedDateTime() ;
对于UTC值,提取Instant
。该类代表UTC时间轴上的一个时刻,分辨率为纳秒。
Instant instant = zdt.toInstant() ;
要生成表示标准ISO 8601格式的UTC值的字符串,请致电toString
。
String output = instant.toString() ;
如果您在生成的字符串中需要其他格式,请转换为更灵活的OffsetDateTime
并使用DateTimeFormatter
。搜索Stack Overflow有很多例子。
最好避开Date
课程。但如果你必须,转换。与Instant
一样,Date
代表UTC时间轴上的一个点。但Date
仅限于毫秒分辨率。所以你冒着数据丢失风险,从超过3位毫秒的小数点开始减去数字,而不是9位数纳秒。
java.util.Date utilDate = Date.from( instant ) ;
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。