2016-12-02 18 views
2

我想改变一个即时的时间:使用java.time更换时间部分的时刻

Instant instant = Instant.parse("2016-03-23T17:14:00.092812Z"); 
LocalTime newTime = LocalTime.parse("12:34:45.567891"); 
instant.with(newTime); 

我期望能获得与同日的瞬间,但随着新的时间,即2016-03-23 12:34:45.567891。

但它引发异常:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: NanoOfDay 
    at java.time.Instant.with(Instant.java:720) 
    at java.time.Instant.with(Instant.java:207) 
    at java.time.LocalTime.adjustInto(LocalTime.java:1333) 
    at java.time.Instant.with(Instant.java:656) 

任何想法如何解决?

+3

在即时设置时间没有多大意义。你需要一个时区来设置时间。将Instant转换为ZonedDateTime,选择时区。然后在ZonedDateTime上设置时间。然后将ZonedDateTime转换为即时。 –

+0

@WilliMentzel我没有真正的代码中的字符串。我在这里解析它只是为了重现最小的代码。日期时间算术的字符串操作看起来很笨拙。 – kan

回答

3

即时的没有本地日历日期或本地时间的概念。其方法toString()以UTC + 00:00的偏移量描述UTC时间轴上的日期和时间,但它仍然是一个时刻,而不是具有本地情景的信息。

但是,您可以使用以下转换。转换为本地时间戳,处理本地时间戳,然后转换回即时/瞬间。 看到转换取决于具体时区是非常重要的。

Instant instant = Instant.parse("2016-03-23T17:14:00.092812Z"); 
LocalTime newTime = LocalTime.parse("12:34:45.567891"); 

// or choose another one, the conversion is zone-dependent!!! 
ZoneId tzid = ZoneId.systemDefault(); 
Instant newInstant = 
    instant.atZone(tzid).toLocalDate().atTime(newTime).atZone(tzid).toInstant(); 
System.out.println(newInstant); // 2016-03-23T11:34:45.567891Z (in my zone Europe/Berlin) 
3

立即设置时间没有多大意义。你需要一个时区来设置时间。将Instant转换为ZonedDateTime,然后选择时区。然后在ZonedDateTime上设置时间。然后变换ZonedDateTime到即时:

假设时间是UTC的时区:

Instant instant = Instant.parse("2016-03-23T17:14:00.092812Z"); 
LocalTime newTime = LocalTime.parse("12:34:45.567891"); 
ZonedDateTime dt = instant.atZone(ZoneOffset.UTC); 
dt = dt.with(newTime); 
instant = dt.toInstant(); 
System.out.println("instant = " + instant); 
// prints 2016-03-23T12:34:45.567891Z