Руководство работы с датами

Правильная работа с датой и временем

Время на прочтение
12 мин

Количество просмотров 126K

Практически все проекты сталкиваются с проблемами, вызванными неправильной обработкой и хранением даты и времени. Даже если проект используется в одном часовом поясе, все равно после перехода на зимнее/летнее время можно получить неприятные неожиданности. При этом мало кто озадачивается реализацией правильного механизма со старта, потому что кажется, что с этим проблем быть не может, так как все тривиально. К сожалению, в последствии реальность показывает, что это не так.

Логически можно выделить следующие типы значений, относящиеся к дате и времени:

  • Дата и время — «материал для медицинского анализа был собран 15 января 2014 года в 13:17:15»
  • Дата без времени — например, «новый контракт вступает в силу 2 февраля 2016 года»
  • Временной интервал — «отчет был сформирован за 3 минуты 15 секунд»
  • Расписание запланированных событий — «импорт данных из другой системы должен происходить каждый будний день в 10:00»

Рассмотрим каждый пункт по отдельности, не забывая об общих рекомендациях.

Дата и время

Допустим, лаборатория, которая собрала материал для анализа находится в часовом поясе +2, а центральный филиал, в котором следят за своевременным выполнением анализов — в поясе +1. Время, приведенное в примере, было отмечено при сборе материала первой лабораторией. Возникает вопрос — какую цифру времени должен увидеть центральный офис? Очевидно, что программное обеспечение центрального офиса должно показывать 15 января 2014 года 12:17:15 — на час меньше, так как по их часам событие произошло именно в этот момент.

Рассмотрим одну из возможных цепочек действий, через которую проходят данные с клиента на сервер и обратно, позволяющую всегда корректно отображать дату/время согласно текущему часовому поясу клиента:

  1. Значение создается на клиенте, например, 2 марта 2016 15:13:36, клиент находится в часовом поясе +2.
  2. Значение преобразуется в строковое представление для передачи на сервер — “2016-03-02T15:13:36+02:00”.
  3. Сериализованные данные передаются на сервер.
  4. Сервер десериализует время в объект даты/времени, приводя его при этом к своему текущему часовому поясу. Например, если сервер работает в +1, значит объект будет содержать 2 марта 2016 14:13:36.
  5. Сервер сохраняет данные в базу, при этом она не содержит никакой информации о часовом поясе — наиболее часто используемые типы даты/времени просто о нем ничего не знают. Таким образом, в базу будет сохранено 2 марта 2016 14:13:36 в «неизвестном» часовом поясе.
  6. Сервер читает данные из базы и создает соответствующий объект со значением 2 марта 2016 14:13:36. И так как сервер работает в часовом поясе +1, то и это значение будет трактоваться в рамках того же часового пояса.
  7. Значение преобразуется в строковое представление для передачи на клиент — “2016-03-02T14:13:36+01:00”.
  8. Сериализованные данные отправляются на клиент.
  9. Клиент десериализует полученное значение в объект даты/времени, приводя его при этом к своему текущему часовому поясу. Например, если это -5, то отображаемое значение должно быть равно 2 марта 2016 09:13:36.

Вроде бы все целостно, но давайте подумаем, что в этом процессе может пойти не так. На самом деле, проблемы здесь могут случиться почти на каждом шаге.

  • Время на клиенте может быть сформировано вообще без часового пояса — например, DateTime тип в .NET с DateTimeKind.Unspecified.
  • Механизм сериализации может использовать формат, который не включает в себя смещение часового пояса.
  • При десериализации в объект может игнорироваться смещение часового пояса, особенно в «самодельных» десериализаторах — как на сервере, так и на клиенте.
  • При чтении из базы объект даты/времени может быть сформирован вообще без часового пояса — например, DateTime тип в .NET с DateTimeKind.Unspecified. Более того, с DateTime в .NET на практике именно так и получается, если сразу после вычитки явно не указывать другой DateTimeKind.
  • Если сервера приложения, работающие с общей базой данных, находятся в разных часовых поясах — будет серьезная путаница в смещениях во времени. Значение даты/времени, записанное в базу сервером А и прочитанное сервером Б будет заметно отличаться от того же исходного значения, записанного сервером Б и прочитанного сервером А.
  • Перевод серверов приложения из одного пояса в другой приведет к неправильной трактовке уже сохраненных значений даты/времени.

Но самый серьезный недостаток в описанной выше цепочке — это использование локального часового пояса на сервере. Если в нем нет перехода на летнее/зимнее время, то никаких дополнительных проблем не будет. А вот в противном случае можно получить массу неприятных неожиданностей.

Правила перевода на летнее/зимнее время — вещь, строго говоря, переменная. Разные страны могут иногда менять свои правила, и эти изменения должны быть заблаговременно заложены в обновления системы. На практике неоднократно встречались ситуации некорректной работы этого механизма, которые по итогу решались установкой хотфиксов либо операционной системы, либо используемых сторонних библиотек. Вероятность повторения тех же проблем — не нулевая, поэтому лучше иметь способ гарантированно их избежать.

Учитывая описанные выше соображения, сформулируем как можно более надежный и простой подход к передаче и хранению времени: на сервере и в базе данных все значения должны быть приведены к часовому поясу UTC.

Рассмотрим, что нам дает такое правило:

  • При отправке данных на сервер клиент должен передать смещение часового пояса, чтобы сервер мог корректно преобразовать время в UTC. Альтернативный вариант — обязать клиент делать это преобразование, но первый вариант гибче. При получении данных обратно с сервера клиент будет переводить дату и и время в свой локальный часовой пояс зная, что ему в любом случае придет время в UTC.
  • В UTC нет переходов на летнее и зимнее время, соответственно связанные с этим проблемы будут неактуальны.
  • На сервере при чтении из базы не нужно преобразовывать значения времени, достаточно только явно указывать, что оно соответствует UTC. В .NET, например, этого можно достичь установкой DateTimeKind для объекта времени в DateTimeKind.Utc.
  • Разница часовых поясов между серверами, работающими с общей базой данных, как и перевод серверов из одного пояса в другой, никак не отразятся на корректности получаемых данных.

Для реализации такого правила достаточно позаботиться о трех вещах:

  1. Сделать механизм сериализации и десериализации такой, чтобы значения даты/времени корректно переводились из UTC в локальный часовой пояс и обратно.
  2. Убедиться, что десериализатор на стороне сервера создает объекты даты/времени в UTC.
  3. Сделать так, чтобы при вычитке из базы объекты даты/времени создавались в UTC. Этот пункт иногда обеспечивают без изменений кода — просто системный часовой пояс на всех серверах устанавливается в UTC.

Описанные выше соображения и рекомендации отлично работают при сочетании двух условий:

  • В требованиях к системе нет надобности отображать локальное время и/или смещение часового пояса именно в том виде, в котором оно было сохранено. Например, в авиабилетах время вылета и прибытия должно быть распечатано в часовом поясе, соответствующем расположению аэропорта. Или если сервер отправляет на печать инвойсы, созданные в разных странах, на каждом должно в итоге стоять локальное время, а не преобразованное в часовой пояс сервера.
  • Все значения даты и времени в системе являются «абсолютными» — т.е. описывают момент времени в будущем или прошлом, которому соответствует единственное значение в UTC. Например, «пуск ракеты-носителя состоялся в 23:00 по киевскому времени», или «совещание будет идти с 13:30 до 14:30 по минскому времени». В разных часовых поясах цифры для этих событий будут разные, но они будут описывать один и тот же момент времени. Но может так случиться, что требования к программному обеспечению подразумевают «относительное» локальное время для некоторых случаев. Например, «эта передача на телевидении будет идти с 9:00 до 10:00 утра в каждой стране, где есть филиал телеканала». Получается, что показ передачи — это не одно событие, а несколько, причем потенциально все они могут происходить в разные отрезки времени по «абсолютной» шкале.

Для случаев, где нарушается первое условие, задачу можно решить использованием типов данных, содержащих часовой пояс – как на сервере, так и в базе данных. Ниже приведен небольшой перечень примеров для разных платформ и СУБД.

.NET DateTimeOffset
Java org.joda.time.DateTime, java.time.ZonedDateTime
MS SQL datetimeoffset
Oracle, PostgreSQL TIMESTAMP WITH TIME ZONE
MySQL

