ts-date is a Date library written in Typescript for Typescript
Main difference from most javascript Date libraries is:
- you will never get
"Invalid Date", if you follow types - literally no overhead under native
Date, take a look at benchmarks - provides tree-shakeable pure functions
import { parse, format, addMonth } from "ts-date/esm/locale/en";
const date = parse("1st August 2017", "Do MMMM YYYY");
const result = format(addMonth(date, 1), "Do MMMM YYYY"); // 1st September 2017To get full benefit from tree shaking you can import from ts-date/esm/*
See resolve.alias for Webpack,
or rollup-plugin-alias for Rollup
There is different import for each locale: ts-date/locale/*
For now there is en, da and ru
ts-date exports without any locale
With momentjs you have no warnings here:
import * as moment from "moment";
function someDateProcessing(isoDate: string): string {
const m = moment(isoDate);
return m.format("YYYY-MM-DD"); // "Invalid date"
}
someDateProcessing("The Day After Tomorrow");With ts-date you forced to make checks or add a null as possible result
import { format, parseIso } from "ts-date";
function dateProcessingWithSafetyBelt(pleaseIsoDate: string): string {
const d = parseIso(pleaseIsoDate); // Type is 'ValidDate | null'
// Warning here:
return format(d, "YYYY-MM-DD"); // Type is 'string | null'
// TS2322:Type 'string | null' is not assignable to type 'string'.
// To avoid warning should:
// - change function type to 'string | null'
// - throw error
// - or return another magic string explicitly
if (d === null) {
throw new TypeError(`ISO 8601 format expected`);
}
d; // Type is 'ValidDate'
return format(d, "YYYY-MM-DD"); // Type is 'string'
}ValidDate type – the immutable wrapper type under Date, actually ValidDate becomes a Date after compile
ValidDate creation occurs through methods which will return null instead of Date("Invalid Date")
import { parseIso, format } from "ts-date/locale/en";
const d = parseIso("2021-12-21"); // ValidDate | null
format(d, "Do MMMM YYYY"); // Type is 'string | null'
if (d) {
d; // ValidDate
format(d, "Do MMMM YYYY"); // Type is 'string'
// no "Invalid Date" option here
} else {
d; // null
format(null, "Do MMMM YYYY"); // Type is 'null'
}Since ValidDate is Date, you can use some Date methods:
const d = parseIso("2021-12-21");
if (d) {
d.getDate(); // 21
}To make ValidDate immutable, all methods for Date mutation are banned in type:
d.setDate(0); // Typescript will warn hereShould work fine without polyfills in every modern browser and IE9+ Chrome 5+, Edge, Firefox 4.0+, IE 9+, Opera 12+, Safari 5+
NOTE: Mostly methods will return null for null or invalid input
This tokens can be used for parsing and formatting dates:
| token | meaning | example |
|---|---|---|
| YYYY | 4 digit year | 2018 |
| YY | 2 digit year | 18 |
| MMMM | month | January, December |
| MMM | short month | Jan, Dec |
| MM, M | month number | 01, 1 |
| DD, D | day of month | 02, 2 |
| dddd | day of week | Friday, Sunday |
| ddd | short day of week | Fri, Sun |
| dd | 2 letter day of week | Fr, Su |
| HH, H | hour-24 | 0..24 |
| hh, h | hour-12 | 0..12 |
| A | meridiem | AM, PM |
| a | meridiem | am, pm |
| aa | meridiem | a.m., p.m. |
| mm, m | minute | 0..59 |
| ss, s | second | 0..59 |
| SSS, SS, S | millisecond | 0..999 |
| Z | timezone | -12:00..+12:00 |
| ZZ | timezone | -1200..+1200 |
Parse date by template using tokens
parse("2018 July 12", "YYYY MMMM D"); // = Date(2018-07-12)Parse most of ISO 8601 formats
parseIso("2018-06-12T19:30"); // = Date(2018-06-12T19:30)Creates ValidDate from Date object
Similar to isValidDate, but returns new valid date or null
Create ValidDate, same signature as new Date(...)
Type guard for ValidDate, returns true if date is valid
Format by template using tokens
format(new Date("2018-07-12"), "YYYY MMMM D"); // = '2018 July 12'Format as YYYY-MM-DD ISO string
Format as YYYY-MM-DD[T]HH:MM ISO string
Format as YYYY-MM-DD[T]HH:MM:SS.sss ISO string
Adding fixed amount of units.
First argument should be ValidDate, null or either. Result will be same type as input
addMilliseconds;
addSeconds;
addMinutes;
addHours;
addDate;
addMonth;
addYear;Reset to default all units after method's name unit
resetYear;
resetMonth;
resetISOWeek;
resetDate;
resetHours;
resetMinutes;
resetSeconds;Example:
resetYear(newValidDate(2017, 5, 30, 12, 30)); // = Date(2017-01-01)Return whole amount of [units] between first and second date, same as you expect from d1 - d2
In case one of arguments is null or Date("Invalid Date"), result is null
diffMilliseconds;
diffSeconds;
diffMinutes;
diffHours;
diffDate;
diffMonth;
diffYear;Example:
diffDate(new Date(2018, 5, 10, 18), new Date(2018, 5, 1, 12)); // = 9
diffDate(new Date(2018, 5, 10, 18), new Date(2018, 5, 1, 20)); // = 8Enumerate units between dates
diffCalendarDate;
diffCalendarMonth;
diffCalendarYear;Example:
diffCalendarDate(new Date(2018, 5, 10, 18), new Date(2018, 5, 1, 12)); // = 9
diffCalendarDate(new Date(2018, 5, 10, 18), new Date(2018, 5, 1, 20)); // = 9 <-- different from diffDate
function isToday(d: ValidDate) {
return diffCalendarDate(d, newValidDate()) === 0;
}