如何将LocalDateTime转换为GregorianCalendar?

时间:2016-08-08 07:27:12

标签: java java-time

如果无法解析简单的日期时间,为什么可以将LocalDateTime对象传递给ZonedDateTime.from()方法,如下所示?

@Test
public void test() throws Exception {
    GregorianCalendar.from(ZonedDateTime.from(LocalDateTime.parse("2016-08-31T23:00:59")));
}

结果:

java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: 2016-08-31T23:00:59 of type java.time.LocalDateTime
    at java.time.ZonedDateTime.from(ZonedDateTime.java:565)

2 个答案:

答案 0 :(得分:7)

  

为什么可以将LocalDateTime对象传递给   ZonedDateTime.from()方法,如果不能解析一个简单的   日期时间?

LocalDateTimeZonedDateTime都实现了名为Temporal的接口,扩展了TemporalAccessor

LocalDateTime是ISO-8601日历系统中没有时区的日期时间,例如2007-12-03T10:15:30

ZonedDateTime是ISO-8601日历系统中带有时区的日期时间,例如2007-12-03T10:15:30 + 01:00欧洲/巴黎。

现在,如果您看到期望TemporalAccessorfrom(TemporalAccessor temporal)方法的实现。 ZonedDateTime和LocalDateTime都实现了超级接口TemporalAccessor的方法(Temporal extends TemporalAccessor),这是正常的(多态行为),允许我们传递Local和Zoned日期时间。

代码:

public static ZonedDateTime from(TemporalAccessor temporal) {
            if (temporal instanceof ZonedDateTime) {
                return (ZonedDateTime) temporal;
            }
            try {
                ZoneId zone = ZoneId.from(temporal);
                if (temporal.isSupported(INSTANT_SECONDS)) {
                    long epochSecond = temporal.getLong(INSTANT_SECONDS);
                    int nanoOfSecond = temporal.get(NANO_OF_SECOND);
                    return create(epochSecond, nanoOfSecond, zone);
                } else {
                    LocalDate date = LocalDate.from(temporal);
                    LocalTime time = LocalTime.from(temporal);
                    return of(date, time, zone);
                }
            } catch (DateTimeException ex) {
                throw new DateTimeException("Unable to obtain ZonedDateTime from TemporalAccessor: " +
                        temporal + " of type " + temporal.getClass().getName(), ex);
            }
        }

现在我们来解决你的问题了。

您正在将LocalDateTime.parse("2016-08-31T23:00:59")传递给from(TemporalAccessor temporal)方法。所以temporal不是ZonedDateTime的一个实例,而是ZoneId zone = ZoneId.from(temporal);

所以你得到的错误是因为LocalDateTime不包含 时区。

如何解决问题?

将Zone Id与ZonedDateTime

一起使用
LocalDateTime ldt = LocalDateTime.parse("2016-08-31T23:00:59");
ZoneId zoneId = ZoneId.of("Europe/Paris");
ZonedDateTime zdt = ldt.atZone(zoneId);
GregorianCalendar gc = GregorianCalendar.from(zdt);

使用Junit测试

@Test
public void test() throws Exception {
    ZoneId zoneId = ZoneId.of("Europe/Paris");
    GregorianCalendar.from(LocalDateTime.parse("2016-08-31T23:00:59").atZone(zoneId));
}

答案 1 :(得分:4)

你也必须提供ZoneId,我将不得不查看为什么会这样做,我会在看到后立即编辑和发布

LocalDateTime ldt = LocalDateTime.parse("2016-08-31T23:00:59");
GregorianCalendar gc = GregorianCalendar.from(ZonedDateTime.of(ldt, ZoneId.systemDefault()));
System.out.println(gc);

结果:

java.util.GregorianCalendar中[时间= 1472664659000,areFieldsSet =真,areAllFieldsSet =真,宽大=真,区= sun.util.calendar.ZoneInfo [ID = “亚洲/加尔各答”,偏移= 19800000,dstSavings = 0 ,useDaylight =假,过渡= 6,lastRule =空],Firstdayofweek可= 2,minimalDaysInFirstWeek = 4,ERA = 1,YEAR = 2016,MONTH = 7,WEEK_OF_YEAR = 35,WEEK_OF_MONTH = 5,DAY_OF_MONTH = 31,DAY_OF_YEAR = 244, DAY_OF_WEEK = 4,DAY_OF_WEEK_IN_MONTH = 5,AM_PM = 1,HOUR = 11,HOUR_OF_DAY = 23,MINUTE = 0,SECOND = 59,微差= 0,ZONE_OFFSET = 19800000,DST_OFFSET = 0]

编辑 刚刚遇到这个帖子(Unable to obtain ZonedDateTime from TemporalAccessor when parsing a Date

  

Java 8 java.time。*包是一个非常严格的包。它不允许类型和输入之间的灵活性 - 如果您需要ZonedDateTime对象,则必须从具有时区,日期和时间的输入构造它。一段时间。