Нарушение второго условия — более сложный случай. Если это «относительное» время нужно хранить просто для отображения, и нет задачи определить «абсолютный» момент времени, когда событие наступило или наступит для заданного часового пояса — достаточно просто запретить преобразование времени. Например, пользователь ввел начало передачи для всех филиалов телекомпании 25 марта 2016 года в 9:00, и оно в таком виде будет передаваться, храниться и отображаться. Но может случиться, что какой-то планировщик должен автоматически выполнить специальные действия за час до начала каждой передачи (разослать уведомления или проверить наличие каких-то данных в базе телекомпании). Надежная реализация такого планировщика является нетривиальной задачей. Допустим, планировщик осведомлен о том, в каком часовом поясе находится каждый из филиалов. И одна из стран, где есть филиал, через некоторое время решает сменить часовой пояс. Случай не настолько редкий, как может показаться — за этот и два предыдущих года я насчитал больше 10 подобных событий (http://www.timeanddate.com/news/time/). Получается, что либо пользователи должны поддерживать привязки к часовым поясам в актуальном состоянии, либо планировщик должен в автоматизированном режиме брать эту информацию из глобальных источников типа Google Maps Time Zone API. Я не берусь предложить универсальное решение для подобных случаев, просто отмечу, что такие ситуации требуют серьезной проработки.

Как видно из вышесказанного, не существует единого подхода, покрывающего 100% случаев. Поэтому сперва нужно четко понять из требований, какие из упомянутых выше ситуаций будут в вашей системе. С большой вероятностью, все ограничится первым предложенным подходом с хранением в UTC. Ну а описанные исключительные ситуации его не отменяют, а просто добавляют другие решения для частных случаев.

Дата без времени

Допустим, с правильным отображением даты и времени с учетом часового пояса клиента разобрались. Перейдем к датам без времени и примеру, указанному для этого случая в начале — «новый контракт вступает в силу 2 февраля 2016 года». Что будет, если для таких значений использовать те же типы и тот же механизм, что и для «обычных» даты с временем?

Не во всех платформах, языках и СУБД есть типы, хранящие только дату. Например, в .NET есть только тип DateTime, отдельного «просто Date» нет. Даже если при создании такого объекта была указана только дата, время все равно присутствует, и оно равно 00:00:00. Если мы значение «2 февраля 2016 00:00:00» из пояса со смещением +2 переведем в +1, то получим «1 февраля 2016 23:00:00». Для указанного выше примера это будет равносильно тому, что в одном часовом поясе новый контракт начнет действовать 2 февраля, а в другом — 1 февраля. С юридической точки зрения это абсурд и так, конечно же, быть не должно. Общее правило для «чисто» дат предельно простое — такие значения не должны преобразовываться ни на одном шаге сохранения и чтения.

Есть несколько способов избежать преобразование для дат:

  • Если платформа поддерживает тип, представляющий дату без времени, то его и нужно использовать.
  • Добавлять в метаданные объектов специальный признак, который будет говорить сериализатору, что для данного значения часовой пояс нужно игнорировать.
  • Передавать дату с клиента и обратно как строку, а хранить как дату. Такой подход неудобен, если на клиенте дату нужно не только отображать, но еще и производить какие-то операции над ней: сравнение, вычитание и т.д.
  • Передавать и хранить как строку, а преобразовывать в дату только для форматирования с учетом региональных настроек клиента. Имеет еще больше недостатков чем предыдущий вариант — например, если в хранимой строке части даты идут не в порядке «год, месяц, день», то будет невозможно сделать эффективный индексированный поиск по диапазону дат.

Можно, конечно, попытаться привести контрпример и сказать, что контракт имеет смысл только в пределах страны, в которой он заключен, страна находится в одном часовом поясе, и поэтому можно однозначно определить момент вступления его в силу. Но даже в этом случае пользователям из других часовых поясов не будет интересно, в какой момент по их локальному времени произойдет это событие. А даже если бы была нужда показывать этот момент времени, то отображать пришлось бы не только дату, но и время, что противоречит исходному условию.

Временной интервал

С хранением и обработкой временных интервалов все просто: их величина не зависит от часового пояса, поэтому никаких особых рекомендаций здесь нет. Их можно хранить и передавать как количество единиц времени (целое или с плавающей точкой, в зависимости от необходимой точности). Если важна секундная точность — то как количество секунд, если миллисекундная — то как количество миллисекунд и т.д.

А вот вычисление интервала может иметь подводные камни. Предположим, у нас есть типовой код на C#, который считает интервал времени между двумя событиями:

DateTime start = DateTime.Now;
//...
DateTime end = DateTime.Now;
double hours = (end - start).TotalHours;

На первый взгляд, никаких проблем здесь нет, но это не так. Во-первых, могут возникнуть проблемы с юнит-тестированием такого кода, но об этом мы поговорим чуть позже. Во-вторых, давайте представим, что начальный момент времени пришелся на зимнее время, а конечный — на летнее (например, таким образом замеряется количество рабочих часов, а у работников есть ночная смена).

Предположим, код работает в часовом поясе, в котором переход на летнее время в 2016 году происходит в ночь 27 марта, и смоделируем описанную выше ситуацию:

DateTime start = DateTime.Parse("2016-03-26T20:00:15+02");
DateTime end = DateTime.Parse("2016-03-27T05:00:15+03");
double hours = (end - start).TotalHours;

Этот код даст в результате 9 часов, хотя фактически между этими моментами прошло 8 часов. В этом легко убедиться, изменив код вот таким образом:

DateTime start = DateTime.Parse("2016-03-26T20:00:15+02").ToUniversalTime();
DateTime end = DateTime.Parse("2016-03-27T05:00:15+03").ToUniversalTime();
double hours = (end - start).TotalHours;

Отсюда вывод — любые арифметические операции с датой и временем нужно делать, используя либо UTC значения, либо типы, хранящие информацию о часовом поясе. А потом обратно переводить в локальные в случае надобности. С этой точки зрения, изначальный пример легко исправить, поменяв DateTime.Now на DateTime.UtcNow.

Этот нюанс не зависит от конкретной платформы или языка. Вот аналогичный код на Java, имеющий тот же недостаток:

LocalDateTime start = LocalDateTime.now();
//...
LocalDateTime end = LocalDateTime.now();
long hours = ChronoUnit.HOURS.between(start, end);

Исправляется он также легко — например, использованием ZonedDateTime вместо LocalDateTime.

Расписание запланированных событий

Расписание запланированных событий – более сложная ситуация. Универсального типа, позволяющего хранить расписания, в стандартных библиотеках нет. Но такая задача возникает не так уж редко, поэтому готовые решения можно найти без проблем. Хорошим примером является формат планировщика cron, который в том или ином виде используется другими решениями, например, Quartz: http://quartz-scheduler.org/api/2.2.0/org/quartz/CronExpression.html. Он покрывает практически все нужды составления расписаний, включая варианты типа «вторая пятница месяца».

В большинстве случаев писать свой планировщик не имеет смысла, так как существуют гибкие проверенные временем решения, но если по какой-то причине есть надобность в создании своего механизма, то как минимум формат расписания можно позаимствовать у cron.

Общие рекомендации

Помимо описанных выше рекомендаций, посвященных хранению и обработке разнотипных значений времени, есть еще несколько других, о которых тоже хотелось бы сказать.

Во-первых, по поводу использования статических членов класса для получения текущего времени — DateTime.UtcNow, ZonedDateTime.now() и т.д. Как и было сказано, использование их напрямую в коде может серьезно усложнить юнит-тестирование, так как без специальных мок фреймворков подменить текущее время не получится. Поэтому, если вы планируете писать юнит тесты, следует позаботиться о том, чтобы реализацию таких методов можно было подменить. Для решения этой задачи есть как минимум два способа:

  • Выделить интерфейс IDateTimeProvider с единственным методом, возвращающим текущее время. Затем добавить зависимость на этот интерфейс во всех единицах кода, где нужно получать текущее время. При обычном выполнении программы во все эти места будет инжектиться реализация «по умолчанию», которая возвращает реальное текущее время, а в юнит тестах – любая другая необходимая реализация. Такой способ является наиболее гибким с точки зрения тестирования.
  • Сделать свой статический класс с методом для получения текущего времени и возможностью установить любую реализацию этого метода извне. Например, в случае C# кода этот класс может выставлять наружу свойство UtcNow и метод SetImplementation(Func<DateTime> impl). Использование статического свойства или метода для получения текущего времени избавляет от надобности везде явно прописывать зависимость от дополнительного интерфейса, но с точки зрения принципов ООП не является идеальным решением. Однако, если по каким-то соображениям предыдущий вариант не подходит, то можно воспользоваться этим.

Дополнительная проблема, которую следует решить при переходе на свою реализацию провайдера текущего времени — это контроль за тем, чтобы никто «по старинке» не продолжил использовать стандартные классы. Эту задачу легко решить в большинстве систем контроля качества кода. По сути она сводится к поиску «нежелательной» подстроки во всех файлах за исключением того, где объявлена реализация «по умолчанию».

Второй нюанс с получением текущего времени — это то, что клиенту доверять нельзя. Текущее время на компьютерах пользователей может очень сильно отличаться от реального, и если есть логика, завязанная на него, то эта разница может все испортить. Все места, где есть необходимость получать текущее время, должны по возможности выполняться на стороне сервера. И, как уже было сказано ранее, все арифметические операции с временем должны производиться либо в UTC значениях, либо с использованием типов, хранящих смещение часового пояса.

И еще одна вещь, которую хотелось упомянуть — это стандарт ISO 8601, описывающий формат даты и времени для обмена информацией. В частности, строковое представление даты и времени, используемое при сериализации, должно соответствовать этому стандарту для предотвращения потенциальных проблем с совместимостью. На практике крайне редко приходится самому реализовывать форматирование, поэтому сам стандарт может быть полезен в основном в ознакомительных целях.

Работа с Датой и Временем

Используемый формат Даты и Времени

Дата и Время всегда Вводятся и ВЫводятся в фиксированном формате:

DD.MM.YYYY HH:mm:ss

где:
DD — день
MM — месяц
YYYY — год (4 цифры)
HH — часы
mm — минуты
ss — секунды

Например:
● «01.01.2020 00:00:01» — новый 2020 год
● «17.05.2020 19:45:05» — вот более однозначный пример формата выводимого времени.

Переменные Даты и Времени

Для хранения Даты/Времени добавлен специальный тип переменных:

«📕 Время».

Чисто технически, Время можно сохранять и в Текстовых Переменных, но полноценно работать с такими переменными у вас не получится. В Текстовой переменной Время можно только хранить, но не выполнять с ним каких-либо действий.

Синтаксис в сообщениях

В Сообщениях бота — Вывод Даты/Времени осуществляется как обычно — через макрос той переменной в которой оно сохранено.

Синтаксис в выражениях

В Выражениях Функций Времени, при использовании переменных хранящих Время — макросы этих переменных ДОЛЖНЫ браться «в кавычки» так как по сути они являются текстом.

Синтаксис параметра в функции

Пример записи переменной «date1» в выражениях ФУНКЦИЙ ВРЕМЕНИ: {dt_passed("%date1%")}.

Само выражение естественно в {фигурных скобках}.
Подробнее о выражениях — в руководстве по выражениям.

Синтаксис функции

При передаче значения одной функции в другую даже если значение будет текстом, саму функцию в кавычки брать НЕ НУЖНО (смыл этого пункта вам станет ясен позднее) например:
{dt_passed(dt_now()...)}
В примере функция dt_now() передана в качестве параметра функции dt_passed() — кавычки не нужны. Вы поймете этот пример когда ниже причитаете про функции.

Ещё раз: в общем случае, при использовании «Переменных Времени» в Выражениях «Функций Времени» ВСЕГДА берите их макрос «в кавычки»! Иначе ничего не будет работать.

Примеры:
● Сообщение: «Вы нажали кнопку в %date1%«.
(Покажет время сохраненное в переменной «date1«)
● Выражение: {dt_add("%date1%", 1)}
(Покажет время сохраненное в переменной «date1» плюс 1 час)

Базовые функции для работы с Датой и Временем

ВСЯ(!) реальная работа с датами происходит ТОЛЬКО через специальные Функции (Кроме случаев, когда Дату/Время нужно просто отобразить в сообщении). Базовых Функций всего 3:

dt_now() — Текущее Время

dt_now() Текущее время — функция получения «сейчас», то есть текущей Даты и Времени. Нужна чтобы можно было от «сейчас» отсчитывать время, сравнивать его и т.д.

Возвращает значение типа «Дата/Время».

Функция имеет практический смысл в Выражениях, в комбинации с другими функциями или значениями переменных.

Так же результат данной функции можно использовать чтобы сохранить в переменную текущее время (например время, в момент нажатия кнопки). В дальнейшем такую запись можно использовать как «отсечку» для расчетов времени прошедшего с этого момента.

Примеры:
{dt_now()}
Если использовано в Сообщении — выведет текущую дату и время (БЕЗ учета часового пояса) в момент показа юзеру. Если использовано в Выражении кнопки или в Action-е — то текущая дата (на момент срабатывания) может быть записана в переменную.

Время показанное при помощи функции {dt_now()} может НЕ СООТВЕТСТВОВАТЬ  времени показанному при помощи макросов %date% и %time%, потому как в отличии от времени макросов, оно НЕ ЗАВИСИТ от установленного в боте часового пояса.

Не используйте данную функцию для вывода текущего времени в сообщениях (если только ваш часовой пояс не соответствует +3UTC).

Подробнее об установке часового пояса в боте в разделе помощи.
Подробнее о доступных макросах.

Концепция времени данной функции схожа с концепцией времени Python или PHP. То есть это некое единое, стандартизированное время (которое можно выразить в минутах, часах, днях, неделях, месяцах или годах) предназначенное для относительных вычислений временнЫх отрезков, основанных на метках времени, которые вы сами записываете в переменные и используете для вычислений прошедшего или оставшегося времени до или после какого-либо события. В случае привязки этого времени к часовым поясам, временнЫе отрезки могут сбиваться при изменении часового пояса в боте, что может приводить к не предсказуемым — чаще неприятным последствиям (Например сползание сроков инвестов или времени получения бонусов, искажение условий кнопок основанных на времени).

dt_add() — Добавить Время

dt_add(date, hours) Добавить время — функция получения даты, отличающейся от «date» на «hours» часов. Другими словами некая «date» плюс сколько-то «hours«.

Возвращает значение типа «Дата/Время».

Функция принимает (требует для работы) два параметра:
date — та дата от которой происходит отсчет времени.
Обычно, к моменту использования, она уже сохранена в какой-либо Переменной Времени (в этом случае используйте макрос той переменной в кавычках), однако это может быть и Текущее Время из функции «dt_now()»).
hours — это количество часов на которое нужно изменить дату — часы задаются дробным числом (например, 0.5 часов — это 30 минут и т.д.). Данный параметр может быть не только жестко задан при помощи конкретного числа, но может быть представлен и значением Числовой Переменной — в этом случае используйте макрос этой перемеренной (без кавычек).

