Date classes supporting flexible calendars, date deltas and ranges.
Optional: convertdate (for non-Western calendar support).
The Calendar
class represents a Year-Month-Day style calendar. The following Calendar
objects are predefined:
gregorian
: proleptic Gregorian calendar [default]julian
: proleptic Julian calendarisodate
: astronomical Gregorian calendarisoweek
: ISO week calendar (where 'months' are actually weeks)islamic
: Islamic calendarhebrew
: Hebrew calendarrepublican
: French Republican calendar
All but the first three require convertdate to be installed. All support dates before AD 1.
The Date
class represents a specific day in time, viewed under a specific calendar. Gregorian is the default.
>> Date()
Sunday, 16 July 2017 [Gregorian]
>> Date((2017,2,1)) # can also init from Date, datetime.date or ordinal
Wednesday, 1 February 2017 [Gregorian]
>> Date((2017,2,1), format="{y:04d}/{m:02d}/{d:02d}")
2017/02/01 [Gregorian]
>> Date((2017,1,32))
InvalidDate: Invalid Gregorian date: YMD(year=2017, month=1, day=32)
Other calendars can be specified:
>> Date((1917,10,25), calendar=julian)
Wednesday, 25 October 1917 [Julian]
>> Date((1917,10,25), calendar=julian).to_calenar(gregorian)
Wednesday, 7 November 1917 [Gregorian]
>> Date((1917,11,7)) == Date((1917,10,25), calendar=julian)
True
>> Date(calendar=isoweek)
Sunday, 2017-W28-7 [ISO week]
>> Date(calendar=islamic)
Sunday, 21 Shawwal 1438 AH [Islamic]
>> Date(calendar=republican)
Octidi, 28 Messidor 225 (Vesce) [French Republican]
Date details can be accessed directly:
>> Date((2017,2,1)).ymd
YMD(year=2017, month=2, day=1)
>> Date((2017,2,1)).weekday
3
>> Date((2017,2,1)).ordinal
736361
Dates support basic day arithmetic:
>> Date((2017,2,1)) + 100
Friday, 12 May 2017 [Gregorian]
>> Date() - Date((2017,2,1))
165
>> Date((2017,2,1)) < Date()
True
>> Date(1) # same ordinals as datetime
Monday, 1 January 1 [Gregorian]
>> Date(0) # AD/BC era has no year zero
Sunday, 31 December 1 BC [Gregorian]
The DateDelta
class represents a calendar-aware transition between dates. Unlike datetime.timedelta
, these do not have to be of constant size. There are two main implementations: DateInterval
and DateFilter
. Furthermore, deltas can be combined using addition, subtraction, negation and mulitplication by an integer.
DateInterval
represents an interval of a given number of years, months and days:
>> DateInterval(years=2, months=1)
DateInterval(years=1,months=2)
>> DateInterval.from_dates((1917,11,7), Date(), gregorian)
DateInterval(years=99,months=8,days=9)
>> Date((2017,3,31))
Friday, 31 March 2017 [Gregorian]
>> Date((2017,3,31)) + DateInterval(months=2)
Wednesday, 31 May 2017 [Gregorian]
>> Date((2017,3,31)) + DateInterval(months=1)*2
Thursday, 1 June 2017 [Gregorian] # since April has only 30 days
>> Date((2017,3,31)) - DateInterval(days=1,months=2,years=3)
Thursday, 30 January 2014 [Gregorian]
>> Date((5776,6,1), hebrew)
Wednesday, 1 Adar A 5776 [Hebrew] # a leap month
>> Date((5776,7,1), hebrew)
Friday, 1 Adar B 5776 [Hebrew] # the non-leap month, confusingly
>> Date((5776,6,1), hebrew) + DateInterval(years=1)
Monday, 1 Adar 5777 [Hebrew] # not a leap year
>> Date((5776,7,1), hebrew) + DateInterval(years=1)
Monday, 1 Adar 5777 [Hebrew]
>> Date((5776,6,1), hebrew) + DateInterval(years=1) - DateInterval(years=1)
Friday, 1 Adar B 5776 [Hebrew]
DateFilter
represents dates with a given property.
>> Date()
Sunday, 16 July 2017 [Gregorian]
>> Date() + DateFilter(lambda d: d.ymd.day == d.calendar.days_in_month(d.ymd.year, d.ymd.month))
Sunday, 30 July 2017 [Gregorian] # last day of the month
>> Date() + DateFilter(lambda d: d.weekday == 1 and d.ymd.day <= 7)
Monday, 7 August 2017 [Gregorian] # first Monday of the month
>> Date() - DateFilter(lambda d: d.weekday == 1 and d.ymd.day <= 7) * 2
Monday, 5 June 2017 [Gregorian]
The DateRange
class represents a date range that spans one or more days. Ranges can be specified directly via a start and end time combined with a calendar:
>> d = DateRange(Date()-10, Date())
>> d
6-16 July 2017 [Gregorian]
>> d.start
Thursday, 6 July 2017 [Gregorian]
>> d.end
Sunday, 16 July 2017 [Gregorian]
>> len(d)
11
>> Date() in d
True
>> d + DateInterval(months=1)
6-16 August 2017 [Gregorian]
>> d + (-DateInterval(months=1), DateInterval(months=1))
6 June-16 August 2017 [Gregorian]
Approximate dates can be specified using the ApproximateDate
class, with a base date and precision level between DatePrecision.DAY
and DatePrecision.MILLENNIUM
. This also accepts a circa parameter (as in c. 1917) to specify a wider range of plus-or-minus 2 precision units.
>> ApproximateDate(Date(), DatePrecision.MONTH)
July 2017 (month) [Gregorian]
>> len(_)
30
>> ApproximateDate(1997, DatePrecision.YEAR, circa=True)
c. 1997 (year) [Gregorian]
>> ApproximateDate(1997, DatePrecision.DECADE)
1990s (decade) [Gregorian]
>> Date() > ApproximateDate(1997, DatePrecision.DECADE)
True