Copy-paste recipes for common formatting tasks.
import FormatDateTime from '@pphatdev/format-datetime';
new FormatDateTime(new Date(2026, 6, 13), 'YYYY-MM-dd').formatDate();
// "2026-07-13"new FormatDateTime(new Date(2026, 6, 13, 14, 30, 45), 'DDDD, MMMM d, YYYY hh:mm:ss A', 'en-US').formatDate();
// "Monday, July 13, 2026 02:30:45 PM"new FormatDateTime(new Date(2026, 6, 13, 14, 30, 45), 'HH:mm:ss').formatDate();
// "14:30:45"new FormatDateTime(new Date(2026, 6, 13, 14, 30, 45), 'YYYY-MM-ddTHH:mm:ssZ').formatDate();
// e.g. "2026-07-13T14:30:45+07:00"new FormatDateTime(new Date(), 'YYYYMMdd_HHmmss').formatDate();
// e.g. "20260713_143045" — safe for filenamesnew FormatDateTime(new Date(2026, 6, 13, 14, 30, 45), 'DDDD, MMMM d, YYYY, hh:mm:ss A', 'km-KH').formatDate();
// "ចន្ទ, កក្កដា ១៣, ២០២៦, ០២:៣០:៤៥ រសៀល"new FormatDateTime(new Date(2026, 0, 1), 'YYYY', 'km-KH').formatDate();
// "២០២៦"new FormatDateTime(new Date(2026, 6, 13, 3, 0, 0), 'a', 'km-KH').formatDate(); // "រំលងអធ្រាត្រ"
new FormatDateTime(new Date(2026, 6, 13, 9, 0, 0), 'a', 'km-KH').formatDate(); // "ព្រឹក"
new FormatDateTime(new Date(2026, 6, 13, 12, 0, 0), 'a', 'km-KH').formatDate(); // "ថ្ងៃត្រង់"
new FormatDateTime(new Date(2026, 6, 13, 14, 0, 0), 'a', 'km-KH').formatDate(); // "រសៀល"
new FormatDateTime(new Date(2026, 6, 13, 18, 0, 0), 'a', 'km-KH').formatDate(); // "ល្ងាច"
new FormatDateTime(new Date(2026, 6, 13, 22, 0, 0), 'a', 'km-KH').formatDate(); // "យប់"new FormatDateTime(new Date(2026, 6, 13), 'DDDD d MMMM YYYY', 'fr-FR').formatDate();
// "lundi 13 juillet 2026"
new FormatDateTime(new Date(2026, 6, 13, 14, 30), 'DDDD hh:mm A', 'ja-JP').formatDate();
// e.g. "月曜日 02:30 午後"
new FormatDateTime(new Date(2026, 6, 13), 'dd/MM/YYYY', 'ar-EG').formatDate();
// "١٣/٠٧/٢٠٢٦"import { KhmerDate } from '@pphatdev/format-datetime';
const kd = new KhmerDate(new Date(2026, 6, 13));
kd.toLunarDate('full');
// "ថ្ងៃចន្ទ ១៣រោច ខែបឋមាសាឍ ឆ្នាំមមី អដ្ឋស័ក ពុទ្ធសករាជ ២៥៧០"
kd.toLunarDate('medium');
// "១៣រោច ខែបឋមាសាឍ ព.ស. ២៥៧០"
kd.toLunarDate('short');
// "១៣រោច ខែបឋមាសាឍ"new KhmerDate(new Date(2026, 6, 13)).toLunarDate('lW ldd lN lM');
// "ចន្ទ ១៣ រោច បឋមាសាឍ"
new KhmerDate(new Date(2026, 6, 13)).toLunarDate('ថ្ងៃlW lddlN ឆ្នាំlA lE ព.ស. BBBB');
// "ថ្ងៃចន្ទ ១៣រោច ឆ្នាំមមី អដ្ឋស័ក ព.ស. ២៥៧០"new FormatDateTime(new Date(2026, 6, 13), 'YYYY-MM-dd (BBBB) lM ld lN lA lE').formatDate();
// "2026-07-13 (2570) បឋមាសាឍ 14 រោច មមី អដ្ឋស័ក"const kd = new KhmerDate(new Date(2026, 6, 16));
`${kd.toLunarDate('full')} ត្រូវនឹងថ្ងៃ${kd.toKhmerDate()}`;
// "ថ្ងៃព្រហស្បតិ៍ ២កើត ខែទុតិយាសាឍ ឆ្នាំមមី អដ្ឋស័ក ពុទ្ធសករាជ ២៥៧០ ត្រូវនឹងថ្ងៃទី១៦ ខែកក្កដា ឆ្នាំ២០២៦"const kd = new KhmerDate(new Date(2026, 6, 13));
kd.toKhmerDate('{dayOfWeekKhmer} ទី{day} ខែ{month} ឆ្នាំ{year}');
// "ចន្ទ ទី១៣ ខែកក្កដា ឆ្នាំ២០២៦"
kd.toKhmerDate('{day}/{month}/{year}');
// "១៣/កក្កដា/២០២៦"import FormatDateTime, { KhmerDate } from '@pphatdev/format-datetime';
const ny = KhmerDate.getKhNewYearMoment(2026);
const kd = new KhmerDate(ny);
`${kd.toLunarDate('full')} ត្រូវនឹងថ្ងៃ${kd.toKhmerDate()}`;
// "ថ្ងៃអង្គារ ១២រោច ខែចេត្រ ឆ្នាំមមី អដ្ឋស័ក ពុទ្ធសករាជ ២៥៦៩ ត្រូវនឹងថ្ងៃទី១៤ ខែមេសា ឆ្នាំ២០២៦"
const km = new FormatDateTime(ny, 'hh:mm', 'km-KH');
const en = new FormatDateTime(ny, 'hh:mm A', 'en-US');
`មហាសង្រ្កាន្ត ម៉ោង ${km.formatDate()} AM (Moha Sankranta at ${en.formatDate()})`;
// "មហាសង្រ្កាន្ត ម៉ោង ១០:៤៨ AM (Moha Sankranta at 10:48 AM)"const startYear = new Date().getFullYear();
for (let i = 0; i < 5; i++) {
const year = startYear + i;
const ny = KhmerDate.getKhNewYearMoment(year);
const kd = new KhmerDate(ny);
console.log(`${year}: ${kd.toLunarDate('full')}`);
}import { KhmerDate } from '@pphatdev/format-datetime';
KhmerDate.arabicToKhmerNumber('12345'); // "១២៣៤៥"
KhmerDate.khmerToArabicNumber('១២៣៤៥'); // "12345"
KhmerDate.getKhmerNumber(2026); // "២០២៦"
// Works with mixed content
KhmerDate.arabicToKhmerNumber('2026-07-13'); // "២០២៦-០៧-១៣"
KhmerDate.arabicToKhmerNumber('$1,234.56'); // "$១,២៣៤.៥៦"// String parsing (via `new Date(str)`)
new FormatDateTime('2026-01-01', 'YYYY', 'en-US').formatDate(); // "2026"
new FormatDateTime('2026-07-13T14:30:45Z', 'HH:mm').formatDate(); // depends on TZ
// Invalid date returns a sentinel string — no exception
new FormatDateTime('this-is-not-a-date').formatDate(); // "Invalid Date"
// Omitting the date uses `new Date()` at construction time
const now = new FormatDateTime();
now.date instanceof Date; // true
// Guard clause pattern
function safeFormat(input: string | null): string {
const dt = new FormatDateTime(input);
if (isNaN(dt.date.getTime())) return 'N/A';
return dt.formatDate();
}import FormatDateTime from '@pphatdev/format-datetime';
function KhmerClock({ date }: { date: Date }) {
const dt = new FormatDateTime(date, 'DDDD d MMMM YYYY, hh:mm:ss A', 'km-KH');
return <time dateTime={date.toISOString()}>{dt.formatDate()}</time>;
}import { useEffect, useState } from 'react';
import FormatDateTime from '@pphatdev/format-datetime';
export function LiveKhmerClock() {
const [now, setNow] = useState(() => new Date());
useEffect(() => {
const id = setInterval(() => setNow(new Date()), 1000);
return () => clearInterval(id);
}, []);
const dt = new FormatDateTime(now, 'DDDD d MMMM YYYY hh:mm:ss A', 'km-KH');
return <span>{dt.formatDate()}</span>;
}import { useMemo } from 'react';
import FormatDateTime from '@pphatdev/format-datetime';
export function useFormattedDate(date: Date, format: string, locale = 'en-US'): string {
return useMemo(() => new FormatDateTime(date, format, locale).formatDate(), [date, format, locale]);
}
// usage
const formatted = useFormattedDate(new Date(), 'YYYY-MM-dd', 'km-KH');import { useState } from 'react';
import FormatDateTime from '@pphatdev/format-datetime';
export function DateWithLocaleToggle({ date }: { date: Date }) {
const [locale, setLocale] = useState<'en-US' | 'km-KH'>('en-US');
const dt = new FormatDateTime(date, 'DDDD, MMMM d, YYYY', locale);
return (
<div>
<span>{dt.formatDate()}</span>
<button onClick={() => setLocale(l => l === 'en-US' ? 'km-KH' : 'en-US')}>
{locale === 'en-US' ? 'ខ្មែរ' : 'English'}
</button>
</div>
);
}<script setup lang="ts">
import { computed } from 'vue';
import FormatDateTime from '@pphatdev/format-datetime';
const props = defineProps<{ date: Date; locale?: string }>();
const formatted = computed(() => {
return new FormatDateTime(props.date, 'DDDD, MMMM d, YYYY', props.locale ?? 'km-KH').formatDate();
});
</script>
<template>
<time :datetime="date.toISOString()">{{ formatted }}</time>
</template><script lang="ts">
import FormatDateTime from '@pphatdev/format-datetime';
export let date: Date;
export let locale: string = 'km-KH';
$: formatted = new FormatDateTime(date, 'DDDD, MMMM d, YYYY', locale).formatDate();
</script>
<time datetime={date.toISOString()}>{formatted}</time>import FormatDateTime, { KhmerDate } from '@pphatdev/format-datetime';
export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
const locale = url.searchParams.get('locale') ?? 'en-US';
const format = url.searchParams.get('format') ?? 'YYYY-MM-dd HH:mm:ss Z';
const dt = new FormatDateTime(new Date(), format, locale);
return Response.json({
solar: dt.formatDate(),
lunar: new KhmerDate().toLunarDate('full'),
timestamp: Date.now(),
});
},
};import FormatDateTime, { KhmerDate } from '@pphatdev/format-datetime';
export default {
async fetch(): Promise<Response> {
const dt = new FormatDateTime(new Date(), 'DDDD, d MMMM YYYY hh:mm A', 'km-KH');
const kd = new KhmerDate();
const html = `<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>ថ្ងៃនេះ</title></head>
<body>
<h1>ថ្ងៃនេះ</h1>
<p>${dt.formatDate()}</p>
<p>${kd.toLunarDate('full')}</p>
</body></html>`;
return new Response(html, { headers: { 'Content-Type': 'text/html; charset=utf-8' } });
},
};#!/usr/bin/env node
import FormatDateTime, { KhmerDate } from '@pphatdev/format-datetime';
const [, , input] = process.argv;
const date = input ? new Date(input) : new Date();
if (isNaN(date.getTime())) {
console.error(`Invalid date: ${input}`);
process.exit(1);
}
console.log(new FormatDateTime(date, 'DDDD, MMMM d, YYYY', 'en-US').formatDate());
console.log(new KhmerDate(date).toLunarDate('full'));
console.log(new KhmerDate(date).toKhmerDate());Usage:
$ node cli.js 2026-07-13
Monday, July 13, 2026
ថ្ងៃចន្ទ ១៣រោច ខែបឋមាសាឍ ឆ្នាំមមី អដ្ឋស័ក ពុទ្ធសករាជ ២៥៧០
ទី១៣ ខែកក្កដា ឆ្នាំ២០២៦import FormatDateTime from '@pphatdev/format-datetime';
const dates = [
new Date(2026, 0, 1),
new Date(2026, 3, 14), // Moha Songkran
new Date(2026, 6, 13),
new Date(2026, 11, 31),
];
dates.map(d => new FormatDateTime(d, 'DDDD, MMMM d, YYYY', 'km-KH').formatDate());
// [
// "ព្រហស្បតិ៍, មករា ១, ២០២៦",
// "អង្គារ, មេសា ១៤, ២០២៦",
// "ចន្ទ, កក្កដា ១៣, ២០២៦",
// "ព្រហស្បតិ៍, ធ្នូ ៣១, ២០២៦"
// ]const dt = new FormatDateTime(new Date(), 'YYYY-MM-dd');
const formatted: string[] = [];
for (const d of dates) {
dt.date = d;
formatted.push(dt.formatDate());
}import FormatDateTime from '@pphatdev/format-datetime';
function DateRange({ start, end, locale = 'km-KH' }: { start: Date; end: Date; locale?: string }) {
const sameMonth = start.getFullYear() === end.getFullYear() && start.getMonth() === end.getMonth();
const dtStart = new FormatDateTime(start, sameMonth ? 'd' : 'MMMM d', locale);
const dtEnd = new FormatDateTime(end, 'MMMM d, YYYY', locale);
return <span>{dtStart.formatDate()} – {dtEnd.formatDate()}</span>;
}import FormatDateTime from '@pphatdev/format-datetime';
const chartData = getMonthlyRevenue(); // [{ date: Date, revenue: number }, ...]
const labels = chartData.map(pt => new FormatDateTime(pt.date, 'MMM YYYY', 'en-US').formatDate());
// e.g. ["Jan 2026", "Feb 2026", "Mar 2026", ...]import { describe, it, expect } from 'vitest';
import FormatDateTime, { KhmerDate } from '@pphatdev/format-datetime';
describe('date formatting', () => {
it('formats Khmer New Year 2026 precisely', () => {
const ny = KhmerDate.getKhNewYearMoment(2026);
expect(new FormatDateTime(ny, 'YYYY-MM-dd hh:mm', 'en-US').formatDate())
.toBe('2026-04-14 10:48');
});
it('handles Khmer digits', () => {
expect(new FormatDateTime(new Date(2026, 0, 1), 'YYYY', 'km-KH').formatDate())
.toBe('២០២៦');
});
});import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import FormatDateTime from '@pphatdev/format-datetime';
describe('with fake timers', () => {
beforeEach(() => vi.useFakeTimers().setSystemTime(new Date('2026-07-13T14:30:00Z')));
afterEach(() => vi.useRealTimers());
it('defaults to `now`', () => {
expect(new FormatDateTime(null, 'YYYY-MM-dd').formatDate()).toBe('2026-07-13');
});
});const now = new Date();
const utcMs = now.getTime() + now.getTimezoneOffset() * 60_000;
const utcDate = new Date(utcMs);
new FormatDateTime(utcDate, 'YYYY-MM-dd HH:mm:ss', 'en-US').formatDate();
// UTC-based formatted stringconst ny = KhmerDate.getKhNewYearMoment(2026);
const local = new FormatDateTime(ny, 'YYYY-MM-dd HH:mm Z').formatDate();
const utc = new FormatDateTime(new Date(ny.getTime() + ny.getTimezoneOffset() * 60_000), 'YYYY-MM-dd HH:mm').formatDate() + ' UTC';
console.log(`Local: ${local}`);
console.log(`UTC: ${utc}`);