Часы могут быть отрицательными (если дату надо уменьшить), в этом случае вычисление времени осуществляется в обратном направлении относительный даты в переменной.

Фактически, это функция добавления времени в часах к некой Дате. Результат покажет новую Дату.

Функция нужна для отображения в сообщении или сохранения в переменной, некоторой точки в будущем (например — окончание «похода в лес» в играх) — вычисленной в данной функции.

Примеры:
{dt_add("%date1%", 1)}
Вычислит дату на 1 час позже чем та, что сохранена в переменной «date1«.

Обратите внимание на то, что макрос Переменной Времени «%date1%» — в кавычках, это важно (дата — это текстовая информация)!

Вычислит дату на 1.5 часа позже чем dt_now() «сейчас» (на момент срабатывания выражения).

Например: «Вы ушли, возвращайтесь обратно в {dt_add(dt_now(), 1.5)}«. То есть через полтора часа.

Вычислит дату на «var1» часов позже чем та, что сохранена в переменной «date1«.

Обратите внимание на то, что макрос Переменной Времени «%date1%» — в кавычках, а макрос Числовой Переменной %var1% — без кавычек!

Добавление стандартных отрезков времени

Бывают ситуации когда к дате (сегодняшней или любой другой) нужно добавить некий стандартный отрезок времени, например: час, день, неделю, месяц или год. Для удобства были введены следующие выражения:

Добавит 1 час.

Для часов, однако можно использовать и следующее выражение {dt_add(dt_now(), 1)}.

добавит 1 день

добавит 1 неделю

добавит 1 месяц

добавит 1 год

Естественно вместо функции dt_now() можно использовать любую дату или макрос переменной времени содержащую дату.

dt_diff() — Разница Времени

dt_diff(date1, date2) Разница времени — функция получения разницы в часах (дробных) между двумя датами. Вычисляет «date1» минус «date2«. Если «date2» будет больше (то есть позже по времени) чем «date1» — результат будет отрицательным числом.

Возвращает дробное число Часов.

Функция нужна для получения информации о том, сколько времени в (дробных) часах прошло между двумя событиями «date1» и «date2«.

Примеры:
{dt_diff(dt_now(), "%date1%")}
Допустим ранее вы сохранили Дату/Время в переменной «date1«. Данный пример вычислит (разницу), сколько часов прошло со времени сохраненного в переменной «date1» (то есть от какого-то события в прошлом) до теперешнего момента из функции «dt_now()».

Обратите внимание на то, что макрос Переменной Времени «%date1%» — в кавычках, это важно!

Дополнительные НЕобязательные параметры:

Тип результата: «s», «m», «h», «d» (секунда, минута, час, день). По умолчанию — час.
Округление: «n», «u», «d» (не округлять, округлять вверх, округлять вниз). По умолчанию — не округлять.
{dt_diff("%date%", dt_now(), "s")} — результат в секундах.
{dt_diff("%date%", dt_now(), "d")} — результат в днях (дробных).
{dt_diff("%dater%", dt_now(), "d", "u")} — результат в днях (целых, округленных вверх).

● Пример сообщения:
«С вашего ухода прошло {dt_diff(dt_now(), «%date1%»)} часов.»

● Или поинтереснее:
«За прошедшие {dt_diff(dt_now(), «%date1%»)} часа вы заработали {dt_diff(dt_now(), «%date1%») * 10} монет.»
При условии что юзер получает 10 монет в час.

Сравнение Даты и Времени

Функции Времени, а так же Переменные содержащие данные о Дате и Времени могут служить Условием для выполнения тех или иных действий в Кнопках и Action-ах. Для этого Время можно сравнивать в Условиях этих кнопок и Action-ов.

Даты и Время сравниваются обычными операторами сравнения:
>, >= (Больше, Больше или равно)
<, <= (Меньше, Меньше или равно)
и другими.

Технически можно сравнивать даты на «равно/не равно» (==, !=), но практического смысла в этом — нет: маловероятно что даты совпадут с точностью до миллисекунд.

Пример 1:
Некую Дату нужно сравнить с Настоящим (со временем «сейчас»).
{dt_left("%date1%") == 0}
Время оствшееся до даты равно 0 (нулю). Дата уже прошла.

Функция dt_left() вернёт оставшееся до %date1% время в часах (смотри ниже).

Пример 2:
У вас две Даты «не сейчас».
{dt_diff(%date1%, %date2%) <=0}
Ипользуйте >=, в зависимости от того какая дата должна быть больше.

Функция dt_diff() вернёт разницу между %date1% и %date2% в часах (смотри выше).

Как НЕ НАДО сравнивавть Даты:
{"%date1%" < dt_now()}
Вданном примере происходит сравнение Строк и результат может быть непредстказуемым, несмотря на то что выражение может казаться верным и даже верно работать в большенстве случаев.

Типы результатов Выражений

При записи в переменные результатов работы функций Даты/Времени (когда они сохраняются в переменную через кнопки типа «Бонус», «Обмен», или через «Action-ы»), важно понимать и учитывать то, какого ТИПА результат возвращает та или иная функция Времени. От этого будет зависеть способ записи данных и соответственно то что останется записанным в переменной в конечном итоге.

Результаты бывают двух Типов:
● Тип — Дата/Время. Если выражение возвращает «Дату» — то дата будет ПРИСВОЕНА переменной. Всегда присвоена: то есть старая дата будет затёрта новой.
● Тип — Число: Если выражение возвращает «Число» — то значение будет ДОБАВЛЕНО (или вычтено, если отрицательное) к Дате в переменной. Работа по принципу функции «dt_add()». 

Какой тип результата возвращает та или иная функция, смотрите выше — в описании самих функций.

Дополнительные Функции

Дополнительные функции предоставляют возможности, которые в принципе можно «собрать» и из «Базовых Функций» — осуществив все вычисления самостоятельно. Однако использование «Дополнительных Функций» для «типовых сценариев», позволяет сократить визуальную сложность Выражений и упростить вам работу.

Набор дополнительных функций, вероятнее всего, будет расширятся по мере выявления новых «типовых», активно используемых сценариев (другими словами — по вашим просьбам).

dt_left()

функция, которая возвращает, сколько В ЧАСАХ осталось до указанной даты (date). Если относительно текущего момента дата уже прошла — функция вернет 0 (ноль).

Функция вернет дробное, десятичное количество часов (1.2, 5.7, 34.4). Больше предназначено для удобства вычислений в Выражениях.

Дополнительные НЕобязательные параметры:

