https://github.com/porsager/datie
Small template string based date formatter for the browser and Node.js.
https://github.com/porsager/datie
date formatter
Last synced: 11 days ago
JSON representation
Small template string based date formatter for the browser and Node.js.
- Host: GitHub
- URL: https://github.com/porsager/datie
- Owner: porsager
- License: wtfpl
- Created: 2020-05-13T08:44:17.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2025-09-02T21:27:05.000Z (about 1 month ago)
- Last Synced: 2025-09-02T23:20:28.100Z (about 1 month ago)
- Topics: date, formatter
- Language: JavaScript
- Size: 13.7 KB
- Stars: 16
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# π Datie
Small template string based date formatter for the browser and Node.js. It supports custom specifiers and relative time calculations without external libraries. Datie is lightweight (~1KB minified) and caches formatters for performance.
### LDML Compliance
Follows Unicode LDML date patterns (https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table) with additions:
- `o`: Ordinal suffix (e.g., `1st`, `2nd`) for numbers like day or month.
- `R`: Relative time (e.g., `1 minute ago`, `in 2 days`).# Usage
Datie uses tagged template literals to define formats, returning a reusable function that accepts a Date object or compatible string. Formatters are cached by string.
```js
import d from 'datie'const string = '2020-05-13T08:34:30.911Z'
const date = new Date(string)d`d/M-y hh:mm`(string) // '13/5-2020 08:34'
d`d/M-y hh:mm`(date) // '13/5-2020 08:34'
```## Supported Specifiers
Comprehensive list of format specifiers, with descriptions and examples (using July 19, 2025, Saturday, 12:34:56):
- **Year**:
- `y` / `yyyy`: Full year β '2025'
- `yy`: Two-digit year β '25'- **Month**:
- `M`: Month number (1-12) β '7'
- `MM`: Padded month (01-12) β '07'
- `MMM`: Abbreviated month β 'Jul'
- `MMMM`: Full month β 'July'
- `MMMMM`: Narrow month (first letter) β 'J'- **Day**:
- `d`: Day of month (1-31) β '19'
- `dd`: Padded day (01-31) β '19'- **Weekday**:
- `e`: Weekday number (0=Sun-6=Sat) β '6'
- `ee`: Padded weekday number β '06'
- `E` / `EE` / `EEE`: Abbreviated weekday β 'Sat'
- `EEEE`: Full weekday β 'Saturday'
- `EEEEE`: Narrow weekday β 'Sa'
- `EEEEEE`: Shortest weekday β 'S'- **Hour** (24-hour; `h`/`hh` aliases `H`/`HH`; no AM/PM):
- `H` / `h`: Hour (0-23) β '12'
- `HH` / `hh`: Padded hour β '12'- **Minute**:
- `m`: Minute (0-59) β '34'
- `mm`: Padded minute β '34'- **Second**:
- `s`: Second (0-59) β '56'
- `ss`: Padded second β '56'- **Week** (ISO week, Thursday-based):
- `w`: Week of year (1-53) β '29'
- `ww`: Padded week β '29'- **Quarter**:
- `Q`: Quarter (1-4) β '3'
- `QQ`: Padded quarter β '03'
- `QQQ`: Prefixed quarter β 'Q3'
- `QQQQ`: Full with ordinal β '3rd quarter'- **Ordinal Suffix**:
- `o`: Suffix for prior number (e.g., `do` β '19th', `Qo` β '3rd')## Relative Time Formatting
Use `R` for relative time vs. current time (`new Date()`). Handles past (`ago`) and future (`in`), with pluralization and `<5s` as `a few seconds ago`/`in a few seconds`. Threshold for `now` is under 5 seconds.
There is an optional 2nd parameter accepted if you want to provide a different reference point instead of Date.now().
Examples (assuming current time is July 22, 2025, 12:00:00):
```js
const reference = new Date('2025-07-22T11:55:00')
const pastDate = reference.getTime() - 1000 * 60 * 5 // 5 minutes ago
const futureDate = reference.getTime() + 1000 * 60 * 10 // 10 minutes futured`R`(pastDate, reference) // '5 minutes ago'
d`R`(futureDate, reference) // 'in 10 minutes'
d`R`(new Date()) // 'now' (or 'a few seconds ago' if slight offset)
```## Relative Fallbacks
Combine relative time with a fallback format using thresholds. If the date is within the spec (past or future), show relative; else, use fallback.
- **Syntax**:
- Past: `R ` (e.g., `R1D yyyy-MM-dd`) β Relative if past and within spec.
- Future: ` R` (e.g., `yyyy-MM-dd R1Y`) β Relative if future and within spec.
- **Spec**: `[unit]`; units: `m` (minutes, default), `H` (hours), `D` (days), `M` (months), `Y` (years). No spec = always relative (threshold Infinity).Examples (current: July 22, 2025, 12:00:00):
```js
// Past fallback
const recentPast = new Date('2025-07-22T11:00:00') // 1 hour ago
const oldPast = new Date('2025-07-20T12:00:00') // >1 day agod`R1D yyyy-MM-dd HH:mm`(recentPast) // '1 hour ago'
d`R1D yyyy-MM-dd HH:mm`(oldPast) // '2025-07-20 12:00'// Future fallback
const nearFuture = new Date('2025-07-22T15:00:00') // 3 hours future
const farFuture = new Date('2025-08-22T12:00:00') // >15 days futured`yyyy-MM-dd HH:mm R3H`(nearFuture) // 'in 3 hours'
d`yyyy-MM-dd HH:mm R3H`(farFuture) // '2025-08-22 12:00'// Other specs
d`yyyy-MM-dd R15D`(farFuture) // '2025-08-22' (31 days >15D)
d`yyyy-MM-dd R6M`(new Date('2025-12-22')) // 'in 5 months'
d`yyyy-MM-dd R1Y`(new Date('2026-07-22')) // 'in 1 year'
d`yyyy-MM-dd R1Y`(new Date('2027-01-01')) // '2027-01-01' (>1Y)
```## Localization
Override names for days, months, seasons (relative time fixed in English):
```js
d.names = {
days: ['Domingo', 'Lunes', /* Spanish days */],
months: ['Enero', 'Febrero', /* Spanish months */],
seasons: ['Primavera', 'Verano', 'OtoΓ±o', 'Invierno'],
ordinals: ['o', 'o', 'o', 'o'] // Custom ordinals (e.g., Spanish)
}
```> [!NOTE]
> Localization doesn't alter LTR output or handle all global formats. Relative strings remain English.