Генератор date
Когда брать. Нужна дата или дата-время — день рождения, дата документа, метка времени события — в заданном диапазоне и в нужном формате вывода.
Даты работают на собственном переносимом рантайме дат TDC: строгий парсер, UTC-календарь и локализованный форматтер, без зависимости от moment.js. Один и тот же конфиг рассчитан на одинаковые даты во всех реализациях.
Примеры вывода ниже иллюстративны — точные значения зависят от сида и могут отличаться между версиями ядра. Неизменны форма и формат.
Кратко
| Атрибут | Что делает |
|---|---|
value | birth, today, now, одна дата или диапазон START..END |
range | Диапазон START..END — более новое написание той же идеи |
from / to | Две границы диапазона, заданные по отдельности |
format | Формат вывода (см. раздел «Форматирование вывода» ниже); по умолчанию L |
local | en, es, ru или zh-cn; наследуется из <env>, если не задан |
oldest / youngest | Возрастное окно в годах для value="birth" (по умолчанию 80 и 10) |
precision | day, second или millisecond |
Диапазон описывает только что-то одно из value, range или пары from/to —
это три написания одного и того же. Не задайте ни одного из них — и диапазон пойдёт от
1970-01-01 до текущего момента; см.
Границ нет вовсе.
Случайная дата из диапазона
Задайте value в виде START..END (обе границы включены) — и получите
случайную дату, равномерно распределённую внутри окна.
<gen type="date" value="2020-01-01..2025-12-31" format="YYYY-MM-DD"/>
2024-08-15 2022-02-04 2020-06-21 2025-10-04 2021-03-31
Границы — часть окна. На узком окне в одну неделю это хорошо видно: на достаточном
числе строк встречаются и 2024-06-01, и 2024-06-07:
<gen type="date" value="2024-06-01..2024-06-07" format="YYYY-MM-DD"/>
2024-06-06 2024-06-03 2024-06-01 2024-06-07 2024-06-02 2024-06-02
Входные даты парсятся строго, в одной из форм:
- дата:
YYYY-MM-DD,YYYY.MM.DDилиYYYY/MM/DD; - дата-время:
YYYY-MM-DDTHH:mm,YYYY-MM-DDTHH:mm:ssилиYYYY-MM-DDTHH:mm:ss.SSS; - диапазон:
START..END.
Свободный текст (6 июня, 06/06/24) не принимается — используйте одну из
строгих форм выше.
Атрибут range — то же окно, более новое написание
range="START..END" означает ровно то же, что value="START..END". Оно читается
лучше, когда value иначе выглядело бы как ключевое слово, и это то самое
написание, что и у шаблона date.range.
<gen type="date" range="2020-01-01..2024-12-31" format="YYYY-MM-DD"/>
2023-11-08 2021-09-30 2020-05-23 2024-10-19 2021-01-14
Атрибут format управляет только тем, как дата
записана, — он никогда не меняет окно, а окно никогда не зависит от формата.
from и to — границы по отдельности
Когда яснее назвать две границы порознь, используйте from и to. Это самое
естественное написание для дата-временны́х окон, где диапазон иначе оказался бы
длинной единой строкой.
<gen type="date"
from="2026-05-02T09:00:00"
to="2026-05-02T09:00:05"
format="YYYY-MM-DDTHH:mm:ss"/>
2026-05-02T09:00:04 2026-05-02T09:00:01 2026-05-02T09:00:03 2026-05-02T09:00:00 2026-05-02T09:00:02
Границ нет вовсе — диапазон закрывают часы
Генератор date, которому не дали ни одной границы, всё равно выдаёт дату. Окно
идёт от 1970-01-01 до текущего момента, то есть генератор читает часы, хотя в конфиге
ни одна дата не упомянута:
<gen type="date" format="YYYY-MM-DD"/>
--now 2026-04-23 --now 2027-04-23 1972-06-01 1972-06-17 1994-11-20 1995-04-30 1972-05-06 1972-05-21
Так воспроизводимость теряется проще всего. Задайте генератору две границы или
зафиксируйте часы через --now.
Одна граница третьим вариантом не является. from без to — ошибка (TDC150), и
range="2020-01-01.." тоже (TDC151). Диапазон — это либо обе границы, либо ни одной.
День рождения через value="birth"
value="birth" выдаёт дату рождения относительно текущей даты, ограниченную
возрастным окном. youngest и oldest — это возраст в годах (по умолчанию
10 и 80), поэтому youngest="18" oldest="65" даёт взрослых трудоспособного
возраста.
<gen type="date" value="birth" youngest="18" oldest="65" format="DD.MM.YYYY"/>
05.07.1997 23.11.1985 14.02.2003 30.09.1971 18.06.1990
Зачем это вместо фиксированного диапазона: окно следует за «сейчас», поэтому тот
же конфиг и через год продолжит выдавать правдоподобные возрасты без правки дат. Для
дня рождения, привязанного к цельному синтетическому человеку, шаблон
person.b_day принимает те же атрибуты
oldest/youngest/format.
По этой же причине даты и уезжают. Окно едет вслед за часами, поэтому завтра тот же сид
даст другую дату рождения: возраст держится, дата — нет. Там, где вывод должен стоять на
месте — снапшот-тест, фикстура, баг-репорт, — зафиксируйте часы через
--now.
today и now
value="today" — текущая дата; value="now" — текущая дата и время. Оба
читают часы runtime, поэтому это естественные метки для полей «сформировано» или «по
состоянию на».
<gen type="date" value="today" format="LL" local="ru"/>
<gen type="date" value="now" format="YYYY-MM-DDTHH:mm:ss.SSS"/>
value="today" format="LL" local="ru" 23 апреля 2026 г. value="now" format="YYYY-MM-DDTHH:mm:ss.SSS" 2026-04-23T12:00:00.000
Чтение часов — в этом и смысл обоих, и именно поэтому они невоспроизводимы: сид никак
не влияет на то, какое сегодня число. Зафиксируйте часы через
--now — и today с now в каждом
прогоне вернут названный вами момент.
precision — шаг для дата-временны́х диапазонов
precision задаёт наименьший шаг, которым движется диапазон: day, second или
millisecond. Для пятисекундного окна с шагом в целые секунды:
<gen type="date"
from="2026-05-02T09:00:00"
to="2026-05-02T09:00:05"
precision="second"
format="YYYY-MM-DDTHH:mm:ss"/>
2026-05-02T09:00:04 2026-05-02T09:00:01 2026-05-02T09:00:03 2026-05-02T09:00:00 2026-05-02T09:00:02
Если precision опущен, значение по умолчанию следует типу диапазона:
| Тип диапазона | Шаг по умолчанию | Что меняет precision |
|---|---|---|
только дата (YYYY-MM-DD) | один день | нужен редко — тут и так целые дни |
| дата-время | одна миллисекунда | precision="second" обнуляет миллисекунды |
Используйте precision="second", когда нужны чистые, «человеческие» метки времени
вместо миллисекундного шума; используйте precision="millisecond" (значение
по умолчанию для дата-времени), когда нужна субсекундная точность.
Форматирование вывода
format — это шаблон из маркеров. Он меняет только то, как дата записана, —
само значение не трогается. По умолчанию — L (локаль-зависимая короткая дата).
Все маркеры на одном зафиксированном моменте — вторник 5 марта 2024, 09:04:07. День и месяц взяты однозначными нарочно, чтобы пары «с нулём / без нуля» отличались на глаз:
| Маркер | Значение | Пример |
|---|---|---|
YYYY | год из 4 цифр | 2024 |
YY | год из 2 цифр | 24 |
MMMM | полное имя месяца | March |
MMM | короткое имя месяца | Mar |
MM | месяц из 2 цифр | 03 |
M | месяц без ведущего нуля | 3 |
DD | день из 2 цифр | 05 |
D | день без ведущего нуля | 5 |
dddd | полное имя дня недели | Tuesday |
ddd | короткое имя дня недели | Tue |
HH | час из 2 цифр (24ч) | 09 |
H | час без ведущего нуля | 9 |
mm | минута из 2 цифр | 04 |
m | минута без ведущего нуля | 4 |
ss | секунда из 2 цифр | 07 |
s | секунда без ведущего нуля | 7 |
SSS | миллисекунды | 000 |
Z | смещение UTC с двоеточием | +00:00 |
ZZ | смещение UTC без двоеточия | +0000 |
ISO | дата в формате ISO 8601 | 2024-03-05 |
L | локаль-зависимая короткая дата | 03/05/2024 |
LL | локаль-зависимая длинная дата | March 5, 2024 |
LLL | длинная дата со временем | March 5, 2024 09:04 |
LLLL | она же с днём недели | Tuesday, March 5, 2024 09:04 |
Имена месяцев и дней недели, а также четыре формы L, следуют локали — см.
ниже. Всё остальное одинаково на любом языке.
Одна и та же дата в четырёх форматах — сид один, поэтому дата в каждой строке одинакова, различается только запись:
<gen type="date" value="2020-01-01..2024-12-31" format="YYYY-MM-DD"/>
<gen type="date" value="2020-01-01..2024-12-31" format="DD.MM.YYYY"/>
<gen type="date" value="2020-01-01..2024-12-31" format="DD MMM YYYY"/>
<gen type="date" value="2020-01-01..2024-12-31" format="LL"/>
YYYY-MM-DD DD.MM.YYYY DD MMM YYYY LL 2023-11-08 08.11.2023 08 Nov 2023 November 8, 2023 2021-09-30 30.09.2021 30 Sep 2021 September 30, 2021 2020-05-23 23.05.2020 23 May 2020 May 23, 2020
Литеральный текст в скобках
Всё, что в квадратных скобках, копируется в вывод дословно, поэтому дату можно обернуть в фиксированный текст:
<gen type="date" value="2024-03-15..2024-03-15" format="[дата:] YYYY-MM-DD"/>
дата: 2024-03-15
Локаль-зависимые форматы: L и LL
L, LL, LLL и LLLL следуют локали, взятой из атрибута local (или local на
<env>), — как и маркеры имён MMMM, MMM, dddd и ddd.
Локаль по умолчанию — en. Числовые шаблоны вроде
YYYY-MM-DD и DD.MM.YYYY никогда не зависят от локали — только от написанного вами
шаблона.
Вот фиксированная дата 2024-03-15 под format="LL", сначала в локали по умолчанию
(en), затем та же дата, перерисованная с local="ru", чтобы показать
локализованное имя месяца и длинную форму, — намеренная демонстрация локализации:
<gen type="date" value="2024-03-15..2024-03-15" format="LL"/> <!-- по умолчанию en -->
<gen type="date" value="2024-03-15..2024-03-15" format="LL" local="ru"/> <!-- русская -->
по умолчанию (en) March 15, 2024 local="ru" 15 марта 2024 г.
L смещается так же: 03/15/2024 в en, 15.03.2024 в ru.
Подводные камни, всё в одном месте
- Входные даты парсятся строго — используйте
YYYY-MM-DD(или.//), а не свободный текст. - Обе границы диапазона включены.
value,rangeиfrom/to— три написания одного окна, берите то, что читается лучше.L/LLменяются сlocal;YYYY-MM-DDи подобные — нет.- Диапазоны только из дат шагают по дням; дата-временны́е — по миллисекундам, если не задан
precision. today,now,value="birth"и генератор без границ читают часы, поэтому одним сидом их не воспроизвести — фиксируйте часы через--now.formatприменяется только к датам. На шаблонных идентификаторах (ИНН, СНИЛС, телефон…) это ошибка — оформляйте их фильтрами интерполяции.