Вопрос или проблема
[23] > my $now = DateTime.now
2024-09-29T14:59:10.178051+08:00
[24] > my $eight-hours-later = Date.today.DateTime.later(:8hours)
2024-09-29T08:00:00Z
[25] > $now - $eight-hours-later
-3649.82194842
[26] > $now.timezone
28800
[27] > $eight-hours-later.timezone
0
[28] > Date.today.DateTime.timezone
0
[29] > $now.WHAT
(DateTime)
[30] $eight-hours-later.WHAT
(DateTime)
В приведенном REPL, $now
и $eight-hours-later
оба являются DateTime
, но почему $now
имеет часовой пояс 28800, а $eight-hours-later
имеет часовой пояс 0, что приводит к различным поясам времени.
Моя версия Raku:
Добро пожаловать в Rakudo v2024.05.1.
Реализация языка программирования Raku v6.d.
Собрано на MoarVM версии 2024.05
DateTime.now: Возвращает текущую дату и время в локальном часовом поясе системы. Он учитывает настройки часового пояса системы, на которой выполняется ваш код.
Date.today.to_datetime: Date.today дает текущую дату без компонента времени, и когда вы вызываете to_datetime, он преобразует эту дату в объект DateTime с временем, установленным на полночь (00:00:00). По умолчанию он не содержит информации о часовом поясе, если не задано явное значение, что приводит к использованию часового пояса по умолчанию (который может быть UTC).
Явно преобразуйте как DateTime.now, так и Date.today.to_datetime в один и тот же часовой пояс.
Используйте методы, учитывающие часовой пояс, из библиотеки, которая более явно обрабатывает преобразование часовых поясов (например, ActiveSupport в Rails).
Ответ или решение
Разница в таймзонах между DateTime.now
и Date.today.DateTime
в Raku объясняется различиями в том, как эти методы интерпретируют и представляют дату и время.
-
DateTime.now
: Этот метод возвращает текущее время в локальной таймзоне системы, где выполняется код. В вашем примере, результат2024-09-29T14:59:10.178051+08:00
указывает, что на момент вызова метода текущее время – это 14:59:10, и что это значение сдвинуто на +8 часов относительно всемирного координированного времени (UTC+8). Это значение ограничено настройками таймзоны вашей операционной системы. -
Date.today.DateTime
: В отличие отDateTime.now
, методDate.today
возвращает только текущую дату, а не дату с временем. При вызове методаDate.today.DateTime
для создания объектаDateTime
, время по умолчанию устанавливается в 00:00:00 (полночь), а таймзона не задается, в результате чего применяется таймзона по умолчанию, которая, скорее всего, является UTC (сдвиг 0). Таким образом,2024-09-29T08:00:00Z
означает, что это время представлено в UTC.
Это объясняет, почему $now
имеет таймзону 28800 (что соответствует UTC+8), а $eight-hours-later
имеет таймзону 0 (UTC).
Для решения проблемы разницы в таймзонах и их несоответствий, рекомендуется явно задавать таймзоны для всех объектов DateTime
. Вы можете делать это, используя методы, которые управляют конверсиями таймзон, например, если вы хотите, чтобы оба объекта были в одном формате, вы можете использовать:
my $now_in_utc = $now.convert-to('UTC');
my $eight_hours_later_in_utc = $eight-hours-later.convert-to('UTC');
Таким образом, вы можете привести оба объекта к одной и той же таймзоне, что упростит дальнейшие манипуляции с ними и исключит возможные путаницы.
Надеюсь, это объяснение помогло прояснить источники разницы в таймзонах и как их правильно обрабатывать в Raku.