Тип результата: «s», «m», «h», «d» (секунда, минута, час, день). По умолчанию — час.
Округление: «n», «u», «d» (не округлять, округлять вверх, округлять вниз). По умолчанию — не округлять.
{dt_left("%datevar%", "s")} — результат в секундах.
{dt_left("%datevar%", "d")} — результат в днях (дробных).
{dt_left("%datevar%", "d", "u")} — результат в днях (целых, округленных вверх).

dt_left_hm()

функция, которая возвращает строку в HH:MM, сколько осталось В ЧАСАХ и МИНУТАХ до указанной даты (date). Если относительно текущего момента дата уже прошла — функция вернет 00:00.

Функция вернет привычное и удобное для понимания человеком количество часов и минут (1:12, 7:42, 36:24). Предназначено для упрощения понимания юзером и удобства вывода значений в Сообщениях.

Дополнительные НЕобязательные параметры:

Форматирование полученных результатов:
{dt_left_hm("31.12.2021 23:59:59", "-")} — собственный разделитель (покажет условно: 170-59)
{dt_left_hm("31.12.2021 23:59:59", " | ", " часов", " минут")} — собственный разделитель и суффиксы для Часов и Минут (покажет условно: 170 часов | 59 минут)

dt_passed()

функция, которая возвращает, сколько прошло В ЧАСАХ с указанной даты (date). Если относительно текущего момента дата ещё не подошла — функция вернет 0 (ноль).

Функция вернет дробное, десятичное количество часов (1.2, 5.7, 34.4). Больше предназначено для удобства вычислений в Выражениях.

Дополнительные НЕобязательные параметры:

Тип результата: «s», «m», «h», «d» (секунда, минута, час, день). По умолчанию — час.
Округление: «n», «u», «d» (не округлять, округлять вверх, округлять вниз). По умолчанию — не округлять.
{dt_passed("%datevar%", "s")} — результат в секундах.
{dt_passed("%datevar%", "d")} — результат в днях (дробных).
{dt_passed("%datevar%", "d", "u")} — результат в днях (целых, округленных вверх).

dt_passed_hm()

функция, которая возвращает строку в HH:MM сколько прошло В ЧАСАХ И МИНУТАХ с указанной даты (date). Если относительно текущего момента дата ещё не подошла — функция вернет 00:00.

Функция вернет привычное и удобное для понимания человеком количество часов и минут (1:12, 7:42, 36:24). Предназначено для упрощения понимания юзером и удобства вывода значений в Сообщениях.

Дополнительные НЕобязательные параметры:

Форматирование полученных результатов:
{dt_passed_hm("31.12.2021 23:59:59", "-")} — собственный разделитель (покажет условно: 170-59)
{dt_passed_hm("31.12.2021 23:59:59", " | ", " часов", " минут")} — собственный разделитель и суффиксы для Часов и Минут (покажет условно: 170 часов | 59 минут)

dt_passedm()

функция, которая возвращает, сколько прошло В ЧАСАХ с указанной даты (date), но не больше (max) часов. Если относительно текущего момента дата ещё не подошла — функция вернет 0 (ноль). Если относительно (data) прошло больше (max) часов — функция вернет (max).

Функция вернет дробное, десятичное количество часов (1.2, 5.7, 34.4). Больше предназначено для удобства вычислений в Выражениях.

dt_passedm_hm()

функция, которая возвращает строку в HH:MM сколько прошло В ЧАСАХ И МИНУТАХ с указанной даты, но не больше (max) часов. Если относительно текущего момента дата ещё не подошла — функция вернет 00:00. Если относительно (data) прошло больше (max) часов — функция вернет (max) в формате HH:MM.

Функция вернет привычное и удобное для понимания человеком количество часов и минут (1:12, 7:42, 36:24). Предназначено для упрощения понимания юзером и удобства вывода значений в Сообщениях.

Дополнительные НЕобязательные параметры:

Форматирование полученных результатов:
{dt_passedm_hm("31.12.2021 23:59:59", "-")} — собственный разделитель (покажет условно: 170-59)
{dt_passedm_hm("31.12.2021 23:59:59", " | ", " часов", " минут")} — собственный разделитель и суффиксы для Часов и Минут (покажет условно: 170 часов | 59 минут)

dt_nextday()

dt_nextday(date)
Функция которая получив дату возвращает дату начала следующего ДНЯ.
Пример указания даты и времени:
dt_nextday("%date% %time%") — при помощи макросов даты и времени
dt_nextday(dt_now()) — при помощи функции «сейчас»
dt_nextday(dt_now_tz()) — при помощи функции «сейчас с учётом часового пояса бота»
Например: получив 01.01.2022 22:22:22 вернет 02.01.2022 00:00:00.

dt_nextmonth()

dt_nextmonth(date)
Функция которая получив дату возвращает дату начала следующего МЕСЯЦА.
Пример указания даты и времени:
dt_nextmonth("%date% %time%") — при помощи макросов даты и времени
dt_nextmonth(dt_now()) — при помощи функции «сейчас»
dt_nextmonth(dt_now_tz()) — при помощи функции «сейчас с учётом часового пояса бота»
Например: получив 22.01.2022 22:22:22 вернет 01.02.2022 00:00:00.

dt_now_tz()

dt_now_tz()
Функция — аналог dt_now(), но формирует время «сейчас», с учетом настроенного в боте часового пояса (_tz — Time Zone). 

Используйте данную функцию только для отображения времени и тому подобных вещей. Не рекомендуем использовать время локальных Часовых Поясов для хранения или учёта каких либо данных. С функциями типа: dt_left(), dt_passed() — данная функция будет работать НЕПРАВИЛЬНО. 

Дополнительная Информация

Дату и Время можно записывать в Переменные

О том что такое переменные и как с ними работать.

• • •

Функции и Переменные с Дата/Время можно использовать в Выражениях

О том как применять Выражения, читай в руководстве по Выражениям.

• • •

Функции и Переменные с Дата/Время можно использовать в Условиях

О том как применять Условия, читай в руководстве по Условиям.

• • •

Дату и Время можно использовать в Action-ах

Подробнее о том что такое Action-ы, чем они удобны и как ими пользоваться смотрите в отдельном Руководстве по Action-ам.

PHP-функция date() преобразует метку времени в более удобочитаемые дату и время.

Компьютер хранит дату и время в формате, который называется UNIX Timestamp; он измеряет время как количество секунд с начала эпохи Unix (полночь по Гринвичу 1 января 1970 г., т.е. 1 января 1970 г., 00:00:00 по Гринвичу). ,

Поскольку это непрактичный формат для чтения людьми, PHP преобразует временную метку в формат, понятный людям, и даты из вашей записи в метку времени, понятную компьютеру. Синтаксис PHP-функции date() можно задать с помощью.

date(format, timestamp)

Параметр формата в функции date() является обязательным, который определяет формат возвращаемых даты и времени. Однако метка времени (timestamp) является необязательным параметром; если она не указана, будут использоваться текущая дата и время. Следующая инструкция отображает сегодняшнюю дату:

<?php
$today = date("d/m/Y");
echo $today;
?>

PHP-функция date() возвращает текущую дату и время в соответствии со встроенными часами веб-сервера, на котором был выполнен скрипт.

Форматирование даты и времени с помощью PHP-функции date()

Параметр формата функции date() на самом деле представляет собой строку, которая может содержать несколько символов, что позволяет вам сгенерировать строку даты, содержащую различные компоненты даты и времени, такие как день недели, AM или PM и т. д. Вот некоторые из символов форматирования, связанные с датой, которые обычно используются в этой строке:

  • d — обозначает день месяца; две цифры с ведущими нулями (01 или 31)
  • D — обозначение дня недели в тексте в виде сокращения (с понедельника по воскресенье)
  • m — обозначает месяц цифрами с ведущими нулями (01 или 12)
  • M — обозначает месяц в тексте, сокращенно (с января по декабрь)
  • y — обозначают год двумя цифрами (08 или 14)
  • Y — обозначает год четырьмя цифрами (2008 или 2014)

Части даты можно разделить, вставив другие символы, например дефисы (-), точки (.), слеши (/) или пробелы, чтобы добавить дополнительное визуальное форматирование.

<?php
echo date("d/m/Y") . "<br>";
echo date("d-m-Y") . "<br>";
echo date("d.m.Y");
?>

Вы можете использовать PHP-функцию date() для автоматического обновления срока действия авторских прав на вашем веб-сайте, например: Copyright &copy; 2010-<?php echo date("Y")?>.

Точно так же вы можете использовать следующие символы для форматирования строки времени:

  • h — обозначает час в 12-часовом формате с ведущими нулями (от 01 до 12)
  • H — часы в 24-часовом формате с ведущими нулями (от 00 до 23)
  • i — минуты с ведущими нулями (от 00 до 59)
  • s — секунды с ведущими нулями (от 00 до 59)
  • a — представляют нижний регистр ante meridiem и post meridiem (am или pm)
  • A — обозначает верхний регистр Ante meridiem и Post meridiem (AM или PM)

PHP-код в следующем примере отображает дату в разных форматах:

<?php
echo date("h:i:s") . "<br>";
echo date("F d, Y h:i:s A") . "<br>";
echo date("h:i a");
?>

PHP-функция time()

Функция time() используется для получения текущего времени в виде метки времени Unix (количество секунд с начала эпохи Unix: 1 января 1970 г. 00:00:00 по Гринвичу).

<?php
// Текущая дата 05 March 2014, 07:19:18
$timestamp = time();
echo($timestamp); // Выводит: 1394003958
?>

Мы можем преобразовать эту метку времени в удобочитаемую дату, передав ее в ранее введенную функцию date().

<?php
$timestamp = 1394003958;
echo(date("F d, Y h:i:s", $timestamp)); // Выводит: March 05, 2014 07:19:18
?>

PHP-функция mktime()

Функция mktime() используется для создания отметки времени на основе определенной даты и времени. Если дата и время не указаны, возвращается метка времени для текущей даты и времени.

