如何将LocalDateTime转换为GregorianCalendar?

mem*_*und 9 java java-time

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

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

结果:

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)
Run Code Online (Sandbox Code Playgroud)

Unk*_*own 8

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

无论LocalDateTimeZonedDateTime实现所谓的接口时序,延伸TemporalAccessor.

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

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

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

码:

public static ZonedDateTime from(final TemporalAccessor temporal) {
            if (temporal instanceof ZonedDateTime) {
                return (ZonedDateTime) temporal;
            }

            try {
                final 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 (final DateTimeException ex) {
                throw new DateTimeException("Unable to obtain ZonedDateTime from TemporalAccessor: " +
                        temporal + " of type " + temporal.getClass().getName(), ex);
            }
        }
Run Code Online (Sandbox Code Playgroud)

现在我们来解决你的问题.

你正在ZonedDateTime转向这个Temporal方法.所以时间不是ZonedDateTime的一个实例,它来了TemporalAccessor;

所以你得到的错误是因为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);
Run Code Online (Sandbox Code Playgroud)

用Junit测试

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


Ram*_*A.G 5

您还必须提供ZoneId。我将不得不查询为什么会这样。看到后,我将立即进行编辑和发布。

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

结果:

java.util.GregorianCalendar[time=1472664659000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Calcutta",offset=19800000,dstSavings=0,useDaylight=false,transitions=6,lastRule=null],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,MILLISECOND=0,ZONE_OFFSET=19800000,DST_OFFSET=0]
Run Code Online (Sandbox Code Playgroud)

编辑: 刚刚碰到这个有趣的线程 ...

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