#excel #java-time #zoneddatetime #excel-dates
#excel #java-время #zoneddatetime #excel-даты
Вопрос:
Дата-время в Excel сохраняется как количество дней, прошедших с 1900-01-01 ( 1, поскольку, по его мнению, произошло 1900-02-29). Дробь в числе — это смещение по времени в сутках.
Это число не имеет понятия о часовых поясах. Таким образом, 12.5 — это 1900-01-12T12:00:00 в часовом поясе, в котором открыта ваша электронная таблица. Откройте его в Colorado, и он покажет полдень. Откройте его в Германии, и он показывает полдень. Это не мгновение, это LocalDateTime.
Для нашей системы, где мы храним все как OffsetDateTime или ZonedDateTime (в зависимости от того, как datetime было передано нам), логично, я думаю, создать ZonedDateTime из этого.
Что приводит к вопросу, как мне создать ZonedDateTime, присвоенный этому номеру Excel datetime, в местном часовом поясе?
Комментарии:
1. Вы могли бы сохранить datetime как UDT, возможно, в скрытом столбце, и использовать UDF, который извлекает смещение часового пояса из региональных настроек системы отдельных компьютеров, чтобы произвести корректировку.
2. Это может содержать некоторую полезную информацию superuser.com/questions/763996 /…
Ответ №1:
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 использует только целые числа, я использую его самую высокую степень детализации, наносекунды. Это приведет к переполнению a long
в 2192 году, поэтому для решения, рассчитанного на будущее, вы можете рассмотреть возможность добавления целых дней отдельно и преобразования только доли в nanos.