{"_id":"@carl.fyi/format","name":"@carl.fyi/format","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@carl.fyi/format","version":"0.1.0","description":"Turn raw values into clear, human-readable numbers, money, file sizes, durations and dates.","type":"module","sideEffects":false,"license":"MIT","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./dates":{"types":"./dist/dates.d.ts","import":"./dist/dates.js"},"./format":{"types":"./dist/format.d.ts","import":"./dist/format.js"}},"gitHead":"8395ae726af204ee2590ca681a8076b73a31a8e7","_id":"@carl.fyi/format@0.1.0","_nodeVersion":"26.7.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-rSDL8P4ul0K6VabjSykz8qm9k/uXe5KIxKOnyFCl+DngKSBjCElMFd7OKguK/ZS0x9PRCr5XDqk54PJwjk4nmA==","shasum":"4473455931eb3804ba94079a3ed538ab28556a33","tarball":"https://registry.npmjs.org/@carl.fyi/format/-/format-0.1.0.tgz","fileCount":15,"unpackedSize":61319,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDmM6sSUpTQeJX1wStOM/yOEMgdFYWwtIJ6v7FK1eiIlAiBPE5GYfc4R0uDFwIvJNfvXQR8d1sw4aUVD8X3dbWyxfQ=="}]},"_npmUser":{"name":"carlfairclough","email":"hi@carlfairclough.me"},"directories":{},"maintainers":[{"name":"carlfairclough","email":"hi@carlfairclough.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/format_0.1.0_1787903733264_0.5926729520793677"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-28T07:55:33.098Z","0.1.0":"2026-08-28T07:55:33.405Z","modified":"2026-08-28T07:55:33.652Z"},"maintainers":[{"name":"carlfairclough","email":"hi@carlfairclough.me"}],"description":"Turn raw values into clear, human-readable numbers, money, file sizes, durations and dates.","license":"MIT","readme":"<!-- Generated from package.json and src TSDoc by scripts/generate-tool-documentation.mjs. Do not edit by hand. -->\n\n# @carl.fyi/format\n\nTurn raw values into clear, human-readable numbers, money, file sizes, durations and dates.\n\n[Interactive documentation](https://tools.carl.fyi/packages/format)\n\n## Install\n\n```sh\nnpm install @carl.fyi/format\n```\n\n## Quick start\n\n```ts\nimport { compactNumber } from \"@carl.fyi/format\";\n\ncompactNumber(1_250_000, { locale: \"en-US\" });\n// => \"1.3M\"\n```\n\n## Entry points\n\n| Import                    | Purpose                |\n| ------------------------- | ---------------------- |\n| `@carl.fyi/format`        | All public exports     |\n| `@carl.fyi/format/dates`  | Focused subpath import |\n| `@carl.fyi/format/format` | Focused subpath import |\n\nAll entry points are ESM, side-effect-free, and include TypeScript declarations.\n\n## Public API\n\nThis is the complete export inventory. The detailed reference below mirrors the APIs demonstrated on the documentation website; its signatures, descriptions, defaults, errors, and examples are compiled from the package source.\n\n| Export                   | Kind      | Import from               | Description                                                          |\n| ------------------------ | --------- | ------------------------- | -------------------------------------------------------------------- |\n| `dateFromPrefixedPath`   | function  | `@carl.fyi/format/dates`  | Parse a UTC date from a `YYMMDD-` or `YYMMDD_` path segment prefix.  |\n| `DateRangeOptions`       | interface | `@carl.fyi/format/dates`  | Options controlling concise date-range formatting.                   |\n| `dateToUnixSeconds`      | function  | `@carl.fyi/format/dates`  | Convert a valid date or millisecond timestamp to whole Unix seconds. |\n| `formatDateRange`        | function  | `@carl.fyi/format/dates`  | Format a month-and-year date range with an optional open end.        |\n| `unixMillisecondsToDate` | function  | `@carl.fyi/format/dates`  | Convert integer Unix milliseconds into a JavaScript date.            |\n| `unixSecondsToDate`      | function  | `@carl.fyi/format/dates`  | Convert integer Unix seconds into a JavaScript date.                 |\n| `ByteFormatOptions`      | interface | `@carl.fyi/format/format` | Options controlling byte-size formatting.                            |\n| `compactNumber`          | function  | `@carl.fyi/format/format` | Format a finite number with compact K, M, B, or T units.             |\n| `CompactNumberOptions`   | interface | `@carl.fyi/format/format` | Options controlling compact number formatting.                       |\n| `CurrencyOptions`        | interface | `@carl.fyi/format/format` | Options controlling localized currency formatting.                   |\n| `DurationOptions`        | interface | `@carl.fyi/format/format` | Options controlling elapsed-duration formatting.                     |\n| `formatBytes`            | function  | `@carl.fyi/format/format` | Format a non-negative byte count using decimal or binary units.      |\n| `formatCurrency`         | function  | `@carl.fyi/format/format` | Format a finite monetary value for a locale and currency.            |\n| `formatDuration`         | function  | `@carl.fyi/format/format` | Format a non-negative duration from milliseconds.                    |\n| `formatTimeAgo`          | function  | `@carl.fyi/format/format` | Describe a date relative to an injectable reference clock.           |\n| `TimeAgoOptions`         | interface | `@carl.fyi/format/format` | Options controlling relative-time formatting.                        |\n\n# API reference\n\n## `@carl.fyi/format/format`\n\n### `compactNumber`\n\n```ts\ncompactNumber(value: number, options?: CompactNumberOptions): string\n```\n\nFormat a finite number with compact K, M, B, or T units.\n\nValues are scaled in powers of 1,000, with promotion beginning at `999.5` so rounding does not produce results such as `1000K`. Values beyond trillions remain expressed in trillions. Locale behaviour is provided by `Intl`.\n\n| Parameter                                  | Type                   | Description                                                                              |\n| ------------------------------------------ | ---------------------- | ---------------------------------------------------------------------------------------- |\n| `value`                                    | `number`               | The finite number to format.                                                             |\n| `options (optional)`                       | `CompactNumberOptions` | Locale and fractional-digit behaviour.                                                   |\n| `options.locale (optional)`                | `string`               | Locale used by `Intl.NumberFormat`. Defaults to the runtime locale.                      |\n| `options.maximumFractionDigits (optional)` | `number`               | Maximum digits after the decimal point. Default: `one below 10 K/M/B/T, otherwise zero`. |\n\n**Returns:** A localized number followed by its compact unit when applicable.\n\n**Throws**\n\n- `TypeError` when `value` is not finite.\n- `RangeError` when `Intl` rejects the locale or digit bound.\n\n**Example**\n\n```ts\nimport { compactNumber } from \"@carl.fyi/format\";\n\ncompactNumber(1_250_000, { locale: \"en-US\" });\n// => \"1.3M\"\n```\n\n## `@carl.fyi/format/format`\n\n### `formatCurrency`\n\n```ts\nformatCurrency(value: number, options?: CurrencyOptions): string\n```\n\nFormat a finite monetary value for a locale and currency.\n\nVery small non-zero values retain up to six fractional digits by default; other values retain up to two. Currency codes and digit bounds are validated by the host `Intl.NumberFormat` implementation.\n\n| Parameter                                  | Type              | Description                                                          |\n| ------------------------------------------ | ----------------- | -------------------------------------------------------------------- |\n| `value`                                    | `number`          | The finite monetary amount to format.                                |\n| `options (optional)`                       | `CurrencyOptions` | Currency, locale, and fractional-digit behaviour.                    |\n| `options.currency (optional)`              | `string`          | ISO 4217 currency code. Default: `\"USD\"`.                            |\n| `options.locale (optional)`                | `string`          | Locale used by `Intl.NumberFormat`. Default: `\"en-US\"`.              |\n| `options.maximumFractionDigits (optional)` | `number`          | Maximum fractional digits. Default: `six below 0.01, otherwise two`. |\n| `options.minimumFractionDigits (optional)` | `number`          | Minimum fractional digits. Default: `0`.                             |\n\n**Returns:** A localized currency string.\n\n**Throws**\n\n- `TypeError` when `value` is not finite.\n- `RangeError` when `Intl` rejects the currency or digit bounds.\n\n**Example**\n\n```ts\nimport { formatCurrency } from \"@carl.fyi/format\";\n\nformatCurrency(12.5, { currency: \"GBP\", locale: \"en-GB\" });\n// => \"£12.5\"\n```\n\n## `@carl.fyi/format/format`\n\n### `formatBytes`\n\n```ts\nformatBytes(bytes: number, options?: ByteFormatOptions): string\n```\n\nFormat a non-negative byte count using decimal or binary units.\n\nBase 1,024 emits IEC units such as `KiB`; base 1,000 emits SI-style units such as `kB`. Values beyond the available units remain expressed in terabytes. This formats a count and does not inspect a file.\n\n| Parameter                                  | Type                | Description                                                          |\n| ------------------------------------------ | ------------------- | -------------------------------------------------------------------- |\n| `bytes`                                    | `number`            | The non-negative finite byte count.                                  |\n| `options (optional)`                       | `ByteFormatOptions` | Unit base, locale, and fractional-digit behaviour.                   |\n| `options.base (optional)`                  | `1000 \\| 1024`      | Decimal or binary unit base. Default: `1024`.                        |\n| `options.maximumFractionDigits (optional)` | `number`            | Maximum fractional digits. Default: `zero for bytes, otherwise one`. |\n| `options.locale (optional)`                | `string`            | Locale used by `Intl.NumberFormat`. Defaults to the runtime locale.  |\n\n**Returns:** A localized value and byte unit separated by a space.\n\n**Throws**\n\n- `RangeError` when `bytes` is negative or not finite.\n- `RangeError` when `Intl` rejects the locale or digit bound.\n\n**Example**\n\n```ts\nimport { formatBytes } from \"@carl.fyi/format\";\n\nformatBytes(1536);\n// => \"1.5 KiB\"\n```\n\n## `@carl.fyi/format/format`\n\n### `formatDuration`\n\n```ts\nformatDuration(milliseconds: number, options?: DurationOptions): string\n```\n\nFormat a non-negative duration from milliseconds.\n\nClock output includes years, weeks, and days when necessary and can retain the millisecond remainder. A year is a fixed 365-day elapsed-time unit, not a calendar year; a week is exactly seven days. Short output emits at most the two largest non-zero units and intentionally ignores `includeMilliseconds`. Set `showWeeks` or `showYears` to `false` to retain those spans in the next smaller enabled day-based unit.\n\n| Parameter                                | Type                 | Description                                                                 |\n| ---------------------------------------- | -------------------- | --------------------------------------------------------------------------- |\n| `milliseconds`                           | `number`             | The non-negative finite elapsed duration.                                   |\n| `options (optional)`                     | `DurationOptions`    | Output style and millisecond visibility.                                    |\n| `options.style (optional)`               | `\"clock\" \\| \"short\"` | Clock or compact unit output. Default: `\"clock\"`.                           |\n| `options.includeMilliseconds (optional)` | `boolean`            | Append a three-digit millisecond fraction in clock style. Default: `false`. |\n| `options.showWeeks (optional)`           | `boolean`            | Convert complete seven-day spans into weeks. Default: `true`.               |\n| `options.showYears (optional)`           | `boolean`            | Convert complete 365-day spans into fixed elapsed years. Default: `true`.   |\n\n**Returns:** A clock string or a compact two-unit duration.\n\n**Throws**\n\n- `RangeError` when `milliseconds` is negative or not finite.\n\n**Example**\n\n```ts\nimport { formatDuration } from \"@carl.fyi/format\";\n\nformatDuration(33_019_506_250, { includeMilliseconds: true });\n// => \"1y 2w 3d 04:05:06.250\"\n```\n\n## `@carl.fyi/format/format`\n\n### `formatTimeAgo`\n\n```ts\nformatTimeAgo(value: Date | number, options?: TimeAgoOptions): string\n```\n\nDescribe a date relative to an injectable reference clock.\n\nThe largest applicable unit from years through seconds is selected using fixed unit lengths. While there is one complete leading unit, a completed remainder is included (for example, 90 minutes becomes 1 hr, 30 min). From two leading units onward, the value is truncated (2 hr, 15 min becomes 2 hours). Inject `now` for deterministic output; this is a human-readable approximation, not calendar math.\n\n| Parameter                    | Type                             | Description                                                                      |\n| ---------------------------- | -------------------------------- | -------------------------------------------------------------------------------- |\n| `value`                      | `Date \\| number`                 | The target date or millisecond timestamp.                                        |\n| `options (optional)`         | `TimeAgoOptions`                 | Reference clock, locale, and numeric wording.                                    |\n| `options.now (optional)`     | `Date \\| number`                 | Reference clock as a date or millisecond timestamp. Default: `Date.now()`.       |\n| `options.locale (optional)`  | `string`                         | Locale used by `Intl.RelativeTimeFormat`. Defaults to the runtime locale.        |\n| `options.numeric (optional)` | `Intl.RelativeTimeFormatNumeric` | Whether terms such as “yesterday” may replace numeric output. Default: `\"auto\"`. |\n\n**Returns:** A localized relative-time phrase.\n\n**Throws**\n\n- `TypeError` when the target or reference date is invalid.\n- `RangeError` when `Intl` rejects the locale or numeric option.\n\n**Example**\n\n```ts\nimport { formatTimeAgo } from \"@carl.fyi/format\";\n\nformatTimeAgo(Date.UTC(2026, 7, 25), { now: Date.UTC(2026, 7, 26), locale: \"en\" });\n// => \"yesterday\"\n```\n\n## `@carl.fyi/format/dates`\n\n### `unixSecondsToDate`\n\n```ts\nunixSecondsToDate(seconds: number | bigint): Date\n```\n\nConvert integer Unix seconds into a JavaScript date.\n\nNumber and bigint inputs must fit JavaScript's safe integer range before conversion. The resulting millisecond timestamp must also fit the supported `Date` range. No timezone conversion is performed.\n\n| Parameter | Type               | Description                           |\n| --------- | ------------------ | ------------------------------------- |\n| `seconds` | `number \\| bigint` | Integer seconds since the Unix epoch. |\n\n**Returns:** A date representing the exact Unix timestamp.\n\n**Throws**\n\n- `RangeError` when the input is unsafe, non-integral, or outside the supported `Date` range.\n\n**Example**\n\n```ts\nimport { unixSecondsToDate } from \"@carl.fyi/format\";\n\nunixSecondsToDate(1_787_745_600n).toISOString();\n// => \"2026-08-26T12:00:00.000Z\"\n```\n\n## `@carl.fyi/format/dates`\n\n### `formatDateRange`\n\n```ts\nformatDateRange(start: Date | string, end: Date | string | null, options?: DateRangeOptions): string\n```\n\nFormat a month-and-year date range with an optional open end.\n\nString inputs use the JavaScript `Date` parser, then formatting is fixed to UTC. Equal formatted endpoints collapse to one label. A `null` end uses the configured present label; this is formatting, not duration calculation.\n\n| Parameter                         | Type                     | Description                                               |\n| --------------------------------- | ------------------------ | --------------------------------------------------------- |\n| `start`                           | `Date \\| string`         | Inclusive range start as a date or parseable date string. |\n| `end`                             | `Date \\| string \\| null` | Range end, or `null` for an ongoing range.                |\n| `options (optional)`              | `DateRangeOptions`       | Locale, present label, and month width.                   |\n| `options.locale (optional)`       | `string`                 | Locale used by `Intl.DateTimeFormat`. Default: `\"en\"`.    |\n| `options.presentLabel (optional)` | `string`                 | Label used when `end` is `null`. Default: `\"Present\"`.    |\n| `options.month (optional)`        | `\"short\" \\| \"long\"`      | Month-name width. Default: `\"short\"`.                     |\n\n**Returns:** A single month label or two labels separated by an en dash.\n\n**Throws**\n\n- `TypeError` when either supplied date is invalid.\n- `RangeError` when `Intl` rejects the locale or month option.\n\n**Example**\n\n```ts\nimport { formatDateRange } from \"@carl.fyi/format\";\n\nformatDateRange(\"2024-01-01\", null, { locale: \"en-GB\" });\n// => \"Jan 2024 – Present\"\n```\n\n### `dateFromPrefixedPath`\n\n```ts\ndateFromPrefixedPath(path: string, pivotYear?: number): Date | null\n```\n\nParse a UTC date from a `YYMMDD-` or `YYMMDD_` path segment prefix.\n\nThe first matching path segment is used. Two-digit years at or above the pivot map to 19xx; lower years map to 20xx. Invalid calendar dates return `null`, and the function does not access the filesystem.\n\n| Parameter              | Type     | Description                                                |\n| ---------------------- | -------- | ---------------------------------------------------------- |\n| `path`                 | `string` | A slash-delimited path or filename to inspect.             |\n| `pivotYear (optional)` | `number` | First two-digit year assigned to the 1900s. Default: `70`. |\n\n**Returns:** The parsed midnight UTC date, or `null` when no valid prefix exists.\n\n**Example**\n\n```ts\nimport { dateFromPrefixedPath } from \"@carl.fyi/format\";\n\ndateFromPrefixedPath(\"writing/260826-tools.mdx\")?.toISOString();\n// => \"2026-08-26T00:00:00.000Z\"\n```\n\n## License\n\n[MIT](./LICENSE)\n","readmeFilename":"README.md","_rev":"1-d72626cba0e22f81723db8a7e7fdbcde"}