Синтаксис функции mktime() может быть задан следующим образом:

mktime(hour, minute, second, month, day, year)

В следующем примере отображается метка времени, соответствующая 15:20:12 10 мая 2014 года:

<?php
// Создаем метку времени для определенной даты
echo mktime(15, 20, 12, 5, 10, 2014); // Выводит: 1399735212
?>

Вы можете не указывать столько аргументов, вместо них будет использоваться значение, соответствующее текущему времени. Если вы опустите все аргументы, функция mktime() вернет временную метку UNIX, соответствующую текущей дате и времени, как и time().

Функцию mktime() можно использовать для поиска названия дня недели, соответствующего определенной дате. Для этого просто используйте символ «l» (строчная буква «L») со своей меткой времени, как в следующем примере, который отображает день, приходящийся на 1 апреля 2014 года:

<?php
// Получаем название дня недели определенной даты
echo date('l', mktime(0, 0, 0, 4, 1, 2014)); // Выводит: Tuesday
?>

Функцию mktime() также можно использовать для поиска определенной даты в будущем по истечении определенного периода времени. Как в следующем примере, где отображается дата, которая наступает спустя 30 месяцев относительно 5 Марта 2014.

<?php
// Текущая дата March 05, 2014
$futureDate = mktime(0, 0, 0, date("m")+30, date("d"), date("Y"));
echo date("d/m/Y", $futureDate); // Выводит: 05/09/2016
?>

Пожалуйста, ознакомьтесь с разделом справки по функциям даты и времени PHP, чтобы получить полный список всех полезных функций даты и времени доступных в PHP.

Похожие посты

  • 22 декабря, 2019
  • 178

В этом руководстве мы узнаем, как загружать файлы на удаленный сервер с помощью простой HTML-формы и PHP. Вы можете загружать файлы любого типа, например изображения, видео, ZIP-файлы, документы Microsoft Office, PDF-файлы, а также исполняемые файлы и множество других типов файлов. Шаг 1. Создание HTML-формы для загрузки файла В следующем примере будет создана простая HTML-форма, которую…

  • 18 декабря, 2019
  • 960

Веб-браузер связывается с сервером, как правило, с помощью одного из двух HTTP-методов (протокола передачи гипертекста) — GET и POST. Оба метода передают информацию по-разному и имеют разные преимущества и недостатки, как описано ниже. PHP-метод GET В методе GET данные отправляются в виде параметров URL, которые обычно представляют собой строки пар имени и значения, разделенные амперсандами…

  • 16 декабря, 2019
  • 78

Обычно, когда движок PHP сталкивается с проблемой, препятствующей правильной работе скрипта, он генерирует сообщение об ошибке. Существует шестнадцать различных уровней ошибок, и каждый уровень представлен целым числом и связанной с ним константой. Вот список уровней ошибок: Название Значение Описание E_ERROR 1 Неустранимая ошибка времени выполнения от которой невозможно избавиться. Выполнение скрипта немедленно прекращается E_WARNING 2…

Работа с датами может быть сложной . Независимо от технологии, разработчики чувствуют боль.

JavaScript предоставляет нам функциональность обработки даты при помощи мощного встроенного объекта: Date.

В этой статье не говорится о Moment.js , который, я считаю, является лучшей библиотекой для обработки дат, и вы почти всегда должны использовать ее при работе с датами.

Объект Date

Экземпляр объекта Date представляет текущий момент времени. Несмотря на имя Date, он также обрабатывает время.

Инициализируйте объект Date

Мы инициализируем объект Date с помощью конструкции:

new Date()

Это создает объект Date, указывающий на текущий момент времени.

Внутренне даты выражаются в миллисекундах с 1 января 1970 года (UTC).

Возможно, вы знакомы с отметкой времени UNIX: она представляет количество секунд , прошедших с этой известной даты.

Временные метки UNIX указываются в секундах а JavaScript объект Date работает с миллисекундами, это важно помнить работая с timestamp

Если у нас есть отметка времени UNIX, мы можем создать экземпляр объекта Date с помощью:

const timestamp = 1530826365
new Date(timestamp * 1000)

Если мы передадим 0, мы получим объект Date, который представляет время на 1 января 1970 года (UTC):

new Date(0)

Если мы передаем строку, а не число, тогда объект Date использует метод parse, чтобы определить, какую дату вы передаете. Примеры:

new Date('2018-07-22')
new Date('2018-07') //July 1st 2018, 00:00:00
new Date('2018') //Jan 1st 2018, 00:00:00
new Date('07/22/2018')
new Date('2018/07/22')
new Date('2018/7/22')
new Date('July 22, 2018')
new Date('July 22, 2018 07:22:13')
new Date('2018-07-22 07:22:13')
new Date('2018-07-22T07:22:13')
new Date('25 March 2018')
new Date('25 Mar 2018')
new Date('25 March, 2018')
new Date('March 25, 2018')
new Date('March 25 2018')
new Date('March 2018') //Mar 1st 2018, 00:00:00
new Date('2018 March') //Mar 1st 2018, 00:00:00
new Date('2018 MARCH') //Mar 1st 2018, 00:00:00
new Date('2018 march') //Mar 1st 2018, 00:00:00

Здесь много гибкости. Вы можете добавить или опустить ведущий ноль в месяцах или днях.

Будьте осторожны с позицией месяц / деня, иначе вы можете ошибочно истолковать месяц как день.

Вы также можете использовать Date.parse:

Date.parse('2018-07-22')
Date.parse('2018-07') //July 1st 2018, 00:00:00
Date.parse('2018') //Jan 1st 2018, 00:00:00
Date.parse('07/22/2018')
Date.parse('2018/07/22')
Date.parse('2018/7/22')
Date.parse('July 22, 2018')
Date.parse('July 22, 2018 07:22:13')
Date.parse('2018-07-22 07:22:13')
Date.parse('2018-07-22T07:22:13')

Date.parse вернет метку времени (в миллисекундах), а не объект Date.

Вы также можете передать набор упорядоченных значений, которые представляют каждую часть даты: год, месяц (начиная с 0), день, час, минуты, секунды и миллисекунды:

new Date(2018, 6, 22, 7, 22, 13, 0)
new Date(2018, 6, 22)

Минимум должен быть 3 параметра, но большинство движков JavaScript также интерпретируют меньшее их число:

new Date(2018, 6) //Sun Jul 01 2018 00:00:00 GMT+0200 (Central European Summer Time)
new Date(2018) //Thu Jan 01 1970 01:00:02 GMT+0100 (Central European Standard Time)

В любом из этих случаев полученная дата относится к часовому поясу вашего компьютера. Это означает, что два разных компьютера могут выводить разные значения для одного и того же объекта даты.

JavaScript, без какой-либо информации о часовом поясе, будет считать дату UTC и автоматически выполнит преобразование в текущий часовой пояс компьютера.

Итак, суммируя, вы можете создать новый объект Date четырьмя способами

  • не передавая никаких параметров, создает объект Date, который представляет текущую дату и время
  • передача числа, которое представляет миллисекунды с 1 января 1970 года
  • передавая строку, которая представляет дату
  • передавая набор параметров, которые представляют различные части даты

Часовые пояса

При инициализации даты вы можете передать часовой пояс, поэтому дата не будет считается UTC, а затем конвертироваться в ваш местный часовой пояс.

Вы можете указать часовой пояс, добавив его в формате +HOURS или добавив имя часового пояса в скобках:

new Date('July 22, 2018 07:22:13 +0700')
new Date('July 22, 2018 07:22:13 (CET)')

Если вы укажете неправильное имя часового пояса в скобках, JavaScript по умолчанию будет считать дату UTC без вывода ошибки.

Если вы укажете неправильный числовой формат, JavaScript будет выдавать сообщение об ошибке «Invalid Date».

Преобразование даты и форматирование

Для данного объекта Date существует множество методов, которые сгенерируют строку с этой датой:

const date = new Date('July 22, 2018 07:22:13')

date.toString() // "Sun Jul 22 2018 07:22:13 GMT+0200 (Central European Summer Time)"
date.toTimeString() //"07:22:13 GMT+0200 (Central European Summer Time)"
date.toUTCString() //"Sun, 22 Jul 2018 05:22:13 GMT"
date.toDateString() //"Sun Jul 22 2018"
date.toISOString() //"2018-07-22T05:22:13.000Z" (ISO 8601 format)
date.toLocaleString() //"22/07/2018, 07:22:13"
date.toLocaleTimeString() //"07:22:13"
date.getTime() //1532236933000
date.getTime() //1532236933000

Методы получения объекта Date

Объект Date предлагает несколько методов для проверки его значения. Все это зависит от текущего часового пояса компьютера:

const date = new Date('July 22, 2018 07:22:13')

date.getDate() //22
date.getDay() //0 (0 means sunday, 1 means monday..)
date.getFullYear() //2018
date.getMonth() //6 (starts from 0)
date.getHours() //7
date.getMinutes() //22
date.getSeconds() //13
date.getMilliseconds() //0 (not specified)
date.getTime() //1532236933000
date.getTimezoneOffset() //-120 (will vary depending on where you are and when you check - this is CET during the summer). Returns the timezone difference expressed in minutes

Существуют эквивалентные версии этих методов в формате UTC, которые возвращают значение UTC, а не значения, адаптированные к вашему текущему часовому поясу:

date.getUTCDate() //22
date.getUTCDay() //0 (0 means sunday, 1 means monday..)
date.getUTCFullYear() //2018
date.getUTCMonth() //6 (starts from 0)
date.getUTCHours() //5 (not 7 like above)
date.getUTCMinutes() //22
date.getUTCSeconds() //13
date.getUTCMilliseconds() //0 (not specified)

Редактирование даты

Объект Date предлагает несколько методов для редактирования значения даты:

const date = new Date('July 22, 2018 07:22:13')

