Справочник языка
UTC и часовые пояса
Одна и та же запись времени означает разное в зависимости от пояса, а при переходе часов местные показания и вовсе становятся неоднозначными. Чтобы работать с такими данными, нужно уметь переводить календарное значение в однозначный момент на шкале UTC и обратно. Это делают UTCOFFSET, TOUTC, FROMUTC, TOINSTANT, FROMINSTANT и INSTANTVALUE; они связывают дату-время без собственного пояса с правилами выбранного пояса.
Календарное время и момент
Тип DATETIME хранит календарную дату и время суток без часового пояса. Такое значение означает показание часов: «29 февраля, 12:34». Оно удобно для дат рождения, расписаний и времени работы, но не говорит, где именно эти часы находились.
Тип UTCDATETIME хранит момент времени: однозначную точку на общей шкале UTC. Такое значение не зависит ни от часового пояса, ни от перевода часов. Оно нужно там, где время является фактом события: когда отправлено сообщение, когда записана операция, какое из двух событий произошло раньше.
Различие проявляется при переходе часов. В Нью-Йорке 3 ноября 2024 года время с 01:00 до 02:00 наступает дважды. Два разных момента дают одинаковую календарную запись 2024-11-03 01:30:00, и как значения DATETIME они неразличимы. Как значения UTCDATETIME они различаются на час.
DIM first AS UTCDATETIME = "2024-11-03T05:30:00Z"
DIM second AS UTCDATETIME = "2024-11-03T06:30:00Z"
PRINT first = second
PRINT FROMINSTANT(first, "America/New_York")
PRINT FROMINSTANT(second, "America/New_York")Ожидаемый вывод:
FALSE
2024-11-03 01:30:00
2024-11-03 01:30:00
Момент и календарное значение не смешиваются неявно. Сравнение UTCDATETIME с DATETIME, присваивание момента переменной DATE или DATETIME и обратное присваивание отклоняются при проверке программы. Перевод выполняют явные функции TOINSTANT и FROMINSTANT, потому что для него нужен часовой пояс. Момент печатается с признаком Z, поэтому его текст нельзя спутать с календарной записью.
TOINSTANT
TOINSTANT возвращает момент времени, соответствующий календарной дате-времени в заданном поясе. Функция переводит показание местных часов в однозначную точку на шкале UTC: она нужна, когда известны местные дата, время и пояс, а дальше требуется сравнивать события или хранить их. Вызывается она в выражениях консольных и графических программ; оператор SCREEN или CANVAS не требуется.
Синтаксис
TOINSTANT(<значение>)TOINSTANT(<значение>, <часовой пояс>)
Аргументы
Первый аргумент должен иметь тип DATETIME и читается как местное время. Второй аргумент — STRING: "UTC", "LOCAL" или идентификатор пояса, известный среде запуска. Без второго аргумента используется местный пояс среды запуска.
Результат
Функция возвращает значение типа UTCDATETIME. Доли секунды сохраняются.
Правила и ограничения
Время перехода часов проверяется. Пропущенное время, которого в этом поясе не существовало, и повторяющееся время, которое наступало дважды, отклоняются: иначе один и тот же текст давал бы два разных момента. Результат не хранит ни пояс, ни смещение.
Диагностика
Компилятор отклоняет неверное число аргументов и несовместимый тип аргумента. MB3007 возникает при неизвестном поясе, неоднозначном местном времени и выходе за допустимый диапазон дат.
Пример
DIM localValue AS DATETIME = "2024-02-29 15:34:56"
PRINT TOINSTANT(localValue, "Europe/Moscow")Ожидаемый вывод:
2024-02-29T12:34:56Z
См. также
FROMINSTANT
Функция FROMINSTANT возвращает календарную дату-время, в которую заданный момент выглядит в выбранном поясе. Так один и тот же момент показывают в местных часах нужного пояса: например, для вывода на экран или для записи в отчёт. Вызов допустим в выражении консольной и графической программы, оператор SCREEN или CANVAS не нужен.
Синтаксис
FROMINSTANT(<момент>)FROMINSTANT(<момент>, <часовой пояс>)
Аргументы
Первый аргумент должен иметь тип UTCDATETIME. Второй аргумент — STRING: "UTC", "LOCAL" или идентификатор пояса. Без второго аргумента используется местный пояс среды запуска.
Результат
Функция возвращает значение типа DATETIME без часового пояса. Доли секунды сохраняются.
Правила и ограничения
Обратное преобразование неоднозначно по своей природе: при переходе часов два разных момента дают одинаковую местную запись. Поэтому FROMINSTANT подходит для показа момента, но не для его хранения. Чтобы сохранить событие, храните сам момент, а не результат этой функции. Повторный TOINSTANT для полученной записи в период перехода часов закономерно сообщит ошибку неоднозначности.
Диагностика
Компилятор отклоняет неверное число аргументов и несовместимый тип аргумента. MB3007 возникает при неизвестном поясе и выходе за допустимый диапазон дат.
Пример
DIM moment AS UTCDATETIME = "2024-02-29T12:34:56Z"
PRINT FROMINSTANT(moment, "Europe/Moscow")Ожидаемый вывод:
2024-02-29 15:34:56
См. также
INSTANTVALUE
INSTANTVALUE возвращает момент времени, прочитанный из текста с признаком UTC. Функция разбирает момент, записанный в тексте: например, прочитанный из файла или полученный от внешней программы. Вызывается она в выражениях консольных и графических программ; оператор SCREEN или CANVAS не требуется.
Синтаксис
INSTANTVALUE(<текст>)
Аргументы
Передайте STRING вида yyyy-MM-ddTHH:mm:ssZ. Допускается дробная часть секунд: точка и от одной до семи цифр перед признаком Z.
Результат
Функция возвращает значение типа UTCDATETIME.
Правила и ограничения
Признак Z обязателен: текст без него означает календарную запись и требует пояса, поэтому он не угадывается. Смещение вида +03:00 не принимается: языка пока не имеет формы, которая сохраняла бы смещение, и молчаливое приведение скрыло бы потерю. Тот же строгий разбор действует при неявном присваивании текста переменной UTCDATETIME.
Диагностика
Компилятор отклоняет неверное количество аргументов и несовместимый тип аргумента. MB3007 возникает при тексте без Z, со смещением, с недопустимой датой или неверной дробной частью.
Пример
PRINT INSTANTVALUE("2024-02-29T12:34:56.125Z")Ожидаемый вывод:
2024-02-29T12:34:56.125Z
См. также
UTCOFFSET
UTCOFFSET возвращает смещение часового пояса относительно UTC в минутах, то есть разницу между местными часами и UTC. Вызывать её можно в выражении консольной или графической программы; оператор SCREEN или CANVAS не требуется.
Синтаксис
UTCOFFSET()UTCOFFSET(<местная дата и время>)UTCOFFSET(<дата и время в поясе>, <часовой пояс>)
Аргументы
Значение задаёт дату и время: передайте DATETIME, DATE (дополняется полуночью) или STRING в точной форме yyyy-MM-dd HH:mm:ss. Оно не содержит собственного идентификатора пояса. Часовой пояс должен быть STRING: "UTC", "LOCAL" или идентификатор, который знает среда запуска. "LOCAL" означает системный местный пояс. Пустая строка и неизвестный идентификатор недопустимы; набор идентификаторов зависит от платформы. Без аргументов используются текущий момент и местный пояс; с одним аргументом используется местный пояс.
Результат
Результат INTEGER в минутах: положительный знак означает опережение UTC.
Правила и ограничения
Формы с датой учитывают правила выбранного пояса на эту дату. Значение трактуется как местные часы пояса, а не как мгновение UTC.
При отладке форма UTCOFFSET() читает часы и ограничивает обратный шаг. Формы с явно переданным календарным значением вычисляют смещение для него и не обрывают историю по правилу чтения текущего времени.
Диагностика
Компилятор отклоняет неверное количество аргументов и несовместимый тип аргумента. MB3007 возникает при неизвестном поясе, неверной строке, пропущенном или повторённом местном времени при переводе часов.
Пример
DIM value AS DATETIME = "2024-02-29 12:34:56"
PRINT UTCOFFSET(value, "UTC")Ожидаемый вывод:
0
См. также
TOUTC
Функция TOUTC возвращает дату и время, преобразованные из выбранного пояса в UTC, — так местную дату и время приводят к UTC. Вызов допустим в выражении консольной и графической программы; оператор SCREEN или CANVAS не нужен.
Синтаксис
TOUTC(<дата и время>)TOUTC(<дата и время>, <часовой пояс>)
Аргументы
Значение задаёт дату и время: передайте DATETIME, DATE (дополняется полуночью) или STRING в точной форме yyyy-MM-dd HH:mm:ss. Оно не содержит собственного идентификатора пояса. Часовой пояс должен быть STRING: "UTC", "LOCAL" или идентификатор, который знает среда запуска. "LOCAL" означает системный местный пояс. Пустая строка и неизвестный идентификатор недопустимы; набор идентификаторов зависит от платформы. Если пояс не указан, используется местный пояс среды запуска.
Результат
Функция возвращает значение типа DATETIME. Из местного времени вычитается смещение пояса на указанную дату.
Правила и ограничения
Пропущенные и неоднозначные местные часы при переходе летнего времени отклоняются.
Диагностика
Компилятор отклоняет неверное количество аргументов и несовместимый тип аргумента. MB3007 возникает при недопустимом поясе, строке, выходе результата за годы 1–9999; для TOUTC также при пропущенных или неоднозначных местных часах.
Пример
DIM value AS DATETIME = "2024-02-29 12:34:56"
PRINT TOUTC(value, "UTC")Ожидаемый вывод:
2024-02-29 12:34:56
См. также
FROMUTC
FROMUTC возвращает дату и время, преобразованные из UTC в выбранный пояс: это нужно для отображения значения UTC на местных часах. Функция работает в выражениях консольных и графических программ, оператор SCREEN или CANVAS не требуется.
Синтаксис
FROMUTC(<дата и время>)FROMUTC(<дата и время>, <часовой пояс>)
Аргументы
Значение задаёт дату и время: передайте DATETIME, DATE (дополняется полуночью) или STRING в точной форме yyyy-MM-dd HH:mm:ss. Оно не содержит собственного идентификатора пояса. Часовой пояс должен быть STRING: "UTC", "LOCAL" или идентификатор, который знает среда запуска. "LOCAL" означает системный местный пояс. Пустая строка и неизвестный идентификатор недопустимы; набор идентификаторов зависит от платформы. Если пояс не указан, используется местный пояс среды запуска.
Результат
Функция возвращает значение типа DATETIME. К UTC прибавляется смещение целевого пояса на исходное мгновение.
Правила и ограничения
Исходное значение всегда трактуется как UTC. Преобразование в часы повторённого периода допустимо, но результат без пояса может быть неоднозначен при обратном TOUTC.
Диагностика
Компилятор отклоняет неверное количество аргументов и несовместимый тип аргумента. MB3007 возникает при недопустимом поясе, строке, выходе результата за годы 1–9999; для TOUTC также при пропущенных или неоднозначных местных часах.
Пример
DIM value AS DATETIME = "2024-02-29 12:34:56"
PRINT FROMUTC(value, "UTC")Ожидаемый вывод:
2024-02-29 12:34:56