Excel中的日期时间保存为自1900-01-01以来的天数(因为它认为1900-02-29发生了+1)。数字中的分数是当天的时间偏移量。
这个数字没有时区概念。因此,在您打开电子表格的时区中,12.5是1900-01-12T12:00:00。在科罗拉多州打开它,它显示正午。在德国打开,它显示正午。这不是一个瞬间,它是一个LocalDateTime。
对于我们将所有内容存储为OffsetDateTime或ZonedDateTime(取决于日期时间如何传递给我们)的系统,我认为逻辑上要做的就是从中创建一个ZonedDateTime。
这导致了一个问题,如何在本地时区创建一个ZonedDateTime,设置为此Excel日期时间号?
LocalDate msBaseDate = LocalDate.of(1899, Month.DECEMBER, 31);
double dateFromExcel = 12.5;
long nanosSinceBase = Math.round(dateFromExcel * TimeUnit.DAYS.toNanos(1));
ZonedDateTime dateTime = msBaseDate.atStartOfDay()
.plusNanos(nanosSinceBase)
.atZone(ZoneId.systemDefault());
System.out.println(dateTime);
在我的电脑上,输出是:
1900-01-12T12:00 + 01:00 [欧洲/哥本哈根]
由于java.time只使用整数,因此我使用其最精细的粒度,纳秒。这将在2192年溢出long
,因此对于面向未来的解决方案,您可以考虑单独添加整天,仅将分数转换为纳米级。