date.setDate(newValue)
date.setDay(newValue)
date.setFullYear(newValue) //note: avoid setYear(), it's deprecated
date.setMonth(newValue)
date.setHours(newValue)
date.setMinutes(newValue)
date.setSeconds(newValue)
date.setMilliseconds(newValue)
date.setTime(newValue)
date.setTimezoneOffset(newValue)

setDay и setMonth принимают нумерацию с 0, например, март месяц имеет индекс 2.

Забавный факт: эти методы «пересекаются», поэтому, если вы, например, установите date.setHours(48), он также будет увеличивать день.

Полезно знать: вы можете добавить более одного параметра, чтобы setHours() также установил минуты, секунды и миллисекунды: setHours(0, 0, 0, 0) — то же самое относится к методам setMinutes и setSeconds.

Методы set также имеют эквивалент UTC:

const date = new Date('July 22, 2018 07:22:13')

date.setUTCDate(newValue)
date.setUTCDay(newValue)
date.setUTCFullYear(newValue)
date.setUTCMonth(newValue)
date.setUTCHours(newValue)
date.setUTCMinutes(newValue)
date.setUTCSeconds(newValue)
date.setUTCMilliseconds(newValue)

Получить текущую метку времени

Если вы хотите получить текущую метку времени в миллисекундах, вы можете использовать сокращение

Date.now()

вместо

new Date().getTime()

JavaScript старается работать без ошибок

Обращать внимание. Если вы передадите большее количеством дней в месяце, ошибок не будет, и дата перейдет к следующему месяцу:

new Date(2018, 6, 40) //Thu Aug 09 2018 00:00:00 GMT+0200 (Central European Summer Time)

То же самое касается месяцев, часов, минут, секунд и миллисекунд.

Формат даты в соответствии с локалью

Internationalization API, хорошо поддерживается в современных браузерах (заметное исключение: UC Browser), позволяя переводить даты.

Он предоставляет объектом Intl, который также помогает локализовать числа, строки и валюты.

Мы будем использовать для преобразования даты метод Intl.DateTimeFormat().

Отформатируйте дату в соответствии с локалью компьютера по умолчанию:

// "12/22/2017"
const date = new Date('July 22, 2018 07:22:13')
new Intl.DateTimeFormat().format(date) //"22/07/2018" in my locale

Отформатируйте дату в соответствии с другим языком:

new Intl.DateTimeFormat('en-US').format(date) //"7/22/2018"

Метод Intl.DateTimeFormat принимает необязательный параметр, который позволяет настроить вывод. Чтобы также отображать часы, минуты и секунды:

const options = {
 year: 'numeric',
 month: 'numeric',
 day: 'numeric',
 hour: 'numeric',
 minute: 'numeric',
 second: 'numeric'
}

new Intl.DateTimeFormat('en-US', options).format(date) 
//"7/22/2018, 7:22:13 AM"

new Intl.DateTimeFormat('it-IT', options2).format(date) 
//"22/7/2018, 07:22:13"

Сравнение двух дат

Вы можете рассчитать разницу между двумя датами, используя Date.getTime():

const date1 = new Date('July 10, 2018 07:22:13')
const date2 = new Date('July 22, 2018 07:22:13')
const diff = date2.getTime() - date1.getTime() //difference in milliseconds

Таким же образом вы можете проверить, равны ли две даты:

const date1 = new Date('July 10, 2018 07:22:13')
const date2 = new Date('July 10, 2018 07:22:13')
if (date2.getTime() === date1.getTime()) {
 //dates are equal
}

Имейте в виду, что метод getTime() возвращает количество миллисекунд, поэтому при сравнении необходимо учитывать время. July 10, 2018 07:22:13 не равно July 10, 2018. В этом случае вы можете использовать метод setHours(0, 0, 0, 0) для сброса времени.

Вступайте в мою группу помощник программиста.
В ней мы обсуждаем программирование в 1С.

2021-02-24T11:02:56+00:00 Дата Если Массивы Математика Процедуры Строки Циклы
Диалоги ОписаниеТипов ОперационнаяСистема Приложение Соответствие
СписокЗначений Структура ТаблицаЗначений ФайловаяСистема Формат

ОбщиеОбъекты Запросы ПрикладныеОбъекты УниверсальныеФункции

См. урок для начинающих по работе с датами в 1С
Скачать эти примеры в виде тестовой базы (как загрузить, как исследовать)
Смотреть видео с демонстрацией выполнения кода

Полный синтаксис (нажмите, чтобы раскрыть)

Оглавление (нажмите, чтобы раскрыть)

&НаКлиенте
Процедура ВыполнитьКод(Команда)
 
    /// Как инициализировать дату константой в 1с 8.3, 8.2
 
    МояДата = '20130724'; // 24.07.2013
 
    /// Как преобразовать строку в дату в 1с 8.3, 8.2
 
    МояДата = Дата("20130724"); // 24.07.2013
 
    /// Как инициализировать дату отдельными компонентами в 1с 8.3, 8.2
 
    МояДата = Дата(2013, 07, 24); // 24.07.2013
 
    /// Как указать в дате часы, минуты и секунды в 1с 8.3, 8.2
 
    МояДата = '20130724132506'; // 24 июля 2013 г. 13 ч. 25 мин. 6 сек.
 
    /// Как узнать год (месяц, день, час, минута, секунда) у
    /// даты в 1с 8.3, 8.2
 
    Г =  Год(МояДата); // 2013
    М =  Месяц(МояДата); // 7
    Д =  День(МояДата); // 24
    Ч =  Час(МояДата); // 13
    Ми = Минута(МояДата); // 25
    С =  Секунда(МояДата); // 6
 
    /// Как получить текущую дату в 1с 8.3, 8.2
 
    Сообщить(ТекущаяДата());
 
    /// Операции с датой в 1с 8.3, 8.2
 
    Сообщить(ТекущаяДата() + 1); // прибавили секунду
 
    Сообщить(ДобавитьМесяц(ТекущаяДата(), 1)); // прибавили месяц
    Сообщить(ДобавитьМесяц(ТекущаяДата(), -1)); // отняли месяц
 
    /// Вспомогательные функции для работы с датой в 1с 8.3, 8.2
 
    МояДата = '20130110125905'; // 10 января 2013 года 12:59:05
 
    Сообщить(ДеньГода(МояДата)); // 10
 
    Сообщить(ДеньНедели(МояДата)); // 4 т.е. четверг (нумерация с понедельника)
 
    Сообщить(НеделяГода(МояДата)); // 2
 
    Сообщить(НачалоГода(МояДата)); // 01.01.2013 0:00:00
    Сообщить(КонецГода(МояДата)); // 31.12.2013 23:59:59
 
    Сообщить(НачалоКвартала(МояДата)); // 01.01.2013 0:00:00
    Сообщить(КонецКвартала(МояДата)); // 31.03.2013 23:59:59
 
    Сообщить(НачалоМесяца(МояДата)); // 01.01.2013 0:00:00
    Сообщить(КонецМесяца(МояДата)); // 31.01.2013 23:59:59
 
    Сообщить(НачалоНедели(МояДата)); // 07.01.2013 0:00:00
    Сообщить(КонецНедели(МояДата)); // 13.01.2013 23:59:59
 
    Сообщить(НачалоДня(МояДата)); // 10.01.2013 0:00:00
    Сообщить(КонецДня(МояДата)); // 10.01.2013 23:59:59
 
    Сообщить(НачалоЧаса(МояДата)); // 10.01.2013 12:00:00
    Сообщить(КонецЧаса(МояДата)); // 10.01.2013 12:59:59
 
    Сообщить(НачалоМинуты(МояДата)); // 10.01.2013 12:59:00
    Сообщить(КонецМинуты(МояДата)); // 10.01.2013 12:59:59 
 
КонецПроцедуры
 
/// Скачать и выполнить эти примеры на компьютере

Скачать эти примеры в виде тестовой базы (как загрузить, как исследовать)

Работа с типом Дата в языке 1С 8.3, 8.2 (в примерах)

Дата Если Массивы Математика Процедуры Строки Циклы
Диалоги ОписаниеТипов ОперационнаяСистема Приложение Соответствие
СписокЗначений Структура ТаблицаЗначений ФайловаяСистема Формат

ОбщиеОбъекты Запросы ПрикладныеОбъекты УниверсальныеФункции

С уважением, Владимир Милькин (преподаватель школы 1С программистов и разработчик обновлятора).

Владимир Милькин

Как помочь сайту: расскажите (кнопки поделиться ниже) о нём своим друзьям и коллегам. Сделайте это один раз и вы внесете существенный вклад в развитие сайта. На сайте нет рекламы, но чем больше людей им пользуются, тем больше сил у меня для его поддержки.

Нажмите одну из кнопок, чтобы поделиться:

Excel для Microsoft 365 Excel для Microsoft 365 для Mac Excel для Интернета Excel 2021 Excel 2021 для Mac Excel 2019 Excel 2019 для Mac Excel 2016 Excel 2016 для Mac Excel 2013 Excel 2010 Excel 2007 Excel для Mac 2011 Excel Starter 2010 Еще…Меньше

Чтобы просмотреть более подробные сведения о функции, щелкните ее название в первом столбце.

Примечание: Маркер версии обозначает версию Excel, в которой она впервые появилась. В более ранних версиях эта функция отсутствует. Например, маркер версии 2013 означает, что данная функция доступна в выпуске Excel 2013 и всех последующих версиях.

Функция

Описание

ДАТА

Возвращает заданную дату в числовом формате.

РАЗНДАТ

Вычисляет количество дней, месяцев или лет между двумя датами. Эта функция полезна в формулах расчета возраста.

ДАТАЗНАЧ

Преобразует дату из текстового формата в числовой.

ДЕНЬ

Преобразует дату в числовом формате в день месяца.

ДНИ

Excel 2013

Возвращает количество дней между двумя датами.

ДНЕЙ360

Вычисляет количество дней между двумя датами на основе 360-дневного года.

ДАТАМЕС

Возвращает дату в числовом формате, отстоящую на заданное число месяцев вперед или назад от начальной даты.

