ts-py-datetime
v0.10.0
Published
Datetime handling the python way (or as close as possible), now with TypeScript
Downloads
33
Maintainers
Readme
Python-style datetime handling lib for TypeScript
This tiny lib emulates most of the main functions of Python's datetime lib to simplify datetime handling in TypeScript that is notoriously cumbersome in this regard. It tries to stay as close to the python API as possible - ideal if you are working with both Python and TS projects. Hope you'll find it useful!
This project is a fork of py-datetime. It ports the project to TypeScript and adds many more functions and constants from the Python datetime module.
For format string specifier directives, see the d3-time-format documentation.
Install
npm install ts-py-datetime
Demo
This package provides a dt
object which wraps all classes and constants into one object, and can be used to intantiate new dates, times, datetimes, and timedeltas with Pythonic syntax.
import dt from 'ts-py-datetime';
// const { default: dt } = await import("./src/index.ts"); in a REPL
const now = dt.datetime.now();
const today = dt.datetime.combine(now, dt.time());
console.log('Now:', now.strftime('%Y-%m-%d %H:%M:%S'));
console.log('Today:', today.strftime('%Y-%m-%d'));
console.log(
'Minutes since midnight:',
dt.timedelta(now - today).valueOf() / 60,
);
You can also import the classes and constants directly, but you will have to use the new
operator to instantiate them.
import { date, time, datetime, timedelta } from 'ts-py-datetime';
// const { date, time, datetime, timedelta } = await import("./src/index.ts"); in a REPL
const then = new datetime(2022, 12, 11, 10, 30, 22);
const now = datetime.now(); // static functions do not need the new operator
Pythonic Syntax
JavaScript/TypeScript does not support keyword arguments like Python does. As an alternative for any function that has multiple optional inputs, the first input can instead be an object with keys with the same names as the arguments.
In order to be as close to the Python datetime module as possible, any externally exposed variables, properties, and methods use Python style naming conventions instead of JavaScript/TypeScript ones. Such as date_string
instead of dateString
or total_seconds()
instead of totalSeconds()
.
Constants
MINYEAR
The smallest year number allowed in date
and datetime
objects. Because of JavaScript Date limitations, it's value is 100.
MAXYEAR
The largest year number allowed in date
and datetime
objects. It's value is 9999.
Available Types
class date
An idealized date, assuming the current Gregorian calendar always was, and always will be, in effect.
Attributes: year
, month
, day
.
class time
An idealized time, independent of any particular day, assuming that every day has exactly 24*60*60 seconds (There is no notion of "leap seconds" here).
Attributes: hour
, minute
, second
, millisecond
.
class datetime
A combination of a date and time.
Attributes: year
, month
, day
, hour
, minute
, second
, millisecond
, and utc
.
class timedelta
A duration expressing the difference between two datetime
or date
instances to millisecond resolution.
timedelta
Objects
A timedelta
object represents a duration, the difference betwee two datetime
or date
instances.
class timedelta({ days: 0, seconds: 0, milliseconds: 0, minutes: 0, hours: 0, weeks: 0 })
All arguments are optional and default to 0. Arguments may be integers or floats, and may be positive or negative.
Only days, seconds, and milliseconds are stored internally. Arguments are converted to those units:
- A minute is converted to 60 seconds.
- An hour is conveted to 3600 seconds.
- A week is converted to 7 days.
and days, seconds, and milliseconds are then normalized so that the representation is unique, with
0 <= milliseconds < 1000
0 <= seconds < 36000*24
-999999999 <= days < 999999999
The following example illustrates how any arguments besides days, seconds and milliseconds are "merged" and normalized into those three resulting attributes:
import dt from 'ts-py-datetime';
const delta = dt.timedelta({
days: 50,
seconds: 27,
milliseconds: 29100,
minutes: 5,
hours: 8,
weeks: 2,
});
// Only days, seconds, and microseconds remain
console.log(delta);
...
timedelta { days: 64, seconds: 29156, milliseconds: 100 }
Any fractional milliseconds are lost, as JavaScript Date objects only support millisecond precision.
If the normalized total seconds lies outside the min and max timedelta range, RangeError
is thrown.
Class properties
Because of JavaScript Date limitations, the minimum and maximum timedelta values differ from Python.
timedelta.min
The most negative timedelta
object, timedelta(-100000000)
timedelta.max
The most positive timedelta
object, timedelta(100000000)
timedelta.resolution
The smallest possible difference between non-equal timedelta
objects, timedelta({ milliseconds: 1 })
Instance properties (read-only):
timedelta.days
Between -100,000,000 and 100,000,000 inclusive.
timedelta.seconds
Between 0 and 86,399 inclusive.
timedelta.milliseconds
Between 0 and 999 inclusive.
Supported operations
Timedelta objects can be added or subtracted to each other or to date, time, or datetime objects. Any of these operations will return a number, which can then be cast back to one of these objects using their constructors or static methods.
const delta = dt.timedelta({ days: 31 });
const datetime = dt.datetime(2013, 10, 1, 12, 11, 10);
console.log(datetime.fromtimestamp(datetime + delta));
...
datetime {
year: 2013,
month: 11,
day: 1,
hour: 12,
minute: 11,
second: 10,
millisecond: 0,
utc: false
}
Instance methods
timedelta.total_seconds()
Return the total number of seconds contained in the duration.
timedelta.valueOf()
For a timedelta delta, delta.valueOf()
is equivalent to delta.total_seconds()
.
timedelta.toString()
Return the days, hours, minutes, seconds, and milliseconds of the timedelta in a string format. If the timedelta is less than one day then days is not included. If the timedelta does not have a millisecond component then it is also not included.
date
Objects
A date
object represents a date (year, month, and day) in an idealized calendar, the current Gregorian calendar indefinitely extended in both directions.
January 1 of year 1 is called day number 1, January 2 of year 1 is called day number 2, and so on.
class date(year, month, day)
All arguments are required. Arguments must be integers, in the following ranges:
MINYEAR <= year < MAXYEAR
1 <= month <= 12
1 <= day <= number of days in the given month and year
If an argument is outside those ranges is given, RangeError
is thrown.
Other static method constructors
static method date.today()
Return the current local date.
static method date.fromtimestamp(timestamp)
Return the local date corresponding to the POSIX timestamp.
static method date.fromoridinal(ordinal)
Return the date corresponding to the proleptic Gregorian ordinal, where January 1 of year 1 has ordinal 1.
The MINYEAR
restriction of year 100 still applies, and any ordinal below 36160 or above 3652059 wil throw a RangeError
.
static method date.fromisoformat(date_string)
Return a date
corresponding to a date_string given in the ISO 8601 format YYYY-MM-DD
.
static_method date.fromisocalendar(year, week, day)
Return a date
corresponding to the ISO calendar date specified by year, week, and day. This is the inverse of the function date.isocalendar()
This function does not seem to work correctly, possibly due to an issue with d3-time-format.
Class properties
date.min
The earliest representable date, date(MINYEAR, 1, 1)
.
date.max
The latest representable date, date(MAXYEAR, 12, 31)
.
date.resolution
The smallest possible difference between non-equal date objects, `timedelta({ days: 1 }).
Instance properties (read-only)
date.year
Between MINYEAR
and MAXYEAR
exclusive.
date.month
Between 1 and 12 inclusive.
date.day
Between 1 and the number of days in the given month of the given year.
Supported Operations
Date objects can be added or subtracted with timedelta objects or logically compared to other date objects. As said above all timedelta object arithmetic returns seconds which can be used to construct other objects.
const delta = dt.timedelta({ days: 1000 })
const date = dt.date( 2006, 6, 11 )
console.log(dt.date.fromtimestamp(date - delta))
...
date { year: 2003, month: 9, day: 15 }
const date1 = dt.date( 2006, 6, 11 )
const date2 = dt.date( 2007, 7, 2 )
console.log(date1 < date2)
...
true
Instance methods
date.replace({ year: this.year, month: this.month, day: this.day })
Return a date with the same value, except for those parameters given new values by whichever arguments are specified.
date.toordinal()
Return the proleptic Gregorian ordinal ofthe date, where January 1 of year 1 has ordinal 1. For any date
object d, dt.date.fromordinal(d.toordinal()) == d
The MINYEAR
restriction of year 100 still applies, and any ordinal below 36160 or above 3652059 wil throw a RangeError
.
date.weekday()
Return the day of the week as an integer, where Monday is 0 and Sunday is 6. For example, dt.date(2002, 12, 4).weekday() == 2
, a Wednesday.
date.isoweekday()
Return the day of the week as an integer, where Monday is 1 and Sunday is 7. For example, dt.date(2002, 12, 4).isoweekday() == 3
, a Wednesday.
date.isocalendar()
Return an array with three components: year
, week
, and weekday
.
The ISO calendar is a widely used variant of the Gregorian calendar.
The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first (Gregorian) calendar week of a year containing a Thursday. This is called week number 1, and the ISO year of that Thursday is the same as its Gregorian year.
This function does not seem to work correctly, possibly due to an issue with d3-time-format.
date.isoformat()
Return a string representing the date in ISO 8601 format, YYYY-MM-DD
.
date.valueOf()
Return the POSIX timestamp of the date, assuming it's time is midnight.
date.toString()
For a date d, d.toString()
is equivalent to d.isoformat()
.
date.ctime()
Return a string representing the date, such as Wed Dec 4 00:00:00 2002
.
date.strftime(format)
Return a string representing the date, controlled by an explicit format string. Format codes referring to hours, minutes, or seconds will see 0 values.
datetime
Objects
A datetime
object is a single object containing all the information from a date
object and a time
object.
Like a date
object, datetime
assumes the current Gregorian calendar extended in both directions; like a time
object, datetime
assumes there are exactly 3600*24 seconds in every day.
class datetime({ year, month, day, hour: 0, minute: 0, second: 0, millisecond: 0, utc: false })
The year, month, and day arguments are required. The remaining arguments must be integers in the following ranges:
MINYEAR <= year <= MAXYEAR
1 <= month <= 12
1 <= day <= number of days in the given month and year
0 <= hour < 24
0 <= minute < 60
0 <= second < 60
0 <= millisecond < 1000
If utc is set to true, then the datetime will be treated as UTC. Otherwise it will use the local time.
Other static method constructors
static method datetime.today()
Return the current local date and time.
static_method datetime.now()
Return the current local date and time. Functionally equivalent to dt.datetime.today()
but is considered the preferred syntax.
static_method datetime.utcnow()
Return the current UTC date and time.
static_method datetime.fromtimestamp(timestamp)
Return the local date and time corresponding to the POSIX timestamp.
static_method datetime.utcfromtimestamp(timestamp)
Return the UTC datetime
corresponding to the POSIX timestamp.
static_method datetime.fromjsdate(jsdate)
Return the local date and time corresponding to the JS Date object.
static_method datetime.utcfromjsdate(jsdate)
Return the UTC datetime
corresponding to the JS Date object.
static_method datetime.fromordinal(ordinal)
Return the datetime
corresponding to the proleptic Gregorian ordinal, where January 1 of year 1 has oridinal 1.
The MINYEAR
restriction of year 100 still applies, and any ordinal below 36160 or above 3652059 wil throw a RangeError
.
static_method datetime.combine(date, time)
Return a new datetime
object whose date components are equal to the given date
object's, and whose time components are equal to the given time
object's. If the date argument is a datetime
object, its time components are ignored.
static_method datetime.fromisoformat(date_string)
Return a datetime
corresponding to a date_string in any valid ISO 8601 format.
static_method datetime.fromisocalendar(year, month, day)
Return a datetime
corresponding to the ISO calendar date specified by the year, week, and day. The non-date components of the datetime are populated with their normal default values.
This function does not seem to work correctly, possibly due to an issue with d3-time-format.
static_method datetime.strptime(date_string, format, utc)
Return a datetime
corresponding to date_string, parsed according to format.
Class properties
datetime.min
The earliest representable datetime
, datetime(MINYEAR, 1, 1)
.
datetime.max
The latest representable datetime
, datetime(MAXYEAR, 12, 31, 23, 59, 59, 999)
.
datetime.resolution
The smallest possible difference between non-equal datetime
objects, timedelta({ milliseconds: 1 })
Instance properties (read-only):
datetime.year
Between MINYEAR
and MAXYEAR
inclusive.
datetime.month
Between 1 and 12 inclusive.
datetime.day
Between 1 and the number of days in the given month of the given year.
datetime.hour
Between 0 and 23 inclusive.
datetime.minute
Between 0 and 59 inclusive.
datetime.second
Between 0 and 59 inclusive.
datetime.millisecond
Between 0 and 999 inclusive.
Supported Operations
Datetime objects can be added or subtracted with timedelta objects or logically compared to other datetime objects. As said above all timedelta object arithmetic returns seconds which can be used to construct other objects.
const delta = dt.timedelta({ days: 31 });
const datetime = dt.datetime(2013, 10, 1, 12, 11, 10);
console.log(datetime.fromtimestamp(datetime + delta));
...
datetime {
year: 2013,
month: 11,
day: 1,
hour: 12,
minute: 11,
second: 10,
millisecond: 0,
utc: false
}
const datetime1 = dt.datetime(2006, 6, 11, 5, 2, 30)
const datetime2 = dt.datetime(2007, 7, 2, 22, 30, 7, 332)
console.log(datetime1 < datetime2)
...
true
Instance methods
datetime.date()
Return date
object with same year, month, and day.
datetime.time()
Return time
object with same hour, minute, second, and millisecond.
datetime.replace({ year: this.year, month: this.month, day: this.day, hour: this.hour, minute: this.minute, second: this.second, millisecond: this.millisecond, utc: this.utc })
Return a datetime with the same attributes, except for those attributes given new values by whichever arguments are specified.
datetime.toordinal()
Return the proleptic Gregorian ordinal of the date.
datetime.timestamp()
Return the POSIX timestamp corresponding to the datetime
instance.
datetime.weekday()
Return the day of the week as an integer, where Monday is 0 and Sunday is 6.
datetime.isoweekday()
Return the day of the week as an integer, where Monday is 1 and Sunday is 7.
datetime.isocalendar()
Return an array with three components: year
, week
, and weekday
.
This function does not seem to work correctly, possibly due to an issue with d3-time-format.
datetime.isoformat({ sep: 'T', timespec: 'auto' })
Return a string representing the date and time in ISO 8601 format.
The optional argument sep is a one-character separator, placed between the date and time portions of the result.
The optional argument timespec specifies the number of additional components of the time to include. It can be one of the following:
auto
: Same asseconds
if millisecond is 0, same asmilliseconds
otherwise.hours
: Include thehour
in the two-digitHH
format.minutes
: Includehour
andminute
inHH:MM
format.seconds
: Includehour
,minute
, andsecond
inHH:MM:SS
format.milliseconds
: Include full time inHH:MM:SS.fff
format.
datetime.valueOf()
For a datetime instance d, d.valueOf()
is equivalent to d.timestamp()
.
datetime.toString()
For a datetime instance d, d.toString()
is equivalent to d.isoformat(' ')
.
datetime.ctime()
Return a string representing the date and time, such as Wed Dec 4 20:30:40 2002
.
datetime.strftime(format)
Return a string representing the date and time, controlled by an explicit format string.
time
Objects
A time
object represents a (local) time of day, independent of any particular day.
class time({ hour: 0, minute: 0, second: 0, millisecond: 0 })
All arguments are optional. The remaining arguments must be integers in the following range:
0 <= hour < 24
0 <= minute < 60
0 <= second < 60
0 <= millisecond < 1000
If an argument outside those ranges is given, RangeError
is thrown. All default to 0.
Class properties
time.min
The earliest representable time
, time(0, 0, 0, 0)
.
time.max
The latest representable time
, time(23, 59, 59, 999)
.
time.resolution
The smallest possible difference between non-equal time
objects, timedelta({ microseconds: 1 })
.
Instance properties (read-only):
time.hour
Between 0 and 23 inclusive.
time.minute
Between 0 and 59 inclusive.
time.second
Between 0 and 59 inclusive.
time.millisecond
Between 0 and 999 inclusive.
Other static method constructors
static method time.fromisoformat(time_string)
Return a time
corresponding to a time_string in any valid ISO 8601 format.
Instance methods
time.replace({ hour: this.hour, minute: this.minute, second: this.second, millisecond: this.millisecond })
Return a time
with the ame value, except for those attributes given new values by whichever arguments are specified.
time.isoformat(timespec='auto')
Return a string representing the time in ISO 8601 format. The optional argument timespec specifies the number of additional components of the time to include (the default is auto
). It can be one of the following:
auto
: Same asseconds
ifmillisecond
is 0, same asmilliseconds
otherwise.hours
: Include thehour
in the two-digitHH
format.minutes
: Includehour
andminute
inHH:MM
format.seconds
: Includehour
,minute
, andsecond
inHH:MM:SS
format.milliseconds
: Include full time inHH:MM:SS.fff
format.
datetime.valueOf()
Return the time in seconds.
time.toString()
For a time t, t.valueOf()
is equivalent to t.isoformat()
.
time.strftime(format)
Return a string representing the time, controlled by an explicit format string.