Files
skills/docs/foundation/data/templates/src/plugins/dynamic/DateTimePlugin.md
2026-05-29 08:20:56 +01:00

3.6 KiB

DateTimePlugin

Purpose

Injects current date and time values into templates using a flexible, token-based formatting syntax. Because date-time generation depends on the system clock, the plugin accepts an injectable Clock from @suaveplan/types so tests can produce deterministic output without real-time coupling. All four token types — date, time, datetime, and Unix timestamp — are handled by a single plugin instance to minimise regex passes per render.

Features

  • {_date} — current date formatted as YYYY-MM-DD.
  • {_date:YYYY/MM/DD} — custom date format using any combination of supported tokens.
  • {_time} — current time formatted as HH:mm:ss.
  • {_time:HH:mm} — custom time format.
  • {_datetime} — full datetime YYYY-MM-DD HH:mm:ss.
  • {_datetime:YYYY/MM/DD HH:mm} — custom datetime format.
  • {_timestamp} — Unix milliseconds as a decimal string.
  • {_timestamp:s} — Unix seconds (floored).
  • Format tokens: YYYY, MM, DD, HH, mm, ss, SSS.
  • Injectable Clock for deterministic testing.

Usage: Basic Example

import { TemplateEngine, createDateTimePlugin } from "@suaveplan/templates";

const engine = new TemplateEngine().use(createDateTimePlugin());

// Actual output depends on system time; shown illustratively
engine.parse("Today is {_date}", {});        // "Today is 2024-06-15"
engine.parse("Time: {_time}", {});           // "Time: 14:30:00"
engine.parse("Epoch: {_timestamp}", {});     // "Epoch: 1718451000000"

Usage: Advanced Example

import { TemplateEngine, createDateTimePlugin } from "@suaveplan/templates";
import type { Clock } from "@suaveplan/types";

// Deterministic clock for tests
const fixedClock: Clock = () => new Date("2024-06-15T14:30:00.500Z").getTime();

const engine = new TemplateEngine().use(createDateTimePlugin({ clock: fixedClock }));

engine.parse("{_date:YYYY/MM/DD}", {});
// → "2024/06/15"

engine.parse("{_datetime:DD-MM-YYYY HH:mm:ss}", {});
// → "15-06-2024 14:30:00"

engine.parse("{_timestamp:s}", {});
// → "1718459400"

API Reference

DateTimePluginOptions

Property Type Description
clock Clock (optional) Injectable clock; defaults to () => Date.now()

createDateTimePlugin<TContext>(opts?): Plugin<TContext>

Returns a Plugin with:

  • name: "datetime"
  • priority: PluginPriority.HIGH (80)
  • pattern: /\{_(date|time|datetime|timestamp)(?::([^}]+))?\}/g

The pattern captures two groups:

  1. Type keyword: date, time, datetime, or timestamp
  2. Optional format string or modifier (s for Unix seconds)

transform(match): Calls clock() to obtain the current epoch milliseconds, wraps it in a Date, and dispatches on the type keyword. Delegates formatting to formatDate(date, pattern). Returns the original match string for unrecognised type keywords (defensive — cannot occur given the pattern).

Implementation Notes

  • The Clock type from @suaveplan/types is defined as () => number, returning epoch milliseconds. The plugin wraps this with new Date(clock()) to feed formatDate.
  • formatDate performs simple token-by-token string replacement in a defined order (longest tokens first) so there is no ambiguity between MM and m characters in the pattern.
  • {_timestamp:s} uses Math.floor(now.getTime() / 1000) to truncate to seconds without rounding, matching the behaviour of POSIX time().
  • Runs at HIGH priority so date/time tokens are resolved before MEDIUM-priority transforms (which might want to further format the resulting string via CaseTransformPlugin).