КОНМЕСЯЦА

Возвращает дату в числовом формате для последнего дня месяца, отстоящего вперед или назад на заданное число месяцев.

ЧАС

Преобразует дату в числовом формате в часы.

НОМНЕДЕЛИ.ISO

Excel 2013

Возвращает номер недели по ISO для заданной даты.

МИНУТЫ

Преобразует дату в числовом формате в минуты.

МЕСЯЦ

Преобразует дату в числовом формате в месяцы.

ЧИСТРАБДНИ

Возвращает количество полных рабочих дней между двумя датами.

ЧИСТРАБДНИ.МЕЖД

Excel 2010

Возвращает количество полных рабочих дней в интервале между двумя датами, руководствуясь параметрами, указывающими выходные дни и их количество.

ТДАТА

Возвращает текущую дату и время в числовом формате.

СЕКУНДЫ

Преобразует дату в числовом формате в секунды.

ВРЕМЯ

Возвращает заданное время в числовом формате.

ВРЕМЗНАЧ

Преобразует время из текстового формата в числовой.

СЕГОДНЯ

Возвращает текущую дату в числовом формате.

ДЕНЬНЕД

Преобразует дату в числовом формате в день недели.

НОМНЕДЕЛИ

Преобразует дату в числовом формате в число, которое указывает, на какую неделю года приходится дата.

РАБДЕНЬ

Возвращает дату в числовом формате, отстоящую вперед или назад на заданное количество рабочих дней.

РАБДЕНЬ.МЕЖД

Excel 2010

Возвращает числовое значение даты, предшествующей заданному количеству рабочих дней или следующей за ними, руководствуясь при этом параметрами, указывающими выходные дни и их количество.

ГОД

Преобразует дату в числовом формате в год.

ДОЛЯГОДА

Возвращает долю года, которую составляет количество дней между начальной и конечной датами.

Важно: Вычисляемые результаты формул и некоторые функции листа Excel могут несколько отличаться на компьютерах под управлением Windows с архитектурой x86 или x86-64 и компьютерах под управлением Windows RT с архитектурой ARM. Подробнее об этих различиях.

Нужна дополнительная помощь?

ГОСТ Р 7.0.97-2016 описывает правила оформления даты документа предельно лаконично. Поэтому нам есть что добавить!
Ставить 0 в начале даты? Можно использовать кавычки? «Длящаяся» дата протокола. Дата совместного документа. Специфика госорганов. Дата подписания электронного документа. Дата доверенности. Дата на обложке дела и на титульном листе ЛНА. В каких реквизитах и как лучше оформлять дату.

Подробно остановились на оформлении дат в тексте документа в различных ситуациях. Статья содержит 25 примеров.

Датой документа является дата:

  • его подписания (распорядительные документы, письма) или
  • события, зафиксированного в документе (протокол, акт);
  • для утверждаемого документа (план, инструкция, положение, отчет) – дата утверждения1.

Для ряда официальных документов существует также дата их опуб­ликования и дата вступления в силу. Кроме того, дата как элемент присутствует в составе разных реквизитов документа.

Какие правила стандартизированы?

В настоящее время действует несколько документов, в которых регламентированы способы проставления даты.

Обратите внимание, что применение ранее действующего ГОСТ ИСО 8601-2001 «Система стандартов по информации, библиотечному и издательскому делу. Представление дат и времени. Общие требования» на территории Российской Федерации прекращено с 01.01.2022 без замены на новый аналогичный документ (приказ Росстандарта от 27.12.2021 № 1857-ст).

В действующем ГОСТ об оформлении организационно-распоряди-тельных документов про интересующий нас реквизит сказано немного:

Фрагмент документа

ГОСТ Р 7.0.97-2016 «Система стандартов по информации, библиотечному и издательскому делу. Организационно-распорядительная документация. Требования к оформлению документов»

5.10. Дата документа соответствует дате подписания (утверждения) документа или дате события, зафиксированного в документе. Документы, изданные двумя или более организациями, должны иметь одну (единую) дату.

Дата документа записывается в последовательности – день месяца, месяц, год – одним из двух способов:

арабскими цифрами, разделенными точкой: 05.06.2016;

словесно-цифровым способом, например: 5 июня 2016 г.

Что мы видим в этом стандарте?

При цифровом способе оформления даты ее элементы приводятся одной строкой арабскими цифрами, отделенными точками:

  • 2 цифры для обозначения числа;
  • 2 цифры – для месяца;
  • 4 цифры – для года, после которого не ставится сокращение «г.»

Пример: 01.09.2022 или 21.02.2022.

Если же дата оформляется словесно-цифровым способом, то ГОСТ Р 7.0.97-2016 предписывает:

  • после 4 цифр года ставить сокращение «г.»;
  • если дата состоит из 1 цифры, то 0 перед ней не ставить.

Пример: 1 сентября 2022 г.

Обратите внимание, что между цифрами года и сокращениями «г.» или «гг.» должен быть пробел: 2022 г., 2020–2022 гг.

Дата документа оформляется без кавычек.

Но какой способ оформления даты будет применяться при оформлении того или иного реквизита в определенном виде документа, будет зависеть от правил, указанных в конкретных локальных нормативных актах (ЛНА) организации по оформлению документов (инструкциях, регламентах и др.). Он может отличаться от указанных в рассмотренном выше ГОСТ Р 7.0.97-2016. Применение данного стандарта носит добровольный характер для организаций различных форм собственности, за исключением государственных органов и органов местного самоуправления.

В соответствии с приказом Росархива от 22.05.2019 № 71 «Об утверждении Правил делопроизводства в государственных органах, органах местного самоуправления» данный стандарт носит обязательный характер для этих органов, поэтому они обязаны четко применять правила оформления даты, указанные в ГОСТ Р 7.0.97-2016. Остальным организациям при оформлении даты в документах желательно все-таки придерживаться Методических рекомендаций по применению ГОСТ Р 7.0.97-2016, разработанных Росархивом в 2018 году, и закрепить особенности оформления даты в ЛНА.

Поэтому далее поговорим про особенности оформления даты различными организациями в различных реквизитах и ситуациях.

Нужен 0 в начале даты?

ГОСТ Р 7.0.97-2016 (п. 5.10) в примере показывает нам, что при словесно-цифровом способе число месяца внутри даты должно быть обозначено 1-й цифрой от 1 до 9: 5 июня 2016 г.

В предыдущем ГОСТ Р 6.30-2003 (п. 3.11) в этой же ситуации 0 присутствовал: 05 июня 2003 г. Такого числа дня месяца, как 05 или 01 не существует, поэтому в новом стандарте «0» был исключен.

Однако его наличие усложняет фальсификацию даты, например 1 декабря 2021 г. достаточно легко превратить в 11 декабря и в 21, и в 31 декабря того же года, подставив в начале всего одну новую цифру. Если бы перед 1 стоял 0, то такую подмену сделать было бы сложнее. А дата издания документа или иного действия либо события, указанного в тексте, порой может сыграть существенную роль. Поэтому некоторые организации в своих ЛНА закрепили старое правило, согласно которому число в дне месяца всегда должно быть двузначным.

Кавычки в дате?

ГОСТ Р 7.0.97-2016 предусматривает оформление даты только без кавычек. Однако некоторые организации используют в бланках документов ограничительные отметки для даты, обозначая кавычками место заполнения числа месяца, таким образом давая понять, что в бланке применяется словесно-цифровой способ оформления даты. Это допустимо, если ваша организация не придерживается правил ГОСТ Р 7.0.97-2016.

Пример 1. Способ указания даты с кавычками в бланке

Какой способ оформления кавычек выбрать («ёлочки» или “лапки”), также решает организация. Однако существует понятие «полиграфических» кавычек: в печатном тексте (в газете, журнале или книге) кавычки всегда должны иметь вид скобок: «». Это же правило перешло в официально-деловой стиль, поэтому рекомендуется придерживаться его при оформлении даты в бланке документа.

В Примерах 2 и 3 показаны правила проставления даты в бланке документа при угловом и продольном расположении реквизитов. Дата всегда располагается слева, а регистрационный номер справа, т.к. сначала документ датируется, а затем уже регистрируется.

Пример 2. Бланк письма

Пример 3. Бланк приказа

В каких реквизитах указывается дата

По правилам делопроизводства все служебные отметки на документе, связанные с его прохождением и исполнением, должны датироваться: согласование, подписание, утверждение, отметка о заверении копии, отметка о поступлении документа в организацию и др. Теоретически в них можно использовать как цифровой способ написания даты, так и словесно-цифровой, но первый применяется чаще в связи с внедрением электронного документооборота, т.к. он является кодом для автоматизированной обработки документа. При этом словесно-цифровой способ предпочтительнее использовать при оформлении финансовых документов, доверенностей, т.к. он практически сводит к минимуму риски подделки даты документа.

Пример 4. Гриф согласования

Пример 5. Виза внутреннего согласования

Пример 6. Резолюция

Пример 7. Гриф утверждения

Пример 8. Отметка о заверении копии

Пример 9. Отметка об исполнении документа

Период события в протоколе и акте

Некоторые мероприятия или события длятся некоторый период времени (например, совещания, заседания, различного рода проверки). Поэтому в таких документах, как акт или протокол, дата документа будет фиксировать весь период события.

Датой протокола является дата проведения протоколируемого мероприятия. Если оно продолжается несколько дней, то через тире указывают даты начала и окончания: 27–28 января 2022 г. или 27–28.01.2022.

Тире (–) длиннее дефиса (-), использовать надо именно тире. Чтобы напечатать его, одновременно нажимают «Alt» внизу клавиатуры слева и «-» вверху справа.

Дата совместного документа

Документы, изданные двумя или более организациями, должны иметь одну (единую) дату. Если авторами документа являются несколько организаций, то датой документа становится наиболее поздняя дата подписания. Эта дата проставляется в бланк документа рядом с регистрационным номером.

Пример 10. Заголовочная часть совместного документа

