### Install rosetta-date with bun Source: https://rosetta-date.dev/getting-started/installation Use this command to install rosetta-date as a dependency in your project using bun. ```bash bun add rosetta-date ``` -------------------------------- ### Install rosetta-date with pnpm Source: https://rosetta-date.dev/getting-started/installation Use this command to install rosetta-date as a dependency in your project using pnpm. ```bash pnpm add rosetta-date ``` -------------------------------- ### Clone, install, and set up rosetta-date Source: https://rosetta-date.dev/contributing Run these commands to clone the repository, enter the project directory, and install dependencies with pnpm. Requires Node ≥ 22 and pnpm. ```bash git clone https://github.com/JoaoPedroAS51/rosetta-date.git cd rosetta-date pnpm install ``` -------------------------------- ### explain usage example with dayjs and momentjs libraries Source: https://rosetta-date.dev/reference/api Example of using explain to check if 'DDD' can be converted from momentjs to dayjs, returning an unsupported status. ```typescript import { explain } from 'rosetta-date' import { dayjs, momentjs } from 'rosetta-date/libraries' explain('DDD', { from: momentjs, to: dayjs }) // [ { kind: 'field', token: 'DDD', canonical: 'day-of-year/numeric', field: 'day-of-year', style: 'numeric', qualifiers: [], status: 'unsupported', reason: 'unsupported-by-target' } ] ``` -------------------------------- ### Install rosetta-date with npm Source: https://rosetta-date.dev/getting-started/installation Use this command to install rosetta-date as a dependency in your project using npm. ```bash npm install rosetta-date ``` -------------------------------- ### Install rosetta-date with yarn Source: https://rosetta-date.dev/getting-started/installation Use this command to install rosetta-date as a dependency in your project using yarn. ```bash yarn add rosetta-date ``` -------------------------------- ### describe usage example with moment dialect Source: https://rosetta-date.dev/reference/api Example of using describe with the moment dialect to parse 'DD/MM' and return segments with canonical tokens. ```typescript import { describe } from 'rosetta-date' import { moment } from 'rosetta-date/dialects' describe('DD/MM', moment) // [ { kind: 'field', token: 'DD', canonical: 'day-of-month/2-digit', field: 'day-of-month', style: '2-digit', qualifiers: [] }, // { kind: 'literal', value: '/' }, // { kind: 'field', token: 'MM', canonical: 'month/2-digit', field: 'month', style: '2-digit', qualifiers: [] } ] ``` -------------------------------- ### toIntlOptions: Unsupported token handling Source: https://rosetta-date.dev/guides/intl Shows how unsupported tokens are handled. The first example drops the quarter token, the second throws an UnsupportedTokenError when onUnsupportedToken is set to 'throw'. ```javascript toIntlOptions('[Q]Q YYYY', { from: moment }) // { year: 'numeric' } — quarter dropped toIntlOptions('Q', { from: moment, onUnsupportedToken: 'throw' }) // throws UnsupportedTokenError ``` -------------------------------- ### createConverter usage example Source: https://rosetta-date.dev/reference/api Example usage of createConverter. Creates a reusable converter from moment to ldml and applies it to a token string. ```typescript import { createConverter } from 'rosetta-date' import { ldml, moment } from 'rosetta-date/dialects' const toLdml = createConverter(moment, ldml) toLdml('YYYY-MM-DD') // 'yyyy-MM-dd' ``` -------------------------------- ### Convert between libraries (momentjs to dateFns) Source: https://rosetta-date.dev/concepts/dialects-and-libraries Uses a Library to model tool-specific behavior, flagging unrenderable tokens via onUnsupportedToken. The example converts 'DD/MM/YYYY' from momentjs to dateFns, resulting in 'dd/MM/yyyy'. ```typescript import { convert } from 'rosetta-date' import { dateFns, momentjs } from 'rosetta-date/libraries' convert('DD/MM/YYYY', { from: momentjs, to: dateFns }) // 'dd/MM/yyyy' ``` -------------------------------- ### fromIntlOptions: Component bag to skeleton Source: https://rosetta-date.dev/guides/intl Converts a component bag to a skeleton pattern. The example shows year, month, and day with the ldml target, producing 'yyyyMMdd'. ```javascript fromIntlOptions({ year: 'numeric', month: '2-digit', day: '2-digit' }, { to: ldml }) // 'yyyyMMdd' ``` -------------------------------- ### fromIntlOptions: Convert Intl options to pattern Source: https://rosetta-date.dev/guides/intl Converts Intl options to a pattern using the style axis. The example shows dateStyle and timeStyle with the dayjs library, returning preset tokens like 'L' and 'LLL'. ```javascript import { fromIntlOptions } from 'rosetta-date/intl' import { dayjs } from 'rosetta-date/libraries' fromIntlOptions({ dateStyle: 'short' }, { to: dayjs }) // 'L' fromIntlOptions({ dateStyle: 'long', timeStyle: 'long' }, { to: dayjs }) // 'LLL' ``` -------------------------------- ### Mix dialect and library (moment to dateFns) Source: https://rosetta-date.dev/concepts/dialects-and-libraries Shows mixing endpoint types: converting from a bare dialect (moment) into a specific library (dateFns). The example converts 'YYYY-MM-DD' to 'yyyy-MM-dd'. ```typescript import { convert } from 'rosetta-date' import { moment } from 'rosetta-date/dialects' import { dateFns } from 'rosetta-date/libraries' convert('YYYY-MM-DD', { from: moment, to: dateFns }) // 'yyyy-MM-dd' ``` -------------------------------- ### toIntlOptions: Convert pattern to Intl options Source: https://rosetta-date.dev/guides/intl Converts a format string to an Intl.DateTimeFormat options bag. The example shows 'YYYY-MM-DD HH:mm' with the moment dialect, producing options with hourCycle 'h23'. ```javascript import { toIntlOptions } from 'rosetta-date/intl' import { moment } from 'rosetta-date/dialects' const options = toIntlOptions('YYYY-MM-DD HH:mm', { from: moment }) // { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' } new Intl.DateTimeFormat('pt-BR', options).format(new Date()) ``` -------------------------------- ### Convert between dialects (moment to ldml) Source: https://rosetta-date.dev/concepts/dialects-and-libraries Uses a Dialect for pure grammar conversion, rewriting tokens without tool-specific behavior. The example converts 'DD/MM/YYYY' from moment to ldml, resulting in 'dd/MM/yyyy'. ```typescript import { convert } from 'rosetta-date' import { ldml, moment } from 'rosetta-date/dialects' convert('DD/MM/YYYY', { from: moment, to: ldml }) // 'dd/MM/yyyy' ``` -------------------------------- ### toIntlOptions: 12-hour pattern with moment Source: https://rosetta-date.dev/guides/intl Converts a 12-hour format string to Intl options. The example shows 'h:mm A' with the moment dialect, producing hourCycle 'h12'. The AM/PM marker is dropped by design. ```javascript import { toIntlOptions } from 'rosetta-date/intl' import { moment } from 'rosetta-date/dialects' toIntlOptions('h:mm A', { from: moment }) // { hour: 'numeric', minute: '2-digit', hourCycle: 'h12' } ``` -------------------------------- ### describe: parse a date format into field and literal segments Source: https://rosetta-date.dev/guides/describe Call describe with a format string and a moment dialect to get an array of field and literal objects for each token. The output preserves order and covers every character, including literals. Requires importing describe from 'rosetta-date' and moment from 'rosetta-date/dialects'. ```JavaScript import { describe } from 'rosetta-date' import { moment } from 'rosetta-date/dialects' describe('DD/MM', moment) // [ // { kind: 'field', token: 'DD', canonical: 'day-of-month/2-digit', field: 'day-of-month', style: '2-digit', qualifiers: [] }, // { kind: 'literal', value: '/' }, // { kind: 'field', token: 'MM', canonical: 'month/2-digit', field: 'month', style: '2-digit', qualifiers: [] }, // ] ``` -------------------------------- ### explain Source: https://rosetta-date.dev/reference/api Performs a read-only dry run of `convert`, reporting per field whether the target can render it and why not if it cannot. ```APIDOC ## `explain` ### Description Performs a read-only dry run of `convert`, reporting per field whether the target can render it and why not if it cannot. Builds on `describe`. ### Function Signature ```typescript function explain(format: string, options: ExplainOptions): ExplainedSegment[] ``` ### Parameters - **format** (string) - Required - The format string to explain. - **options** (ExplainOptions) - Required - An object containing `from` and `to` properties specifying the source and target dialects or libraries. ### Returns - **ExplainedSegment[]** - An array of explained segments, each indicating conversion status and reason if unsupported. ### Example ```typescript import { explain } from 'rosetta-date' import { dayjs, momentjs } from 'rosetta-date/libraries' explain('DDD', { from: momentjs, to: dayjs }) // [ { kind: 'field', token: 'DDD', canonical: 'day-of-year/numeric', field: 'day-of-year', style: 'numeric', qualifiers: [], status: 'unsupported', reason: 'unsupported-by-target' } ] ``` ### Type Definitions ```typescript interface ExplainOptions { readonly from: Dialect | Library readonly to: Dialect | Library } // The subset of `UnsupportedTokenReason` a per-token `explain` can produce. type ExplainedReason = 'unmappable' | 'unsupported-by-target' type ExplainedField = DescribedField & ( | { readonly status: 'converted', readonly target: string } | { readonly status: 'unsupported', readonly reason: ExplainedReason } ) type ExplainedSegment = | { readonly kind: 'literal', readonly value: string } | ExplainedField | { readonly kind: 'unknown', readonly value: string } ``` ``` -------------------------------- ### Convert between libraries Source: https://rosetta-date.dev/getting-started/quick-start Demonstrates converting between momentjs and dateFns libraries. The conversion reads naturally from one library to another. ```typescript import { convert } from 'rosetta-date' import { dateFns, momentjs } from 'rosetta-date/libraries' // Library → library reads like the intent: convert('DD/MM/YYYY', { from: momentjs, to: dateFns }) // 'dd/MM/yyyy' ``` -------------------------------- ### Create a changeset Source: https://rosetta-date.dev/contributing Run pnpm changeset to record user-facing changes. CI runs lint, typecheck, test:coverage, and build on every pull request. ```bash pnpm changeset ``` -------------------------------- ### fromIntlOptions usage with dayjs Source: https://rosetta-date.dev/reference/api Example usage of fromIntlOptions with the dayjs library. The dateStyle 'short' maps to the token 'L'. ```typescript import { fromIntlOptions } from 'rosetta-date/intl' import { dayjs } from 'rosetta-date/libraries' fromIntlOptions({ dateStyle: 'short' }, { to: dayjs }) // 'L' ``` -------------------------------- ### toIntlOptions usage with moment Source: https://rosetta-date.dev/reference/api Example usage of toIntlOptions with the moment dialect. The format 'YYYY-MM-DD' maps to an options object with year, month, and day components. ```typescript import { toIntlOptions } from 'rosetta-date/intl' import { moment } from 'rosetta-date/dialects' toIntlOptions('YYYY-MM-DD', { from: moment }) // { year: 'numeric', month: '2-digit', day: '2-digit' } ``` -------------------------------- ### Import dateFns from rosetta-date/libraries Source: https://rosetta-date.dev/reference/libraries/datefns Shows how to import the dateFns rendering target from the rosetta-date library. ```javascript import { dateFns } from 'rosetta-date/libraries' ``` -------------------------------- ### Import momentjs from rosetta-date/libraries Source: https://rosetta-date.dev/reference/libraries/momentjs Imports the momentjs rendering target from the rosetta-date library. This is the entry point for using the momentjs target in your code. ```javascript import { momentjs } from 'rosetta-date/libraries' ``` -------------------------------- ### fromIntlOptions Source: https://rosetta-date.dev/reference/api Translates Intl options into a target's tokens. dateStyle/timeStyle map to localized presets; components reconstruct a CLDR-canonical-order skeleton. ```APIDOC ## fromIntlOptions ### Description Translates Intl options into a target's tokens. `dateStyle` / `timeStyle` map to the target's localized presets; components reconstruct a CLDR-canonical-order skeleton. ### Function Signature ```typescript function fromIntlOptions(intlOptions: Intl.DateTimeFormatOptions, options: FromIntlOptions): string ``` ### Parameters - **intlOptions** (`Intl.DateTimeFormatOptions`) - Required - The Intl options to convert. - **options** (`FromIntlOptions`) - Required - Options object containing the target dialect or library and unsupported token policy. ### Example ```typescript import { fromIntlOptions } from 'rosetta-date/intl' import { dayjs } from 'rosetta-date/libraries' fromIntlOptions({ dateStyle: 'short' }, { to: dayjs }) // 'L' ``` ### Returns - **string** - The token string for the target dialect or library. ``` -------------------------------- ### Import moment dialect from rosetta-date/dialects Source: https://rosetta-date.dev/reference/dialects/moment Import the Moment.js-style token grammar from the rosetta-date dialects package. This is the entry point for using the moment dialect in your project. ```javascript import { moment } from 'rosetta-date/dialects' ``` -------------------------------- ### Import dayjs from rosetta-date/libraries Source: https://rosetta-date.dev/reference/libraries/dayjs Import the Day.js rendering target from the rosetta-date library. This is the entry point for using Day.js as the target in rosetta-date. ```javascript import { dayjs } from 'rosetta-date/libraries' ``` -------------------------------- ### decodeCanonical: decode a canonical token directly Source: https://rosetta-date.dev/guides/describe When you already have a CanonicalToken, decodeCanonical returns the same field, style, and qualifiers split without a format string. Pass a canonical constant, like Canonical.WeekOfYearOrdinalIso, to get its decoded parts. ```JavaScript import { Canonical, decodeCanonical } from 'rosetta-date' decodeCanonical(Canonical.WeekOfYearOrdinalIso) // { field: 'week-of-year', style: 'ordinal', qualifiers: ['iso'] } ``` -------------------------------- ### Import and convert between strftime and moment dialects Source: https://rosetta-date.dev/reference/dialects/strftime Shows how to import the strftime dialect and convert between strftime and moment token formats using the convert function from rosetta-date. ```javascript import { convert } from 'rosetta-date' import { moment, strftime } from 'rosetta-date/dialects' convert('%Y-%m-%d', { from: strftime, to: moment }) // 'YYYY-MM-DD' convert('DD/MM/YYYY', { from: moment, to: strftime }) // '%d/%m/%Y' ``` -------------------------------- ### Convert Moment.js format to LDML with rosetta-date Source: https://rosetta-date.dev/ Converts a Moment.js date format string to an LDML format string using the `convert` function and the `moment` and `ldml` dialects. The example shows that `YYYY-MM-DD` becomes `yyyy-MM-dd`, demonstrating that the library rewrites tokens, not the date. ```javascript import { convert } from 'rosetta-date' import { ldml, moment } from 'rosetta-date/dialects' convert('YYYY-MM-DD', { from: moment, to: ldml }) // 'yyyy-MM-dd' ``` -------------------------------- ### Migrate Moment.js format to date-fns with rosetta-date Source: https://rosetta-date.dev/ Migrates a Moment.js format string to a date-fns format string using the `convert` function and the `momentjs` and `dateFns` libraries. The example shows that `dddd, MMMM Do YYYY` becomes `EEEE, MMMM do yyyy`, illustrating a typical migration scenario. ```javascript import { convert } from 'rosetta-date' import { dateFns, momentjs } from 'rosetta-date/libraries' convert('dddd, MMMM Do YYYY', { from: momentjs, to: dateFns }) // 'EEEE, MMMM do yyyy' ``` -------------------------------- ### explain types: ExplainOptions, ExplainedReason, ExplainedField, ExplainedSegment Source: https://rosetta-date.dev/reference/api TypeScript interfaces and type aliases for the options and return types of the explain function. ```typescript interface ExplainOptions { readonly from: Dialect | Library readonly to: Dialect | Library } // The subset of `UnsupportedTokenReason` a per-token `explain` can produce. type ExplainedReason = 'unmappable' | 'unsupported-by-target' type ExplainedField = DescribedField & ( | { readonly status: 'converted', readonly target: string } | { readonly status: 'unsupported', readonly reason: ExplainedReason } ) type ExplainedSegment = | { readonly kind: 'literal', readonly value: string } | ExplainedField | { readonly kind: 'unknown', readonly value: string } ``` -------------------------------- ### explain() with converted fields Source: https://rosetta-date.dev/guides/explain Shows the diagnostic output for a conversion that keeps both fields: each token is classified as 'converted' and the target token spelling is provided. Literals pass through unchanged. ```javascript import { explain } from 'rosetta-date' import { ldml, moment } from 'rosetta-date/dialects' explain('DD/MM', { from: moment, to: ldml }) // [ { kind: 'field', token: 'DD', canonical: 'day-of-month/2-digit', ..., status: 'converted', target: 'dd' }, // { kind: 'literal', value: '/' }, // { kind: 'field', token: 'MM', canonical: 'month/2-digit', ..., status: 'converted', target: 'MM' } ] ``` -------------------------------- ### Configure onUnsupportedToken with presets or a handler Source: https://rosetta-date.dev/guides/unsupported-tokens Shows the three ways to set onUnsupportedToken: the default 'literalize' preset, the 'throw' preset, and a custom handler that inspects info.reason. The handler returns Unsupported.drop or Unsupported.literalize sentinels; the default policy never throws. ```javascript import { convert, Unsupported, UnsupportedTokenError } from 'rosetta-date' import { ldml, moment } from 'rosetta-date/dialects' // 'literalize' (default) — escape it as a literal, so it can never be re-read as a token: convert('K', { from: ldml, to: moment }) // '[K]' // 'throw' — fail fast (handy for migrations / validation): convert('K', { from: ldml, to: moment, onUnsupportedToken: 'throw' }) // throws UnsupportedTokenError // handler — decide per token, keyed on `info.reason` (the reasons are listed below): convert('K', { from: ldml, to: moment, onUnsupportedToken: (token, info) => info.reason === 'unmappable' ? Unsupported.drop : Unsupported.literalize, }) ``` -------------------------------- ### moment Source: https://rosetta-date.dev/reference/api Built-in dialect for moment. ```APIDOC ## moment ### Description Built-in dialect for moment. ### Type `Dialect` ``` -------------------------------- ### Perform one-off conversions with convert and dialects Source: https://rosetta-date.dev/getting-started/quick-start Imports convert and dialects to perform one-off conversion between moment and ldml formats. The from and to options determine the direction. ```typescript import { convert } from 'rosetta-date' import { ldml, moment } from 'rosetta-date/dialects' convert('DD/MM/YYYY', { from: moment, to: ldml }) // 'dd/MM/yyyy' convert('yyyy-MM-dd', { from: ldml, to: moment }) // 'YYYY-MM-DD' ``` -------------------------------- ### createConverter with onUnsupportedToken: 'throw' Source: https://rosetta-date.dev/guides/converting Opt into `onUnsupportedToken: 'throw'` when validating or running a mass migration and you want failures to surface. The default policy never throws. ```javascript import { createConverter } from 'rosetta-date' import { dayjs, momentjs } from 'rosetta-date/libraries' const safe = createConverter(momentjs, dayjs, { onUnsupportedToken: 'throw' }) ``` -------------------------------- ### UnsupportedTokenInfo Source: https://rosetta-date.dev/reference/api Information passed to an unsupported token handler: { reason, from, to, fromLibrary?, toLibrary? }. ```APIDOC ## UnsupportedTokenInfo ### Description Information passed to an unsupported token handler: `{ reason, from, to, fromLibrary?, toLibrary? }`. ### Fields - `reason` - Reason for unsupported token - `from` - Source token - `to` - Target token - `fromLibrary?` - Optional source library - `toLibrary?` - Optional target library ``` -------------------------------- ### Import built-in libraries from rosetta-date/libraries Source: https://rosetta-date.dev/reference/libraries Imports the built-in libraries dateFns, dayjs, and momentjs from the 'rosetta-date/libraries' module. Use this to access the built-in library objects for conversion. ```javascript import { dateFns, dayjs, momentjs } from 'rosetta-date/libraries' ``` -------------------------------- ### Narrow a tool's rendering with supports Source: https://rosetta-date.dev/guides/custom-dialects Defines a library that narrows the moment dialect to a subset of fields using the 'supports' set. Unsupported fields like month ordinal are flagged with brackets in the output. ```javascript import { Canonical, convert, defineLibrary } from 'rosetta-date' import { moment } from 'rosetta-date/dialects' const dayjsLike = defineLibrary({ name: 'dayjs-like', dialect: moment, supports: new Set([Canonical.YearNumeric, Canonical.MonthTwoDigit, Canonical.DayOfMonthTwoDigit]), }) convert('MM', { from: moment, to: dayjsLike }) // 'MM' — a supported field convert('Mo', { from: moment, to: dayjsLike }) // '[Mo]' — month ordinal isn't in `supports`, so it's flagged ``` -------------------------------- ### Import built-in dialects from rosetta-date/dialects Source: https://rosetta-date.dev/reference/dialects Imports the built-in dialects from the rosetta-date/dialects module. This is the entry point for using the moment, ldml, and strftime dialects in your code. ```javascript import { ldml, moment, strftime } from 'rosetta-date/dialects' ``` -------------------------------- ### createConverter Source: https://rosetta-date.dev/reference/api Binds a fixed direction once and returns a reusable Converter. ```APIDOC ## createConverter ### Description Binds a fixed direction once and returns a reusable Converter. ### Method function ### Endpoint createConverter( from: Dialect | Library, to: Dialect | Library, options?: ConverterOptions, ): Converter ### Parameters #### Parameters - **from** (Dialect | Library) - Required - The source dialect or library. - **to** (Dialect | Library) - Required - The target dialect or library. - **options** (ConverterOptions) - Optional - Additional options for the converter. ### Request Example ```typescript import { createConverter } from 'rosetta-date' import { ldml, moment } from 'rosetta-date/dialects' const toLdml = createConverter(moment, ldml) toLdml('YYYY-MM-DD') // 'yyyy-MM-dd' ``` ### Response #### Success Response - **Converter** - A reusable converter function. #### Response Example ```typescript const toLdml = createConverter(moment, ldml) ``` ``` -------------------------------- ### describe Source: https://rosetta-date.dev/reference/api Parses a format string and returns its segments with canonical semantics. This is the read-only counterpart to `convert`. ```APIDOC ## `describe` ### Description Parses a format string and returns its segments with canonical semantics. This is the read-only counterpart to `convert`. ### Function Signature ```typescript function describe(format: string, endpoint: Dialect | Library): DescribedSegment[] ``` ### Parameters - **format** (string) - Required - The format string to parse. - **endpoint** (Dialect | Library) - Required - The dialect or library to use for parsing. ### Returns - **DescribedSegment[]** - An array of described segments, each representing a field, literal, or unknown token. ### Example ```typescript import { describe } from 'rosetta-date' import { moment } from 'rosetta-date/dialects' describe('DD/MM', moment) // [ { kind: 'field', token: 'DD', canonical: 'day-of-month/2-digit', field: 'day-of-month', style: '2-digit', qualifiers: [] }, // { kind: 'literal', value: '/' }, // { kind: 'field', token: 'MM', canonical: 'month/2-digit', field: 'month', style: '2-digit', qualifiers: [] } ] ``` ```