Skip to content

This site describes solve-engine as it is on main: 2.43.0, which npm does not have yet. npm installs 2.40.0, so a page may show an answer that version does not give yet.

DATETIME_PACKAGE

const DATETIME_PACKAGE: IEnginePackage;

Defined in: packages/engine/src/packages/datetime/DatetimePackage.ts:131

Date/time keywords: now, today, tomorrow, yesterday, next <Weekday>/last <Weekday>, <unit> until <Datetime>/<unit> since <Datetime>. Uses the datetime arithmetic opcodes (DATE_ADD/DATE_SUB/DATE_NEXT_WEEKDAY/DATE_LAST_WEEKDAY) plus the shared UoM conversion opcode (UOM_CONVERT_IN) for until/since.

Also: workdays/weekdays and timestamps/ISO8601

  • workdays in <duration>. See WorkdaysInParselet.ts.
  • <date> + N workdays / <date> - N workdays, plain ”+”/”-” arithmetic, special-cased in vm/VM.ts’s ADD/SUB dispatch for the workday/workdays UNIT (see lexer/units.ts) since business-day math needs actual weekend-skipping, not a linear ms conversion.
  • N working/business days after|from|before <date>, the natural-language spelling of the same offset (5 working days after 20 Dec, 3 business days from today). Fused as INFIX phrase tokens (WORKDAYS_AFTER/WORKDAYS_BEFORE) since the count is the left operand; emits DATE_WORKDAY_OFFSET, which walks the very same addBusinessDays() as <date> + N workdays. See WorkdayOffsetParselet.ts.
  • working/business days between <date> and <date>, the COUNT of working days in the inclusive window (working days between 1 Jan and 31 Jan), the working-day sibling of <unit> between below. Emits DATE_WORKDAYS_BETWEEN. See WorkdaysBetweenParselet.ts.
  • <amount>/workday x <duration>, a Rate, exactly like $99/week already works, using uom/UomConverter.ts’s workday<->day shim so getMeasure()/convertUnit() treat “workday” as a Time-measure unit (5 workdays == 7 calendar days). See that file’s doc comment. The bare-denominator syntax $500/workday (no explicit “1”) additionally needs workdayRateDenominatorNormalizerRule. See its doc comment.
  • day of the week on <date> / weekday on <date>, and the natural-question forms over the same three date fields what day is it, what day is it on <date>, what day is it in <duration>, and the month/week equivalents. All one parselet, see DateFieldQueryParselet.ts. The same fields are also available composably as <date> as weekday / as month / as week via asConverters below.
  • <unit> between <date> and <date>, the two-explicit-endpoints sibling of until/since, see DurationBetweenParselet.ts. A leading how many is accepted for it and for until/since, see BetweenUnitNormalizerRule.ts.
  • <date> is a weekend / is a workday, postfix predicates, see DayTypePredicateParselet.ts. Mon-Fri only: these answer the week’s SHAPE (is this a weekday), which the holiday calendar deliberately does not touch, see the scope note below.
  • current timestamp / <date/time> to timestamp / <ISO8601 string or unix timestamp> to date. See CurrentTimestampParselet.ts / ToTimestampParselet.ts / ToDateParselet.ts and DatetimeTimestampPluginFunctions.ts.
  • Bare numeric date literals, 25/12/2023 (European DD/MM/YYYY) 12-25-2023 (US MM-DD-YYYY), 2023-12-25 (ISO YYYY-MM-DD), and 25.12.2023 (dot-separated DD.MM.YYYY), fused into a single DATETIME_LITERAL token by dateLiteralNormalizerRule() and pushed by DateLiteralParselet. Ported from the sibling feat/safety-limits-datetime-literals branch referenced in Iso8601.ts’s and the Stocks package’s DatePhrase.ts’s doc comments. This is that work, now merged.
  • <date/time> as iso8601, registered below via asConverters (the Converters package’s <expr> as <type> extension point, see api/PackageRegistry.ts’s doc comment) rather than a new opcode or a Converters-package-owned built-in name: asConverters already exists precisely for a third-party/domain package to contribute a new as <name> target without touching AsConverterParselet.ts or OpCode.ts at all, and “iso8601” is inherently a datetime-package concept (needs Iso8601.ts’s formatting, which already lives here) simpler to keep it self-contained in this package than to split the feature across two packages for a marginal “which package owns the converter-name list” tidiness gain.

SCOPE DECISION (holidays): the business-day WALK and COUNT (the offset forms, between, and <date> + N workdays) skip weekends always, and public holidays too when the host configures a calendar via date.holidays (see constants/Configuration.ts and vm/HolidayCalendar.ts). No calendar means weekends-only, the honest default: the engine excludes exactly the days it can prove are non-working. Picking a region’s holidays and keeping them current is the host’s to own, the same “bring your own data source” shape stocks and weather use, so this package never guesses a holiday the caller did not supply.

Two workday features stay weekends-only by design, and say so: workdays in <duration> (a deterministic ratio with no anchor date, so no calendar to consult, see WorkdaysInParselet.ts) and the is a weekend/is a workday predicates (which report the week’s Mon-Fri shape, a different question from “is this a working day here”). See vm/VM.ts’s addBusinessDays() for the walk’s side of this.