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 2017
To 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 here
Should 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)); // = 8
Enumerate 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;
}