millis-js v0.6.0
Millis.js
A tiny and dependency-free datetime library with a chainable and immutable API.
Key Features
- 🔄 Immutable operations - All operations return new instances, preventing accidental state mutations
- 🔗 Chainable API - Fluent interface for composing multiple operations
- 📅 UTC-based - Works with UTC milliseconds internally, avoiding timezone complexities
- ⚡ Zero dependencies - Tiny footprint, built without any external dependencies
- 🎯 Type-safe - Written in TypeScript with full type definitions
Install
npm install millis-jsAPI
This library provides three classes: DateTime, Duration, and Interval.
DateTime class
The DateTime class represents a millisecond timestamp.
Factory methods
Factory methods return a new DateTime instance.
DateTime.now(): DateTime: Returns a new DateTime representing the current UTC timeDateTime.now();DateTime.from(dateTime: DateTimeLike): DateTime: Returns a new DateTime from a date time like object// From milliseconds timestamp DateTime.from(1_704_067_200_000); // From strings DateTime.from('2024-01-01T00:00:00.000Z'); // ISO DateTime.from('2024-01-01'); // YYYY-MM-DD DateTime.from('2024-001'); // YYYY-DDD // From Date object DateTime.from(new Date()); // From DateTime object DateTime.from(DateTime.now()); // From calendar date components DateTime.from({ year: 2024, month: 1, dayOfMonth: 1, hour: 12, // optional minute: 30, // optional second: 15, // optional millisecond: 0 // optional }); // From ordinal date components DateTime.from({ year: 2024, dayOfYear: 1, hour: 12 // optional, etc. });DateTime.until(dateTime: DateTimeLike): Interval: Returns an Interval from the current time to a given date time// Creates interval spanning one day DateTime.now().until(DateTime.now().plus({ days: 1 })) // Interval object
Instance methods
Arithmetic
DateTime accepts both absolute (days, hours, minutes, seconds, milliseconds) and relative (months, years) durations.
plus(duration: DurationLike): DateTime: Returns a DateTime with the duration added// Add absolute durations (days and smaller units) DateTime.from('2024-01-01T00:00:00.000Z').plus({ days: 1, hours: 2, minutes: 30 }) // 2024-01-02T02:30:00.000Z // Add relative durations (months/years) DateTime.from('2024-01-31T00:00:00.000Z').plus({ months: 1 }) // 2024-02-29T00:00:00.000Z (handles leap years) // Add Duration object DateTime.from('2024-01-31T00:00:00.000Z').plus(Duration.hours(2)) // 2024-01-31T02:00:00.000Z // Add milliseconds DateTime.from('2024-01-31T00:00:00.000Z').plus(86_400_000) // 2024-02-01T00:00:00.000Zminus(duration: DurationLike): DateTime: Returns a DateTime with the duration subtracted// Subtract absolute durations DateTime.from('2024-01-01T00:00:00.000Z').minus({ days: 1, hours: 2 }) // 2023-12-30T22:00:00.000Z // Subtract relative durations DateTime.from('2024-03-31T00:00:00.000Z').minus({ months: 1 }) // 2024-02-29T00:00:00.000Z (handles leap years) // Subtract Duration object DateTime.from('2024-01-31T00:00:00.000Z').minus(Duration.hours(2)) // 2024-01-30T22:00:00.000Z // Subtract milliseconds DateTime.from('2024-01-31T00:00:00.000Z').minus(86_400_000) // 2023-12-31T00:00:00.000Z
Conversion
millis(): number: Returns the milliseconds since Unix EpochDateTime.from('2024-01-01T00:00:00.000Z').millis() // 1_704_067_200_000timestamp(): number: Returns the seconds since Unix Epoch (floored)DateTime.from('2024-01-01T00:00:00.500Z').timestamp() // 1_704_067_200date(): Date: Returns a JavaScript Date objectDateTime.from('2024-01-01T00:00:00.000Z').date() // new Date("2024-01-01T00:00:00.000Z")year(): number: Returns the calendar yearDateTime.from('2024-01-01T00:00:00.000Z').year() // 2024month(): number: Returns the calendar month (1-12)DateTime.from('2024-01-01T00:00:00.000Z').month() // 1dayOfMonth(): number: Returns the day of month (1-31)DateTime.from('2024-01-01T00:00:00.000Z').dayOfMonth() // 1dayOfYear(): number: Returns the day of year (1-365/366)DateTime.from('2024-01-01T00:00:00.000Z').dayOfYear() // 1 DateTime.from('2024-12-31T00:00:00.000Z').dayOfYear() // 366 (leap year)hour(): number: Returns the hour of day (0-23)DateTime.from('2024-01-01T12:00:00.000Z').hour() // 12minute(): number: Returns the minute of hour (0-59)DateTime.from('2024-01-01T12:30:00.000Z').minute() // 30second(): number: Returns the second of minute (0-59)DateTime.from('2024-01-01T12:30:15.000Z').second() // 15
Comparison
isBefore(dateTime: DateTimeLike): boolean: Returns true if the current DateTime is before the given date timeDateTime.from('2024-01-01T12:30:15.000Z').isBefore('2024-01-01T12:30:16.000Z') // trueisAfter(dateTime: DateTimeLike): boolean: Returns true if the current DateTime is after the given date timeDateTime.from('2024-01-01T12:30:15.000Z').isAfter('2024-01-01T12:30:14.000Z') // trueisBetween(start: DateTimeLike, end: DateTimeLike): boolean: Returns true if the current DateTime is between the given start and end date timesDateTime.from('2024-01-01T12:30:15.000Z').isBetween('2024-01-01T12:30:14.000Z', '2024-01-01T12:30:16.000Z') // trueisSameSecond(dateTime: DateTimeLike): boolean: Returns true if the current DateTime is in the same second as the given DateTimeDateTime.from('2024-01-01T12:30:15.123Z').isSameSecond('2024-01-01T12:30:15.456Z') // trueisSameMinute(dateTime: DateTimeLike): boolean: Returns true if the current DateTime is in the same minute as the given DateTimeDateTime.from('2024-01-01T12:30:15.000Z').isSameMinute('2024-01-01T12:30:45.000Z') // trueisSameHour(dateTime: DateTimeLike): boolean: Returns true if the current DateTime is in the same hour as the given DateTimeDateTime.from('2024-01-01T12:30:00.000Z').isSameHour('2024-01-01T12:45:00.000Z') // trueisSameDay(dateTime: DateTimeLike): boolean: Returns true if the current DateTime is in the same day as the given DateTimeDateTime.from('2024-01-01T12:00:00.000Z').isSameDay('2024-01-01T23:59:59.999Z') // trueisSameMonth(dateTime: DateTimeLike): boolean: Returns true if the current DateTime is in the same month as the given DateTimeDateTime.from('2024-01-01T00:00:00.000Z').isSameMonth('2024-01-31T23:59:59.999Z') // trueisSameYear(dateTime: DateTimeLike): boolean: Returns true if the current DateTime is in the same year as the given DateTimeDateTime.from('2024-01-01T00:00:00.000Z').isSameYear('2024-12-31T23:59:59.999Z') // trueisStartOfYear(): boolean: Returns true if the current DateTime is at the start of the yearDateTime.from('2024-01-01T00:00:00.000Z').isStartOfYear() // trueisStartOfMonth(): boolean: Returns true if the current DateTime is at the start of the monthDateTime.from('2024-01-01T00:00:00.000Z').isStartOfMonth() // trueisStartOfDay(): boolean: Returns true if the current DateTime is at the start of the dayDateTime.from('2024-03-15T00:00:00.000Z').isStartOfDay() // trueisStartOfHour(): boolean: Returns true if the current DateTime is at the start of the hourDateTime.from('2024-03-15T12:00:00.000Z').isStartOfHour() // trueisStartOfMinute(): boolean: Returns true if the current DateTime is at the start of the minuteDateTime.from('2024-03-15T12:30:00.000Z').isStartOfMinute() // trueisStartOfSecond(): boolean: Returns true if the current DateTime is at the start of the secondDateTime.from('2024-03-15T12:30:15.000Z').isStartOfSecond() // trueisEndOfYear(): boolean: Returns true if the current DateTime is at the end of the yearDateTime.from('2024-12-31T23:59:59.999Z').isEndOfYear() // trueisEndOfMonth(): boolean: Returns true if the current DateTime is at the end of the monthDateTime.from('2024-03-31T23:59:59.999Z').isEndOfMonth() // trueisEndOfDay(): boolean: Returns true if the current DateTime is at the end of the dayDateTime.from('2024-03-15T23:59:59.999Z').isEndOfDay() // trueisEndOfHour(): boolean: Returns true if the current DateTime is at the end of the hourDateTime.from('2024-03-15T12:59:59.999Z').isEndOfHour() // trueisEndOfMinute(): boolean: Returns true if the current DateTime is at the end of the minuteDateTime.from('2024-03-15T12:34:59.999Z').isEndOfMinute() // trueisEndOfSecond(): boolean: Returns true if the current DateTime is at the end of the secondDateTime.from('2024-03-15T12:34:56.999Z').isEndOfSecond() // true
Formatting
iso(): string: Returns the ISO string representationDateTime.now().iso() // "2024-01-01T00:00:00.000Z"format(format: DateTimeFormat | Intl.DateTimeFormat): string: Format the date time using a format string// Built-in formats dateTime.format('YYYY'); // "2024" dateTime.format('YYYY-DDD'); // "2024-001" dateTime.format('YYYY-MM-DD'); // "2024-01-01" dateTime.format('HH:mm:ss'); // "12:30:45" // Using Intl.DateTimeFormat dateTime.format(new Intl.DateTimeFormat('en-US')) // "1/1/2024, 12:30:45 AM"
Manipulation
startOfYear(): DateTime: Returns a new DateTime set to the start of the yearDateTime.from('2024-03-15T12:34:56.789Z').startOfYear() // 2024-01-01T00:00:00.000ZstartOfMonth(): DateTime: Returns a new DateTime set to the start of the monthDateTime.from('2024-03-15T12:34:56.789Z').startOfMonth() // 2024-03-01T00:00:00.000ZstartOfDay(): DateTime: Returns a new DateTime set to the start of the dayDateTime.from('2024-03-15T12:34:56.789Z').startOfDay() // 2024-03-15T00:00:00.000ZstartOfHour(): DateTime: Returns a new DateTime set to the start of the hourDateTime.from('2024-03-15T12:34:56.789Z').startOfHour() // 2024-03-15T12:00:00.000ZstartOfMinute(): DateTime: Returns a new DateTime set to the start of the minuteDateTime.from('2024-03-15T12:34:56.789Z').startOfMinute() // 2024-03-15T12:34:00.000ZstartOfSecond(): DateTime: Returns a new DateTime set to the start of the secondDateTime.from('2024-03-15T12:34:56.789Z').startOfSecond() // 2024-03-15T12:34:56.000ZendOfYear(): DateTime: Returns a new DateTime set to the end of the yearDateTime.from('2024-03-15T12:34:56.789Z').endOfYear() // 2024-12-31T23:59:59.999ZendOfMonth(): DateTime: Returns a new DateTime set to the end of the monthDateTime.from('2024-03-15T12:34:56.789Z').endOfMonth() // 2024-03-31T23:59:59.999ZendOfDay(): DateTime: Returns a new DateTime set to the end of the dayDateTime.from('2024-03-15T12:34:56.789Z').endOfDay() // 2024-03-15T23:59:59.999ZendOfHour(): DateTime: Returns a new DateTime set to the end of the hourDateTime.from('2024-03-15T12:34:56.789Z').endOfHour() // 2024-03-15T12:59:59.999ZendOfMinute(): DateTime: Returns a new DateTime set to the end of the minuteDateTime.from('2024-03-15T12:34:56.789Z').endOfMinute() // 2024-03-15T12:34:59.999ZendOfSecond(): DateTime: Returns a new DateTime set to the end of the secondDateTime.from('2024-03-15T12:34:56.789Z').endOfSecond() // 2024-03-15T12:34:56.999Z
Duration class
The Duration class represents a length of time in milliseconds.
Factory methods
Factory methods return a new Duration instance.
Duration.from(duration: DurationLike): Duration: Returns a Duration from a duration like object// From components Duration.from({ days: 1, hours: 2, minutes: 30 }) // P1DT2H30M // From milliseconds Duration.from(93_600_000) // P1DT2HDuration.between(start: DateTimeLike, end: DateTimeLike): Duration: Returns a Duration from a start and end date time// From ISO strings Duration.between('2024-01-01T00:00:00.000Z', '2024-01-02T00:00:00.000Z') // From DateTime objects Duration.between(DateTime.now(), DateTime.now().plus({ days: 1 })) // From milliseconds Duration.between(1704067200000, 1704067200000 + 24 * 60 * 60 * 1000) // From Date objects Duration.between(new Date(), new Date().setDate(new Date().getDate() + 1)) // From datetime components Duration.between({ year: 2024, month: 1, dayOfMonth: 1 }, { year: 2025, month: 1, dayOfMonth: 1 }) // From formatted strings Duration.between({ 'YYYY': '2024' }, { 'YYYY': '2025' })
Instance methods
Arithmetic
Duration accepts only absolute durations (days, hours, minutes, seconds, milliseconds).
plus(duration: AbsoluteDuration): Duration: Returns a Duration by adding a durationDuration.hours(2).plus({ minutes: 30 }) // 2.5 hoursminus(duration: AbsoluteDuration): Duration: Returns a Duration by subtracting a durationDuration.hours(5).minus({ hours: 2, minutes: 30 }) // 2.5 hoursabs(): Duration: Returns a Duration with the absolute value of the current durationDuration.hours(-2).abs() // 2 hours
Conversion
days(): number: Returns the duration in days// Precise value Duration.hours(25).days() // 1.0416666666666667 // Rounded value Duration.hours(25).days({ round: true }) // 1hours(): number: Returns the duration in hoursDuration.minutes(150).hours() // 2.5 Duration.minutes(150).hours({ round: true }) // 3minutes(): number: Returns the duration in minutesDuration.seconds(150).minutes() // 2.5 Duration.seconds(150).minutes({ round: true }) // 3seconds(): number: Returns the duration in secondsDuration.millis(2500).seconds() // 2.5 Duration.millis(2500).seconds({ round: true }) // 3millis(): number: Returns the duration in millisecondsDuration.seconds(1.5).millis() // 1500iso(): string: Returns the ISO duration stringDuration.from({ days: 1, hours: 2, minutes: 30 }).iso() // "P1DT2H30M"
Interval class
The Interval class represents a time span between two DateTime instances.
Factory methods
Factory methods return a new Interval instance.
Interval.between(start: DateTimeLike, end: DateTimeLike): Interval: Returns an Interval between two date timesInterval.between('2024-01-01T00:00:00.000Z','2024-01-02T00:00:00.000Z') // 2024-01-01T00:00:00.000Z/2024-01-02T00:00:00.000ZInterval.days(days: number): Interval: Returns an Interval spanning the specified number of days from now// Creates interval from now to 7 days in future Interval.days(7) // 2024-01-01T00:00:00.000Z/2024-01-08T00:00:00.000Z // Creates interval from now to 7 days in past Interval.days(-7) // 2024-01-01T00:00:00.000Z/2023-12-25T00:00:00.000Z
Instance methods
Conversion
duration(): Duration: Returns a Duration representing the length of the intervalInterval.between('2024-01-01T00:00:00.000Z', '2024-01-02T23:59:59.999Z').duration() // 2 daysstarts(): DateTime: Returns a DateTime representing the start of the intervalInterval.between('2024-01-01T00:00:00.000Z', '2024-01-02T23:59:59.999Z').starts() // 2024-01-01T00:00:00.000Zends(): DateTime: Returns a DateTime representing the end of the intervalInterval.between('2024-01-01T00:00:00.000Z', '2024-01-02T23:59:59.999Z').ends() // 2024-01-02T23:59:59.999Zdays(): Array<DateTime>: Returns an array of DateTimes for each day in the intervalInterval.between('2024-01-01T00:00:00.000Z', '2024-01-02T23:59:59.999Z').days() // [2024-01-01T00:00:00.000Z, 2024-01-02T23:59:59.999Z]years(): Array<DateTime>: Returns an array of DateTimes for each year in the intervalInterval.between('2024-01-01T00:00:00.000Z', '2025-01-01T23:59:59.999Z').years() // [2024-01-01T00:00:00.000Z, 2025-01-01T23:59:59.999Z]
Comparison
contains(dateTime: DateTimeLike): boolean: Returns true if the interval contains the given date timeInterval.between('2024-01-01T00:00:00.000Z', '2024-01-02T00:00:00.000Z').contains('2024-01-01T12:00:00.000Z') // true
Formatting
iso(): string: Returns the ISO interval string representationInterval.between('2024-01-01T00:00:00.000Z', '2024-01-02T00:00:00.000Z').iso() // "2024-01-01T00:00:00.000Z/2024-01-02T00:00:00.000Z"
License
MIT