Генератор date
Когда брать. Нужна дата или дата-время — день рождения, дата документа, метка времени события — в заданном диапазоне и в нужном формате вывода.
Даты работают на собственном переносимом рантайме дат TDC: строгий парсер, UTC-календарь и локализованный форматтер, без зависимости от moment.js. Один и тот же конфиг рассчитан на одинаковые даты во всех реализациях.
Примеры вывода ниже иллюстративны — точные значения зависят от сида и могут отличаться между версиями ядра. Неизменны форма и формат.
Кратко
| Атрибут | Что делает |
|---|---|
value | birth, today, now, одна дата или диапазон START..END |
range | Диапазон START..END — более новое написание той же идеи |
from / to | Две границы диапазона, заданные по отдельности |
order | sequential обходит диапазон вместо выбора из него — см. Ось дат |
step | Насколько сдвигается каждая строка на обходимой оси: 15m, 1h30m, 2d, 3mo, 1y |
weekdays | Какие дни недели оставляет обходимая ось: mon..fri, sun,wed |
cycle | false отказывает вместо зацикливания, когда обходимый ОГРАНИЧЕННЫЙ диапазон исчерпан |
format | Формат вывода (см. раздел «Форматирование вывода» ниже); по умолчанию L |
local | Двадцать пять: ar, cs, de, el, en, es, fi, fr, hi, hu, id, it, ja, ko, nl, pl, pt, ru, sv, th, tr, uk, vi, zh-cn, zh-tw. Девятнадцать отзываются ещё и на трёхбуквенный псевдоним — ara, ces, deu, ell, eng, spa, fin, fra, hun, ind, ita, jpn, kor, nld, pol, por, tur, ukr, vie, — а у hi, ru, sv, th, zh-cn, zh-tw псевдонима нет (голое zh принимается и читает традиционную таблицу). Наследуется из <env>, если не задан |
oldest / youngest | Возрастное окно в годах для value="birth" (по умолчанию 80 и 10) |
precision | day, second или millisecond |
of | Отсчитывать от другой колонки дат вместо розыгрыша — см. «Интервал» ниже |
plus | Насколько далеко от неё: 7d, 3..10d, 1..3mo, -10..-3d |
Диапазон описывает только что-то одно из value, range или пары from/to —
это три написания одного и того же. Не задайте ни одного из них — и диапазон пойдёт от
1970-01-01 до текущего момента; см.
Границ нет вовсе.
Последние четыре атрибута относятся к обходимому диапазону и читаются только вместе с
order="sequential". На разыгрываемой дате step или weekdays были бы молча
проигнорированы, поэтому они отвергаются (TDC248).
Случайная дата из диапазона
Задайте 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. Там, где значение
разыгрывается, одна граница ничего не говорит о том, что именно разыгрывать. Одной границы
ДОСТАТОЧНО, когда диапазон
обходят — об этом следующий раздел.
Ось дат: обход диапазона вместо выбора из него
Всё, что выше, разыгрывает: каждая строка берёт из окна случайную дату. Попросите по строке на каждый день года — получите повторы и пропуски, потому что розыгрыш именно это и означает.
Добавьте order="sequential" — и диапазон будет обойден. Строка 0 — это начало, строка
1 — один шаг дальше, строка i — это начало + i × шаг. Такая ось времени нужна прогону
тогда, когда данные это ряд, а не выборка: показания, транзакции, журнал.
from в одиночку — ось без конца
Обходимая ось принимает только начало. Её последняя строка — начало + (count − 1) × шаг:
строка 0 и есть само начало. Это следствие длины прогона, а не то, что вы вычисляете и
вписываете руками:
<gen type="date" from="2026-01-01" order="sequential" format="YYYY-MM-DD"/>
2026-01-01 2026-01-02 2026-01-03 2026-01-04 2026-01-05
Поднимите count до миллиона — ось просто пройдёт миллион дней. Ничего не разворачивается
в список, поэтому диапазон не стоит памяти, какой бы длинный он ни был.
step — насколько сдвигается каждая строка
По умолчанию — один день. step принимает число и единицу, и единицы складываются:
| Запись | Означает | Группа |
|---|---|---|
15m | 15 минут | фиксированная |
1h30m | 90 минут | фиксированная |
2 или 2d | 2 дня | фиксированная |
1w | 7 дней | фиксированная |
3mo | 3 календарных месяца | календарная |
1y6mo | 18 календарных месяцев | календарная |
m — это минута, как и во всякой записи такого вида. Месяц — это mo, потому что m
занято; и не M, потому что разница в сорок четыре тысячи раз между тремя минутами и тремя
месяцами не должна держаться на регистре одной буквы.
<gen type="date" from="2026-01-01T09:00:00" order="sequential"
step="15m" format="YYYY-MM-DD HH:mm"/>
2026-01-01 09:00 2026-01-01 09:15 2026-01-01 09:30 2026-01-01 09:45
Шаг бывает ЛИБО фиксированным, ЛИБО календарным, но не тем и другим сразу. 15m — это
всегда 900 000 миллисекунд, а месяц — от 28 до 31 дня. Складываются они только внутри своей
группы, и step="1mo15d" отвергается (TDC247): «месяц и пятнадцать дней» — это 43, 44, 45
или 46 дней в зависимости от того, какую половину применить первой, а конфиг, смысл которого
зависит от невидимого порядка, хуже конфига, который не разбирается. Пишите 45d или 1mo.
Календарный шаг сохраняет день месяца
Каждый шаг отмеряется от начала, а не накапливается. На днях эта разница незаметна, а на месяцах она решает ответ:
<gen type="date" from="2026-01-31" order="sequential" step="1mo" format="YYYY-MM-DD"/>
2026-01-31 2026-02-28 2026-03-31 2026-04-30
Февраль усекается до 28-го, а март возвращается к 31-му. Шаг от усечённого февраля дал бы 28 марта и утащил бы за собой все последующие месяцы.
weekdays — оставить только некоторые дни
Это фильтр, а не шаг:
<gen type="date" from="2026-01-01" order="sequential"
weekdays="mon..fri" format="ddd YYYY-MM-DD"/>
Thu 2026-01-01 Fri 2026-01-02 Mon 2026-01-05 Tue 2026-01-06 Wed 2026-01-07 Thu 2026-01-08
С пятницы на понедельник — прыжок в три дня, и именно поэтому это не шаг: шаг держит интервал ровным, а фильтр его ломает. Разведённые, они складываются — «каждые 12 часов, только в рабочие дни» требует обоих слов:
<gen type="date" from="2026-01-02T00:00:00" order="sequential"
step="12h" weekdays="mon..fri" format="ddd YYYY-MM-DD HH:mm"/>
Fri 2026-01-02 00:00 Fri 2026-01-02 12:00 Mon 2026-01-05 00:00 Mon 2026-01-05 12:00 Tue 2026-01-06 00:00 Tue 2026-01-06 12:00
Диапазон записывается через .., как и всякий диапазон в TDC, а перечисление — через
запятую: weekdays="sun,wed". Диапазон заворачивается: fri..mon — это пятница,
суббота, воскресенье, понедельник. Неделя это круг, и запрет обходить его сделал бы половину
диапазонов невыразимыми.
weekdays отвергают два вида шага (TDC250) — и по двум разным причинам.
Целое число недель каждый раз попадает на один и тот же день недели, поэтому фильтр
совпал бы со всеми строками или ни с одной — полная колонка или пустая, и ни слова о том,
что произошло. Проверяется длина шага, поэтому 14d отвергается ровно так же, как 2w,
а 10d проходит.
Календарный шаг — 1mo, 3mo, 1y — отвергается по обратной причине: он как раз
не фиксирует день недели. Пятнадцатое число за первую половину 2026-го проходит
четверг, воскресенье, воскресенье, среду, пятницу, понедельник. Какие строки переживут
фильтр по дням недели, решал бы календарь, а не то, что написано в конфиге, — поэтому шаг
и фильтр просят выбрать что-то одно.
Если вам нужна была ежемесячная дата, сдвинутая на ближайший рабочий день — как
биллинг переносит счёт с воскресенья, — то сегодня это не выражается, и фильтр этого бы
не сделал: он бы выкинул февраль целиком, а не перенёс его. Календарь рабочих дней —
это другое, и он работает: step="1d" вместе с weekdays="mon..fri", как выше.
Ограниченный диапазон заворачивается
Задайте обходимому диапазону обе границы — и он пойдёт по кругу, когда закончится, как это делает короткий список:
<gen type="date" range="2026-01-01..2026-01-03" order="sequential" format="YYYY-MM-DD"/>
2026-01-01 2026-01-02 2026-01-03 2026-01-01 2026-01-02 2026-01-03 2026-01-01
cycle="false" превращает исчерпание в отказ:
tdcv2: order="sequential" cycle="false": the source has only 2 values, so row 3 has none — shorten count= or lengthen the source
У открытой оси заворачиваться не на чем, поэтому cycle там ничего не значит.
День рождения через 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" (значение
по умолчанию для дата-времени), когда нужна субсекундная точность.
Интервал: дата, отсчитанная от другой даты
Настоящие записи полны пар: поступил и выписан, заказал и отгрузили, выдан и действителен до, начало и конец смены. Вторая дата не независима от первой — она и есть первая плюс длительность, — и два отдельных диапазона этого сказать не могут. Они ставят выписку раньше поступления в изрядной доле строк.
of называет колонку, от которой отсчитывать, а plus — насколько далеко:
<sequence name="Admitted">
<gen type="date" from="2026-01-01" to="2026-03-01" format="YYYY-MM-DD"/>
</sequence>
<sequence name="Discharged">
<gen type="date" of="Admitted" plus="2..14d" format="YYYY-MM-DD"/>
</sequence>
2026-02-06 2026-02-16 2026-02-14 2026-02-23 2026-01-11 2026-01-16 2026-01-11 2026-01-24 2026-02-27 2026-03-06 2026-01-08 2026-01-14
Каждая выписка позже своего поступления, на 2–14 дней — и длительность каждого пребывания разыгрывается для строки отдельно, а именно это два независимых диапазона и выбрасывают.
plus — расстояние
| Запись | Что значит |
|---|---|
7d | ровно семь дней, в каждой строке |
3..10d | от трёх до десяти дней, розыгрыш на строку (границы включены) |
1..3mo | от одного до трёх месяцев, по календарю |
-10..-3d | от трёх до десяти дней раньше источника |
45 | голое число означает дни |
Единицы те же, что у step:
s, m, h, d, w, mo, y — и так же m — это минута, а mo — месяц.
Одно значение — одно и то же расстояние в каждой строке:
<sequence name="Shipped">
<gen type="date" of="Ordered" plus="1d" format="YYYY-MM-DD"/>
</sequence>
2026-05-23 2026-05-24 2026-05-06 2026-05-07 2026-05-13 2026-05-14 2026-05-21 2026-05-22
Меньшая граница пишется первой, как и в любом другом диапазоне. Чтобы отсчитывать
назад, сделайте обе границы отрицательными: plus="-10..-3d" — это от трёх до
десяти дней раньше. plus="10..3d" — опечатка, и она отвергается (TDC264), а не
тихо переворачивается.
Месяцы и годы двигаются по календарю, а не фиксированным числом дней, поэтому
2026-01-31 плюс месяц — это 2026-02-28: то же поджатие, что делает
step.
Смещение читает значение, а не напечатанный текст
Колонка дат печатает представление своей даты. 03/02/2026 — это 3 февраля при
local="en" и 2 марта при local="ru", а format="MMMM D" вообще выбрасывает
год. Поэтому смещение не читает ячейку вовсе: колонка, от которой оно
отсчитывает, хранит саму сгенерированную дату, и арифметика идёт по ней. Любой
format и любая локаль подходят.
<env count="4" seed="visit" local="ru">
<sequence name="Visit"><gen type="date" from="2026-03-01" to="2026-03-31"/></sequence>
<sequence name="Followup"><gen type="date" of="Visit" plus="2w"/></sequence>
</env>
20.03.2026 03.04.2026 22.03.2026 05.04.2026 27.03.2026 10.04.2026 09.03.2026 23.03.2026
Единственный случай, когда читать нечего, — дата, которую TDC не генерировал:
например, колонка из file. Там есть только текст, поэтому он
должен быть в форме ISO (YYYY-MM-DD), которая означает одно и то же в любой
локали. Всё остальное отвергается, а не угадывается.
Источник может быть обходимым, разыгранным или другим смещением
of= читает всё, что произвела названная колонка. Обходимый источник — это как раз та
пара, которую настоящие записи просят чаще всего: заказы идут по календарю день за днём, а
доставка — через несколько дней после своего заказа:
<sequence name="Ordered">
<gen type="date" from="2026-01-01" order="sequential" step="1d" format="YYYY-MM-DD"/>
</sequence>
<sequence name="Delivered">
<gen type="date" of="Ordered" plus="2..9d" format="YYYY-MM-DD"/>
</sequence>
2026-01-01 2026-01-06 2026-01-02 2026-01-06 2026-01-03 2026-01-12 2026-01-04 2026-01-11
Единственный источник, от которого отсчитывать не от чего, — повторяющийся: ячейка,
собранная через repeat=, содержит несколько дат через разделитель. Такое отвергается по
имени, а не отвечается пустой колонкой.
Цепочки и пустые ячейки
Смещение само по себе — дата, которую произвёл движок, так что от неё может отсчитывать третья колонка: подписан, истекает через год, напомнить за месяц до того.
<sequence name="Signed"><gen type="date" from="2026-01-15" to="2026-02-15" format="D MMMM YYYY"/></sequence>
<sequence name="Expires"><gen type="date" of="Signed" plus="1y" format="D MMMM YYYY"/></sequence>
<sequence name="Remind"><gen type="date" of="Expires" plus="-30d" format="D MMMM YYYY"/></sequence>
5 February 2026 | 5 February 2027 | 6 January 2027 31 January 2026 | 31 January 2027 | 1 January 2027 13 February 2026 | 13 February 2027 | 14 January 2027 20 January 2026 | 20 January 2027 | 21 December 2026
Строка, у которой в источнике нет даты — та, что отсеял фильтр parent, или та,
которую обнулил missing, — не получает даты и
здесь. Отсчитывать не от чего, а придумать значение означало бы поставить
уверенно выглядящую дату в ячейку, которая по конфигурации должна быть пустой.
Что исключает of
of ставит дату относительно другой колонки, поэтому атрибуты, задающие
собственный жребий генератора, больше ничего не значат: value, from, to,
range, oldest, youngest, order и step. Написанный рядом с of, любой из
них отвергается (TDC264), а не игнорируется: конфигурация, которая просит
июньские даты и получает январские, права насчёт того, о чём просила, и не права
насчёт того, что получила.
Колонка, названная в of, должна быть объявлена выше смещения (TDC240) —
то же правило, что у running и stat.
Слой форматирования исключён по той же причине, по какой он исключён у бегущего итога:
смещение строится в порядке объявления, до того как этот слой запускается. mask,
case, missing, missing_as, repeat, anomaly, anomaly_factor и percent
отказываются (TDC015), а не игнорируются. Применяйте их там, где значение
печатается — ${{Later|mask:x}}, ${{Later|upper}}: там они работают и сейчас.
Обычный type="date" без of читает каждый из них как обычно; не может именно
смещение.
Смещение читает соседнюю колонку по ходу сборки строки, чего потоковый путь пока
не умеет, поэтому конфигурация со смещением собирается
в памяти. TDC направляет её туда сам; заметить это
можно, только если принудительно взять потоковый движок через --engine 2 — он
откажет по имени, а не станет приближать.
Форматирование вывода
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 |
ISO_TIME | дата и время в ISO 8601 | 2024-03-05T09:04:07 |
L | локаль-зависимая короткая дата | 03/05/2024 |
LL | локаль-зависимая длинная дата | March 5, 2024 |
LLL | длинная дата со временем | March 5, 2024 09:04 |
LLLL | она же с днём недели | Tuesday, March 5, 2024 09:04 |
Каждое имя из таблицы сочетается с остальными. LL [at] HH:mm даёт
March 5, 2024 at 00:00; именованные формы — не ключевые слова, работающие только
поодиночке.
Буква, похожая на токен, но токеном не являющаяся, — ошибка, а не текст. hh:mm A —
это 12-часовые часы и метка AM/PM из Moment, которых у TDC нет; раньше они печатали сами
себя — hh:00 A, — и прогон молчал. Теперь это не проходит check и говорит, что делать:
error[TDC152]: date format: "hh" is not a token — write it as [hh] if it is meant to be literal text
Обычные слова не затронуты — их буквы не входят в набор токенов: DD of MM по-прежнему
даёт 05 of 03. Всё, что нужно сохранить дословно, берите в скобки — это и так правило
ниже.
Имена месяцев и дней недели, а также четыре формы 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 никогда не зависят от локали — только от написанного вами
шаблона.
Откуда берутся слова: двадцать четыре локали встроены в движок, а любая другая, чей
пак данных возит DATE_LOCALE.json — таких семьдесят, — переводит свои даты, как
только пак виден. Грузинский, латышский, казахский и им подобные теперь печатают свои
месяцы и дни недели, включая падежную форму месяца в дате (15 იანვარს), — раньше они
молча падали в английский. Файл возит L и LL; LLL и LLLL берутся из него, если
записаны, и выводятся иначе — LL плюс время, день недели впереди. Локаль совсем без
слов дат по-прежнему печатает английский, и валидатор говорит об этом вслух, а не
пропускает молча.
Вот фиксированная дата 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. order="sequential"ОБХОДИТ диапазон; без него каждая строка — самостоятельный розыгрыш.- На обходимой оси
m— это минута, аmo— месяц.step="1mo15d"отвергается: пишите45dили1mo. weekdaysфильтрует,stepзадаёт темп. Они складываются, и одно не заменяет другое.today,now,value="birth"и генератор без границ читают часы, поэтому одним сидом их не воспроизвести — фиксируйте часы через--now.ofотсчитывает от другой колонки, аplusговорит насколько. Названная колонка должна быть объявлена выше, а атрибуты, ограничивающие собственный жребий генератора (from,to,value,range,order,step,oldest,youngest), рядом с ним отвергаются.- Смещение работает от даты, которую сгенерировала колонка-источник, а не от напечатанного
ею текста, поэтому подходят любой
formatи любая локаль. Только дата, которую TDC не генерировал — прочитанная из файла, — обязана быть в форме ISO. formatприменяется только к датам. На шаблонных идентификаторах (ИНН, СНИЛС, телефон…) это ошибка — оформляйте их фильтрами интерполяции.