А номер будет составным из номеров, присвоенных авторами документов, каждый вписывается в порядке указания авторов в заголовочной части документа через косую черту.

Особенности для госорганов

О том, что для госорганов и органов местного самоуправления ГОСТ Р 7.0.97-2016 является обязательным, мы уже сказали (в силу приказа Росархива от 22.05.2019 № 71 «Об утверждении Правил делопроизводства в государственных органах, органах местного самоуправления»).

В 2018 году Росархивом еще была разработана Примерная инструкция по делопроизводству в государственных организациях, требования к оформлению даты в которой аналогичны ГОСТ Р 7.0.97-2016.

Некоторые особенности имеют способы оформления даты в федеральных законах и федеральных конституционных законах, а также в указах и распоряжениях Президента Российской Федерации. В утвержденных приказом Росархива от 24.12.2020 № 199 Методических рекомендациях по разработке инструкций по делопроизводству в государственных органах и органах местного самоуправления указано, что при оформлении проектов указов и распоряжений Президента Российской Федерации дата проставляется ниже реквизита подпись словесно-цифровым способом. В данных документах после указания года слово «года» пишется полностью: 22 апреля 2020 года или 3 сентября 2020 года.

Пример 11. Указ Президента России

Датой принятия федерального закона считается день принятия его Государственной Думой в окончательной редакции. Она оформляется в заголовочной части документа словесно-цифровым способом, так же как в указах и распоряжениях Президента Российской Федерации (см. Пример 12).

В постановлениях Правительства Российской Федерации дата оформляется словесно-цифровым способом в заголовочной части, но слово «года» в конце пишется сокращенно «г.»: 27 февраля 2021 г. (см. Пример 13).

При ссылке в тексте документа на ранее изданный документ его дата обычно указывается цифровым способом, например: «на основании пункта 2 статьи 11 Федерального закона от 06.04.2011 № 63-ФЗ “Об электронной подписи”».

Пример 12. Федеральный закон РФ

Пример 13. Постановление Правительства РФ

Дата подписания электронного документа

При бумажном делопроизводстве дата документа проставляется:

  • должностным лицом, подписывающим / утверждающим документ, либо
  • службой делопроизводства при регистрации документа (после подписания).

Дата подписания электронного документа фиксируется информаци-онной системой. Она имеет значение лишь для подтверждения действительности сертификата электронной подписи на момент подписания (п. 2 ст. 11 Федерального закона от 06.04.2011 № 63-ФЗ «Об электронной подписи»).

Внедрение электронных документов в бухгалтерском учете влечет за собой разделение понятий «дата приема» в акте и «дата формирования подписи». В первичных учетных документах дата подписания документа может отличаться от даты фактического приема работ / услуг. Например, при общей системе налогообложения расходы в налоговом учете при методе начисления принимаются по дате приема работ / услуг, если договором не предусмотрено иное (согласно ст. 272 НК РФ). Дата формирования электронной подписи не определяет свершение события хозяйственной деятельности (за исключением случаев, когда иное прописано в договоре или утверждено в учетной политике организации). В рассматриваемой ситуации услуги необходимо относить к тому периоду, который зафиксирован в дате приема услуг, указанной в первичном учетном документе.

Дата совершения доверенности

Дату оформления доверенности предпочтительнее зафиксировать буквенным вариантом написания – это когда цифры в дате не используются совсем. Это заимствовано из нотариальной практики. Оформление даты прописью существенно усложняет внесение в нее изменений и повышает защиту доверенности от фальсификации.

Пример 14. Доверенность

Обложка дела и титульный лист ЛНА

Слово «год» опускается при его цифровом обозначении внизу титульного листа ЛНА (см. «2» в Примере 15). Если фигурируют другие даты – обычно в реквизитах утверждающего документа, то их можно писать цифровым или словесно-цифровым способом (см. «1» в Примере 15).

Пример 15. Титульный лист ЛНА

Пример 16. Обложка дела

На обложке дела при передаче его в архив дата указывается словесно-цифровым способом: сначала число, затем месяц и год; число и год обозначаются арабскими цифрами, название месяца – словом; слово «года» пишется полностью (см. Методические рекомендации по применению Правил организации хранения, комплектования, учета и использования документов Архивного фонда Российской Федерации и других архивных документов в государственных органах, органах местного самоуправления и организациях, 2018). См. Пример 16.

При заполнении строки «Крайние даты» на обложке дела указываются даты (год(ы)) заведения и окончания дела в делопроизводстве: 5 февраля 2020 года – 15 декабря 2020 года.

Выходные данные библиографического описания

Слово «год» опускается в выходных данных библиографического описания (согласно ГОСТ Р 7.0.100-2018 «СИБИД. Библиографическая запись. Библиографическое описание. Общие требования и правила составления»).

Пример 17. Описание книги в сноске

Даты в тексте

Правила написания дат в текстах документов отличаются от их написания в других реквизитах. Рассмотрим на конкретных примерах.

Если обозначение даты в тексте состоит только из года, слово «год» пишется полностью:

Пример 18. В тексте только год

Просим ознакомиться с производственным календарем на 2022 год, в котором содержится информация о количестве рабочих, выходных и праздничных дней, норме рабочего времени в 2022 году.

Номер квартала указывается римской цифрой (Пример 19), полугодие пишется словом полностью, а год рядом арабскими цифрами (Пример 20).

Пример 19. В тексте указываем квартал года

В I квартале 2021 г. внешнеторговый оборот России составил, по данным Банка России, 155,9 млрд долларов США.

Пример 20. В тексте указываем полугодие

В соответствии с приказом Росстандарта от 11.11.2021 № 2533 «Об утверждении температурных коэффициентов (коэффициентов приведения к стандартным условиям) на первое полугодие 2022 года»…

Все виды некалендарных лет (учебный, бюджетный, отчетный год), т.е. начинающихся в одном году, а заканчивающихся в другом, пишут через косую черту (см. Пример 21). В остальных случаях – между календарными годами ставится тире без пробелов, не дефис (Пример 22).

Пример 21. В тексте указываем учебный год

В 2021/2022 учебном году организация образовательного процесса будет осуществляться по четвертям.

Пример 22. В тексте указываем период из календарных годов

Увеличение сборов налогов в 2019–2021 гг. на товары и услуги в первую очередь спровоцировало перераспределение акцизов в пользу региональных бюджетов.

При записи календарных чисел наращение (буквенное падежное окончание) не используется. Перед цифровым способом написания числа месяца употребляется предлог «с» (Пример 23), а перед словом-числительным употребляется предлог «со» (Пример 24).

Пример 23. Предлог перед цифрой

Испытание промышленного образца автомобильного двигателя будет проходить с 2 по 6 марта 2022 года.

Пример 24. Предлог перед словом согласуется с ним

Выставка будет проходить со второго по шестое марта 2022 года.

Если дата указана периодом «с»…«по», слово «годы» или «годов» указывается 1 раз.

Пример 25. Слово «год» / «годы» при указании периода пишется 1 раз

Основные направления бюджетной, налоговой и таможенно-тарифной политики на 2022 год и на плановый период 2023 и 2024 годов разработаны в соответствии со статьей 165 Бюджетного кодекса Российской Федерации с учетом итогов реализации бюджетной, налоговой и таможенно-тарифной политики на период до 2021­­–2023 годов.

При разработке инструкций по делопроизводству рекомендуем придерживаться данных способов написания дат в реквизитах документов, чтобы соблюдать единообразие и логичность оформления документов в России.

Для работы с датами разработан ряд специальных типов полей, которые мы подробно рассмотрим в этой статье.

Дата с календарем

Для ввода даты в форме записи предусмотрено два типа поля:

  1. Дата с календарем
  2. Дата с календарем и выбором времени

Эти поля идентичны по настройкам. На вкладке «Настройки» можно указать собственный формат для конкретного поля.

На вкладке «Дополнительно» можно задать дату по умолчанию и минимальную/максимальную дату, которую можно выбрать в календаре. Например: 0 — текущая дата, 5 — текущая дата + 5 дней.

Вкладка «Цвет» содержит ряд настроек для выделения даты цветом. Просроченную дату, или дату за несколько дней до указанной даты можно выделить цветом.

Обратите внимание: опция «Отключить цвет» отключает подсветку даты при определенном значении полей типа «выпадающий список».

Разница между датами

Для вычисления разницы между датами предусмотрены следующие поля:

  • Разница в годах
  • Разница в месяцах
  • Разница в днях
  • Разница в часах

Данные типы полей имеют схожие настройки, где вам необходимо указать два поля, между которыми будет вычисляться разница.

Используйте опцию «Выполнять динамически» только при вычислениях между текущей датой. Обратите внимание: данная опция увеличивает нагрузку на сервер.

Опция «Исключить праздники» исключает даты, установленные на странице «Настройки — Праздничные даты».

Динамическая дата

Специальный тип поля, который высчитывает дату по MySQL формуле. Данный тип поля может применяться в фильтрах записей по дате, а так же использоваться в календарном отчете или диаграмме Ганта.

Даты в CRM Руководитель хранятся в timestamp (в секундах), поэтому, для увеличения даты на 1 день необходимо добавить 86400 секунд.

Давайте рассмотрим несколько примеров:

[159]+(86400*[150])

159 — поле дата с календарем.
150 — поле ввода, в котором хранится количество дней.

[159]+(86400*get_value([151]))

159 — поле дата с календарем.
151 — поле выпадающий список, значение которого умножается на 1 день.

Для получения даты из родительской сущности воспользуйтесь следующим примером:

(select field_159 from app_entity_21 where id=e.parent_item_id)

159 — ID поля дата в родительской сущности
21 — ID родительской сущности

Понравилась статья? Поделить с друзьями:
  • Термет газовая колонка инструкция по применению
  • Эстрогиал крем инструкция по применению отзывы врачей
  • Моб телефон алкатель раскладушка 2012д инструкция
  • Дипроспан уколы инструкция по применению цена отзывы аналоги таблетки
  • Лагерь сказка руководство