Skip to content

Latest commit

 

History

History
166 lines (136 loc) · 5.44 KB

dates.md

File metadata and controls

166 lines (136 loc) · 5.44 KB

Summary

Date classes supporting flexible calendars, date deltas and ranges.

Dependencies

Required: toolz, utils.

Optional: convertdate (for non-Western calendar support).

Documentation

Calendars

The Calendar class represents a Year-Month-Day style calendar. The following Calendar objects are predefined:

  • gregorian: proleptic Gregorian calendar [default]
  • julian: proleptic Julian calendar
  • isodate: astronomical Gregorian calendar
  • isoweek: ISO week calendar (where 'months' are actually weeks)
  • islamic: Islamic calendar
  • hebrew: Hebrew calendar
  • republican: French Republican calendar

All but the first three require convertdate to be installed. All support dates before AD 1.

Dates

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]

DateDeltas

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]

DateRanges

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