繁体   English   中英

按照Java 8中的偏移量转换UTC时间

[英]Convert UTC time as per offset in java 8

我在字符串中有时间和偏移量。

时间以UTC为单位,我必须根据偏移量转换此时间,然后将其分配给Calendar对象。

问题是我正在使用OffsetDateTime类的plusHours()方法。 我得到相同的结果。

OffsetDateTime odtB = OffsetDateTime.parse( "2018-03-26T06:00:00Z" ) ;
odtB.plusHours(2);
System.out.println(odtB); 

例如,如果我的日期是"2018-03-26T06:00:00Z"并且偏移量/时区值是“ +02:00”,如何更改它以获取输出"2018-03-26T08:00:00Z"

首先,第一件事: plusHours方法返回另一个 OffsetDateTime ,但它不会更改原始的。 要获取方法的结果,您需要将其分配给变量:

OffsetDateTime odtB = OffsetDateTime.parse("2018-03-26T06:00:00Z");
odtB = odtB.plusHours(2);
System.out.println(odtB);

这将打印:

2018-03-26T08:00Z

现在您的问题:

例如,如果我的日期是“ 2018-03-26T06:00:00Z”,偏移/时区值是“ +02:00”,如何更改它以获取输出“ 2018-03-26T08:00:00Z”?

我认为您误会了一些概念。 最后的ZUTC指示符 ,它与+00:00相同。

上面的两个日期( 2018-03-26T06:00:00Z2018-03-26T08:00Z )都是UTC,并且每个日期都代表一个不同的时刻(时间轴上的一个不同点)。 当您调用plusHours(2) ,结果是另一个OffsetDateTime ,该时间比第一个时间晚2小时。

如果要将OffsetDateTime 转换为另一个偏移量,则不应为其增加时间。 你应该做这个:

OffsetDateTime odtB = OffsetDateTime.parse("2018-03-26T06:00:00Z");
// convert to offset +02:00
odtB = odtB.withOffsetSameInstant(ZoneOffset.ofHours(2));

现在的结果是2018-03-26T08:00+02:00请注意,偏移量从Z更改为+02:00,但是两者( 2018-03-26T08:00+02:002018-03-26T06:00:00Z )表示同一时刻 (时间轴上的同一点)。

如果使用isEqual (一种检查日期是否对应于同一时刻的方法 )比较结果,这将变得更加清晰:

OffsetDateTime odtB = OffsetDateTime.parse("2018-03-26T06:00:00Z");

// add hours
OffsetDateTime twoHoursLater = odtB.plusHours(2);
System.out.println(odtB.isEqual(twoHoursLater)); // false

// convert to offset +02:00
OffsetDateTime sameInstantDifferentOffset = odtB.withOffsetSameInstant(ZoneOffset.ofHours(2));
System.out.println(odtB.isEqual(sameInstantDifferentOffset)); // true

要转换为其他偏移量,例如+05:30 ,只需更改使用的偏移量即可。 除了使用ZoneOffset.ofHours(2) ,您还可以使用其中之一:

ZoneOffset.ofHoursMinutes(5, 30)
ZoneOffset.of("+05:30")

尝试

OffsetDateTime odtB = OffsetDateTime.parse( "2019-01-16T00:05:00.000" ) ;
odtB = odtB.plusHours(2);
System.out.println(odtB);

据我了解,您希望将字符串中的日期时间(这里是3月26日上午6点)转换为本地时区的同一时间点,即UTC + 2,因此是8 AM(而不是UTC)。 您并不是真的在以正确的方式进行操作。 而是:

    ZoneOffset myOffset = ZoneOffset.ofHours(2);
    odtB = odtB.withOffsetSameInstant(myOffset);
    System.out.println(odtB);

输出:

2018-03-26T08:00 + 02:00

更好的是,而不是依赖偏移量,而是使用实时区域,例如:

    ZoneId myZone = ZoneId.of("Africa/Kigali");
    ZonedDateTime zdt = odtB.atZoneSameInstant(myZone);
    System.out.println(zdt);

2018-03-26T08:00 + 02:00 [非洲/基加利]

如果确实需要OffsetDateTime ,我仍然建议通过上述相关的ZoneId转换,然后再转换回OffsetDateTime

    odtB = zdt.toOffsetDateTime();
    System.out.println(odtB);

2018-03-26T08:00 + 02:00

但是,您说过要将其分配给Calendar 最简单,最正确的方法也要通过ZonedDateTime

    Calendar cal = GregorianCalendar.from(zdt);

希望您知道, Calendar类早已过时。 仍然可能您需要一个不能更改或只是不想立即更改的旧版API的Calendar对象。

如果您希望使用其他偏移量,则可以创建该偏移量:

    ZoneOffset myOffset = ZoneOffset.ofHoursMinutes(5, 30);

但是,我仍然建议您使用适当的时区,例如:

    ZoneId myZone = ZoneId.of("Asia/Kolkata");

您的代码出了什么问题?

我怀疑您有两个错误:

  • 在UTC OffsetDateTime 2小时添加到您的OffsetDateTimeOffsetDateTime您在UTC中增加两个小时。 我认识到您既不想在两个小时后也不想在UTC呆过。
  • 正如其他人所说, plusHours返回具有新值的 OffsetDateTime 您似乎忽略了返回值,实际上丢弃了结果。 该方法需要返回一个新对象,因为OffsetDateTime是不可变的。

编辑:一开始我都没有正确阅读您的问题,也不清楚。 我已经更改了答案,所以现在可以回答我认为您的意思了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM