Работа с датами и временем в боте
- Хелпер formatDate →
- Переменная date →
- Переменная format →
- Примеры использования →
- Unix-время →
- Выбор языка форматирования, параметр lang →
- Выбор часового пояса, параметр timezone →
- Использование произвольного формата даты, параметр fromFormat →
- Получение и форматирование текущего времени и даты →
- Регулярные выражения для преобразования даты →
- Как с помощью регулярного выражения настроить ответ бота в зависимости от времени входа пользователя →
- Как настроить ответ бота в зависимости от времени входа пользователя используя хелпер vars →
- Как сравнить даты между собой →
- Как читать даты от пользователя →
Текущую дату и время можно получить с помощью хелпера:
{{formatDate "DD.MM.YYYY HH:mm"}}
Хелпер formatDate
Нужен, чтобы менять формат даты.
Иногда нужно отформатировать и показать дату в каком-то формате, или превратить дату в день недели, или преобразовать один формат даты в другой.
Все это можно сделать при помощи хелпера formatDate.
Хелпер можно использовать так:
{{formatDate date format}}
- date — это имя переменной с датой
- format — это имя переменной с допустимым шаблоном для формата даты
Переменная date
Должна содержать дату, записанную в подходящем формате.
formatDate принимает даты вида:
- 2020-05-01
- 2020/05/01
- 2020.05.01
- 05.01.2020
- 05-01-2020
Во всех случаях записана дата 1 мая 2020 года.
Обратите внимание, что в привычной для русского языка дате 05.01.2020 все равно первым считается месяц, а потом число. Дело в том, что по умолчанию formatDate читает дату в международных форматах.
Как указать свой собственный, в т. ч. правильный, порядок для русскоязычных дат будет рассказано ниже.
Если нужно указать часы, минуты и секунды, то их записывают через двоеточие, отделив от даты пробелом, например:
2020-05-01 12:45:30.
Также formatDate умеет работать с точными компьютерными датами и временем, полученными Запросами из некоторых API:
2020-05-01T12:45:30.900Z
Тут записана дата: 1 мая 2020 года, 12 часов, 45 минут, 30 секунд, 900 миллисекунд.
Переменная format
Это строка, в которой можно записать формат, в который мы хотим превратить дату.
В формате могут быть: года, месяцы, дни, часы, минуты и много-много других параметров.
format не обязательно записывать в переменную, его можно записать прямо в хелпере.
Допустим, у нас в переменной date есть дата: 2020-05-01, и мы хотим показать ее в привычном для русского языка формате: 01.05.2020.
Это можно сделать такой записью хелпера:
{{formatDate date "DD.MM.YYYY"}}
"DD.MM.YYYY" — это строка с форматом:
- DD — означает день месяца с ведущим нулем;
- MM — означает порядковый номер месяца в году с ведущим нулем;
- YYYY — означает год записанный четырьмя цифрами.
Такие записи, как DD, MM, YYYY называются последовательностями формата даты, и formatDate поддерживает большое их количество.
Из самых частых также стоит отметить:
- HH — это часы с ведущим нулем от 00 до 23;
- mm — это минуты с ведущим нулем от 00 до 59;
- ss — это секунды с ведущим нулем от 00 до 59.
Полный список возможных последовательностей
Последовательность | Пример | |
Месяц | M | 1 2 ... 11 12 |
Mo | 1st 2nd ... 11th 12th | |
MM |
01 02 ... 11 12 | |
MMM | Jan Feb ... Nov Dec | |
MMMM | January February ... November December | |
Квартал | Q | 1 2 3 4 |
Qo | 1st 2nd 3rd 4th | |
День месяца | D | 1 2 ... 30 31 |
Do | 1st 2nd ... 30th 31st | |
DD | 01 02 ... 30 31 | |
День года | DDD | 1 2 ... 364 365 |
DDDo | 1st 2nd ... 364th 365th | |
DDDD | 001 002 ... 364 365 | |
День недели | d | 0 1 ... 5 6 |
do | 0th 1st ... 5th 6th | |
dd | Su Mo ... Fr Sa | |
ddd | Sun Mon ... Fri Sat | |
dddd | Sunday Monday ... Friday Saturday | |
День недели зависимый от выбранного языка в параметре lang | e | 0 1 ... 5 6 |
День недели по стандарту ISO | E | 1 2 ... 6 7 |
Неделя в году | w | 1 2 ... 52 53 |
wo | 1st 2nd ... 52nd 53rd | |
ww | 01 02 ... 52 53 | |
Неделя в году по стандарту ISO | W | 1 2 ... 52 53 |
Wo | 1st 2nd ... 52nd 53rd | |
WW | 01 02 ... 52 53 | |
Год | YY | 70 71 ... 29 30 |
YYYY | 1970 1971 ... 2029 2030 | |
YYYYYY | -001970 -001971 ... +001907 +001971 | |
Y | 1970 1971 ... 9999 +10000 +10001 Соответствует стандарту ISO 8601 |
|
Год эры | y | 1 2 ... 2020 ... |
Эра | N, NN, NNN | BC AD |
NNNN | Before Christ, Anno Domini | |
NNNNN | BC AD | |
Недельный год(Week Year) | gg | 70 71 ... 29 30 |
gggg | 1970 1971 ... 2029 2030 | |
Недельный год по стандарту ISO (Week Year) | GG | 70 71 ... 29 30 |
GGGG | 1970 1971 ... 2029 2030 | |
AM/PM | A | AM PM |
a | am pm | |
Час | H | 0 1 ... 22 23 |
HH | 00 01 ... 22 23 | |
h | 1 2 ... 11 12 | |
hh | 01 02 ... 11 12 | |
k | 1 2 ... 23 24 | |
kk | 01 02 ... 23 24 | |
Минута | m | 0 1 ... 58 59 |
mm | 00 01 ... 58 59 | |
Секунда | s | 0 1 ... 58 59 |
ss |
00 01 ... 58 59 | |
Миллисекунда | S | 0 1 ... 8 9 |
SS | 00 01 ... 98 99 | |
SSS | 000 001 ... 998 999 | |
SSSS ... SSSSSSSSS | 000[0..] 001[0..] ... 998[0..] 999[0..] | |
Часовой пояс | Z | -07:00 -06:00 ... +06:00 +07:00 |
ZZ | -0700 -0600 ... +0600 +0700 | |
Unix Timestamp в секундах | X | 1360013296 |
Unix Timestamp в миллисекундах | x | 1360013296123 |
Время в зависимости от выбранного языка в параметре lang | LT | 8:30 PM |
Время с секундами в зависимости от выбранного языка в параметре lang | LTS | 8:30:25 PM |
Дата в зависимости от выбранного языка в параметре lang | L | 09/04/1986 |
l | 9/4/1986 | |
Дата с именем месяца в зависимости от выбранного языка в параметре lang | LL | September 4, 1986 |
ll | Sep 4, 1986 | |
Дата и время с именем месяца в зависимости от выбранного языка в параметре lang | LLL | September 4, 1986 8:30 PM |
lll | Sep 4, 1986 8:30 PM | |
Дата и время с именем месяца и днем недели в зависимости от выбранного языка в параметре lang | LLLL | Thursday, September 4, 1986 8:30 PM |
llll | Thu, Sep 4, 1986 8:30 PM |
Примеры приведены для языка по умолчанию — английского.
Примеры использования
Приведем несколько примеров работы с датами используя данные из таблицы.
Так можно вывести день недели в виде порядкового номера:
{{formatDate "d"}}
В этом формате дни будут считаться от 0 до 6, где 0 — это воскресенье, 1 — понедельник и т.д.
Выводить дни недели в формате «Mo», «Tu» и т.д. можно так:
{{formatDate "dd"}}
Так можно выводить дни недели полностью («понедельник», «вторник», и т. д.). Добавим lang="ru", чтобы дни недели вывелись по-русски :
{{formatDate "dddd" lang="ru"}}
По умолчанию названия дней недели выводятся по-английски:
{{formatDate "dddd"}}
Дата будет преобразовываться в зависимости от того, в какой день недели зашел пользователь.
Так можно вывести название месяца:
{{formatDate "MMM"}}
С помощью хелпера capitalize месяц выведется с большой буквы:
{{capitalize (formatDate "MMM")}}
Так можно вывести порядковый номер недели в году:
{{formatDate 'w'}}
Вместе с formatDate можно использовать хелперы. Например, с помощью addDate, можно прибавлять к текущей дате дни, недели, года и другие промежутки времени.
Так прибавится один день:
{{addDate (formatDate "DD.MM.YYYY HH:mm:ss") 1 "days" "DD.MM.YYYY HH:mm:ss"}}
Можно поменять 1 на нужное количество дней, которые прибавляются:
{{addDate (formatDate "DD.MM.YYYY HH:mm:ss") 15 "days" "DD.MM.YYYY HH:mm:ss"}}
Если поменять "days" на "months" — прибавятся месяцы:
{{addDate (formatDate "DD.MM.YYYY HH:mm:ss") 1 "months" "DD.MM.YYYY HH:mm:ss"}}
"weeks" — недели:
{{addDate (formatDate "DD.MM.YYYY HH:mm:ss") 1 "weeks" "DD.MM.YYYY HH:mm:ss"}}
"years" — года:
{{addDate (formatDate "DD.MM.YYYY HH:mm:ss") 1 "years" "DD.MM.YYYY HH:mm:ss"}}
"quarters" — кварталы:
{{addDate (formatDate "DD.MM.YYYY HH:mm:ss") 1 "quarters" "DD.MM.YYYY HH:mm:ss"}}
"hours" — часы:
{{addDate (formatDate "DD.MM.YYYY HH:mm:ss") 2 "hours" "DD.MM.YYYY HH:mm:ss"}}
"minutes" — минуты:
{{addDate (formatDate "DD.MM.YYYY HH:mm:ss") 2 "minutes" "DD.MM.YYYY HH:mm:ss"}}
"seconds" — секунды:
{{addDate (formatDate "DD.MM.YYYY HH:mm:ss") 2 "seconds" "DD.MM.YYYY HH:mm:ss"}}
Unix-время
Также часто называют Unix timestamp или просто таймстэмп.
Это специальный способ записывать точные дату и время в виде числа.
Число показывает, сколько миллисекунд прошло с начала эпохи Unix — 00:00:00 1 января 1970 года по Гринвичу.
Например, 1 мая 2020 года, 12 часов, 45 минут, 30 секунд, 900 миллисекунд в timestamp будет равняться 1588337130900 миллисекунд.
Unix-время часто можно получить в запросах от разных API.
Unix-время можно использовать в formatDate. Например, мы можем легко убедиться,
когда началась эпоха Unix таким форматированием:
{{formatDate 0 "DD.MM.YYYY HH:mm:ss:SSS"}}
Если выполнить такой шаблон, то вы увидите: 01.01.1970 03:00:00:000.
Три часа ночи 1 января 1970 года. 3 часа ночи, потому что formatDate по умолчанию использует московский часовой пояс.
Параметры в примере простые:
- 0 — ноль миллисекунд, с начала эпохи Unix
- "DD.MM.YYYY HH:mm:ss:SSS" — формат Дни.Месяцы.Года Часы:Минуты:Секунды:Миллисекунды
Обратите внимание, что в языке PHP timestamp — это время в секундах,
и чтобы использовать его в formatDate нужно умножить его на 1000 хелпером multiply:
{{formatDate (multiply timestampFromPHP 1000) "DD.MM.YYYY"}}
Выбор языка форматирования, параметр lang
Для некоторых последовательностей важен выбор языка. По умолчанию язык английский,
но его можно изменить, например, на русский.
Если мы используем хелпер вот так:
{{formatDate date "DD MMMM YYYY"}}
без смены языка, то у нас получится какой-то такой результат: 01 May 2020
Допустим, мы хотим, чтобы дата показывалась на русском языке, а не на английском.
Это можно сделать при помощи параметра lang:
{{formatDate date "DD MMMM YYYY" lang="ru"}}
теперь язык будет русский: 01 мая 2020
Выбор часового пояса, параметр timezone
По умолчанию хелпер использует московский часовой пояс.
Это может оказаться неудобным, если нужно поддерживать другой регион или вообще несколько.
Чтобы сменить часовой пояс можно использовать параметр timezone:
{{formatDate date "HH:mm" timezone="America/New_York"}}
В примере выше мы указали часовой пояс New York, и это изменило часы и минуты при форматировании даты.
Полный список поддерживаемых часовых поясов можно посмотреть в песочнице →
Использование произвольного формата даты, параметр fromFormat
formatDate сам по себе умеет работать только со стандартизированными датами.
Но иногда даты бывают и в других форматах.
Например, в русском языке принято записывать дату как День.Месяц.Год, но formatDate такую дату распознает неправильно — как Месяц.День.Год. К счастью, это легко изменить при помощи параметра fromFormat.
Допустим, у нас в переменной date находится такая дата — 1 мая 2020 — в виде строки:
01.05.2020
Если мы просто попытаемся ее преобразовать в другой вид, например, выделить отдельно месяц:
{{formatDate date "MM"}}
получится неправильно: 01, т. е. январь.
Чтобы сообщить formatDate точный формат, в котором записана наша дата, можно использовать специальный параметр fromFormat:
{{formatDate date "MM" fromFormat="DD.MM.YYYY"}}
Так мы точно указали, в каком формате хранится изначальная дата, и теперь можем с ней работать.
В параметре fromFormat можно использовать любые последовательности форматирования дат, чтобы составить такой формат входящей даты, который будет вам удобен.
Получение и форматирование текущего времени и даты
При помощи formatDate можно получить отформатированное текущее время и дату.
Сделать это можно двумя способами.
Используем хелпер now
Этот хелпер возвращает Unix-время в миллисекундах.
Мы можем использовать его, чтобы получить, например, сегодняшнюю дату:
{{formatDate (now) "DD.MM.YYYY"}}
Или день недели:
{{formatDate (now) "dddd" lang="ru"}}
Или часы и минуты:
{{formatDate (now) "HH:mm"}}
Или составить любой другой формат даты из возможных последовательностей.
Используем только формат
Только now использовать не обязательно. Если не передавать в formatDate дату,
а использовать только формат, он сам поймет, что вы хотите использовать шаблон
для текущего времени:
{{formatDate "DD.MM.YYYY"}} {{formatDate "dddd" lang="ru"}} {{formatDate "HH:mm"}}
Все эти три примера полностью совпадают с использованием хелпера now.
Регулярные выражения для преобразования даты
Что бы получать дату в необходимом формате, используйте регулярные выражения:
^\d\d\.\d\d\.\d\d\d\d$ — для даты в формате дд.мм.гггг, например 15.05.2000
^\d\d\d\d\/\d\d\/\d\d$ — для даты в формате гггг/мм/дд, например 2000/05/15
Как с помощью регулярного выражения настроить ответ бота в зависимости от времени входа пользователя
В этом кейсе бот присылает два разных ответа в зависимости от времени суток. На стороне пользователя точка входа всегда одна и та же.
С 10 до 19 бот отвечает по сценарию рабочего времени. Например, бот может перевести пользователя на оператора, который работает в это время.
С 19 до 10 бот отвечает пользователю что сейчас компания не работает и нужно написать в рабочее время.
Настройка
Получаем и преобразовываем в нужный формат текущее время
Текущую дату и время мы можем получать с помощью хелпера:
{{formatDate "DD.MM.YYYY HH:mm"}}
Записываем компонентом Запись переменной значение в переменную Time. Поскольку нас интересует только время, в которое пришел пользователь в бота, то нужно удалить из хелпера дату и оставить только часы и минуты:
{{formatDate "HH:mm"}}
Обрабатываем время и переводим на заданные экраны
Ставим на экран компонент Развилка. В поле Имя переменной, откуда развилка возьмёт значение указываем Time.
Регулярное выражение проще составить для первого интервала — с 10 до 19:
^1[0-8]\:[0-5][0-9]$
Добавляем это регулярное выражение в значение цели Развилки. Выбираем Регулярное выражение в Типе данных. Цель по умолчанию — перевод в интервал с 19 до 10.
Оформляем экраны с ответами бота. Готово.
Как настроить ответ бота в зависимости от времени входа пользователя используя хелпер vars
Добавьте этот кейс и пользователь будет получать разные ответы в зависимости от времени, в которое он обратился к боту. Например, у бота можно спросить какое мероприятие или лекция сейчас проходит на воркшопе. Этот сценарий подойдет и для других случаев где ответы бота определяются расписанием.
В примере семь ответов, которые соответствуют семи временным промежуткам. Каждый ответ срабатывает в соответствии со временем, которое вы пропишете в шаблоне. Для пользователя точка входа будет одна и та же, ответы будут зависеть только от того, во сколько пользователь напишет боту.
Для каждого промежутка времени есть отдельный экран. Этот экран приходит только в указанное время.
Вы можете поменять диапазоны времени на другие.
Настройка
1. Добавьте Запись переменной с типом данных Строка.
2. Добавьте Имя переменной. В примере это route, так как это имя используется далее в шаблоне.
3. В Значение добавьте следующий шаблон:
{{#vars}} {{var "time" (toInt (formatDate "HHmm")) ~}} {{#var "route"}} {{!-- До 06:00 --}} {{#lt @vars.time 0600}} До утра {{/lt}} {{!-- С 06:00 до 09:00 --}} {{#and (gte @vars.time 0600) (lt @vars.time 0900) }} Ранее утро {{/and}} {{!-- С 09:00 до 12:00 --}} {{#and (gte @vars.time 0900) (lt @vars.time 1200) }} Утро {{/and}} {{!-- С 12:00 до 15:00 --}} {{#and (gte @vars.time 1200) (lt @vars.time 1500) }} Обед {{/and}} {{!-- С 15:00 до 19:00 --}} {{#and (gte @vars.time 1500) (lt @vars.time 1900) }} Вечер {{/and}} {{!-- С 19:00 до 22:00 --}} {{#and (gte @vars.time 1900) (lt @vars.time 2200) }} Поздний вечер {{/and}} {{!-- С 22:00 --}} {{#and (gte @vars.time 2200) }} Перед полуночью {{/and}} {{/var}} {{!-- Обрезаем возможные пробелы по краям --}} {{~trim @vars.route~}} {{/vars}}
В этом шаблоне:
- {{#vars}} — хелпер для создания и использования лоĸальных переменных в шаблонах.
- {{!-- С 22:00 --}}, {{!-- С 12:00 до 15:00 --}} и т.д. — комментарии приводятся для удобства и не влияют на работу шаблона. Вы можете их убрать при необходимости.
- 1900, 2200 и т.д. обозначают время по принципу 1900 = 19:00. Вы можете поменять интервалы времени меняя эти значения.
- До утра, Ранее утро, Утро, Обед, Вечер, Поздний вечер и Перед полуночью — значения, которые далее будут проверяться в Развилке. Вы также можете поменять эти значения. Важно, чтобы значения в Шаблоне и Развилке совпадали и соответствовали заданному вами временному диапазону.
- #lt (строго меньше) и #gtе (больше или равно) — блочные хелперы для проверки условий.
- {{~trim @vars.route~}} — тильды справа и слева удаляют возможные пробелы и переносы строки, которые могут возникнуть в шаблоне. Это важно, так как из-за лишних пробелов и переносов может не сработать Развилка, которую мы добавим в следующем шаге.
4. Добавьте Развилку.
5. Заполните Имя переменной откуда Развилка возьмет значение переменной route. Если в вашем шаблоне из Записи переменной вы поменяли значение на другое, то добавьте его вместо значения из примера.
6. Добавьте в Развилку 7 Целей и создайте 7 экранов для каждой из них.
7. Заполните Значения Целей развилки:
- До утра — цель будет срабатывать до 06:00,
- Ранее утро — цель будет срабатывать с 06:00 до 09:00,
- Утро — цель будет срабатывать с 09:00 до 12:00,
- Обед — цель будет срабатывать с 12:00 до 15:00,
- Вечер — цель будет срабатывать с 15:00 до 19:00,
- Поздний вечер — цель будет срабатывать с 19:00 до 22:00,
- Перед полуночью — цель будет срабатывать после 22:00.
8. Добавьте переходы на соответствующие экраны.
Готово.
Как сравнить даты между собой
Сделаем так, чтобы пользователю написавшему менее чем через 15 дней после покупки пришло сообщение с одним текстом, а тому, кто написал позже 15-дневного срока — с другим.
Это может быть полезно, если скидка на товар действует только 15 дней после покупки или для других подобных случаев.
1. Спросим у пользователя, когда он совершил последнюю покупку.
2. Запишем ответ в переменную Usday с помощью Ввода от пользователя. Выберем тип данных Дата.
3. Переведем сегодняшнюю дату в милисекунды с помощью хелпера
{{now}}
4. Переведем в миллисекунды дату, в которую была совершена последняя покупка, используя другой хелпер:
{{formatDate Usday 'x'}}
Таким образом перезапишем переменную Usday.
5. Вычтем из сегодняшнего дня дату, в которую была сделана последняя покупка:
{{subtract today Usday}}
Запишем результат вычитания в переменную diff
6. С помощью хелпера для сравнения gt определим прошло больше 15 дней или меньше:
{{#gt (toInt diff) 1296000000}}Больше 15 дней{{else}}Меньше 15 дней{{/gt}}
7. Проверим переменную days развилкой и направим пользователей на разные экраны в зависимости от того, сколько прошло времени.
8. Оформим отдельные экраны для тех кто написал позже чем через 15 дней и тем кто раньше.
Как читать даты от пользователя
Такой способ чтения даты будет полезен в случае, когда от пользователя требуется дата в формате 01.01.2000 или 01\01\2000 и бот не должен пропустить цифры не являющиеся датой.
Корректность даты, которую прислал пользователь, можно проверить с помощью Ввода от пользователя с типом данных Регулярное выражение, регулярное выражение должно быть таким:
\d{2}.\d{2}.\d{4}
Затем добавьте Развилку.
Имя переменной, откуда развилка возьмет значение должно быть таким же, как во Вводе от пользователя. Так мы проверим эту переменную в Развилке.
Добавьте в Развилку одну Цель с типом данных: Дата. Разверните настройки Развилки и добавьте Имя переменной, куда запишется дата введенная пользователем. В сообщении после Развилки эту дату можно вывести или использовать ее в дальнейшем сценарии бота.