You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1483 lines
40 KiB

dateutil examples
=================
.. contents::
relativedelta examples
----------------------
.. testsetup:: relativedelta
from datetime import *; from dateutil.relativedelta import *
import calendar
NOW = datetime(2003, 9, 17, 20, 54, 47, 282310)
TODAY = date(2003, 9, 17)
Let's begin our trip::
>>> from datetime import *; from dateutil.relativedelta import *
>>> import calendar
Store some values::
>>> NOW = datetime.now()
>>> TODAY = date.today()
>>> NOW
datetime.datetime(2003, 9, 17, 20, 54, 47, 282310)
>>> TODAY
datetime.date(2003, 9, 17)
Next month
.. doctest:: relativedelta
>>> NOW+relativedelta(months=+1)
datetime.datetime(2003, 10, 17, 20, 54, 47, 282310)
Next month, plus one week.
.. doctest:: relativedelta
>>> NOW+relativedelta(months=+1, weeks=+1)
datetime.datetime(2003, 10, 24, 20, 54, 47, 282310)
Next month, plus one week, at 10am.
.. doctest:: relativedelta
>>> TODAY+relativedelta(months=+1, weeks=+1, hour=10)
datetime.datetime(2003, 10, 24, 10, 0)
Here is another example using an absolute relativedelta. Notice the use of
year and month (both singular) which causes the values to be *replaced* in the
original datetime rather than performing an arithmetic operation on them.
.. doctest:: relativedelta
>>> NOW+relativedelta(year=1, month=1)
datetime.datetime(1, 1, 17, 20, 54, 47, 282310)
Let's try the other way around. Notice that the
hour setting we get in the relativedelta is relative,
since it's a difference, and the weeks parameter
has gone.
.. doctest:: relativedelta
>>> relativedelta(datetime(2003, 10, 24, 10, 0), TODAY)
relativedelta(months=+1, days=+7, hours=+10)
One month before one year.
.. doctest:: relativedelta
>>> NOW+relativedelta(years=+1, months=-1)
datetime.datetime(2004, 8, 17, 20, 54, 47, 282310)
How does it handle months with different numbers of days?
Notice that adding one month will never cross the month
boundary.
.. doctest:: relativedelta
>>> date(2003,1,27)+relativedelta(months=+1)
datetime.date(2003, 2, 27)
>>> date(2003,1,31)+relativedelta(months=+1)
datetime.date(2003, 2, 28)
>>> date(2003,1,31)+relativedelta(months=+2)
datetime.date(2003, 3, 31)
The logic for years is the same, even on leap years.
.. doctest:: relativedelta
>>> date(2000,2,28)+relativedelta(years=+1)
datetime.date(2001, 2, 28)
>>> date(2000,2,29)+relativedelta(years=+1)
datetime.date(2001, 2, 28)
>>> date(1999,2,28)+relativedelta(years=+1)
datetime.date(2000, 2, 28)
>>> date(1999,3,1)+relativedelta(years=+1)
datetime.date(2000, 3, 1)
>>> date(2001,2,28)+relativedelta(years=-1)
datetime.date(2000, 2, 28)
>>> date(2001,3,1)+relativedelta(years=-1)
datetime.date(2000, 3, 1)
Next friday
.. doctest:: relativedelta
>>> TODAY+relativedelta(weekday=FR)
datetime.date(2003, 9, 19)
>>> TODAY+relativedelta(weekday=calendar.FRIDAY)
datetime.date(2003, 9, 19)
Last friday in this month.
.. doctest:: relativedelta
>>> TODAY+relativedelta(day=31, weekday=FR(-1))
datetime.date(2003, 9, 26)
Next wednesday (it's today!).
.. doctest:: relativedelta
>>> TODAY+relativedelta(weekday=WE(+1))
datetime.date(2003, 9, 17)
Next wednesday, but not today.
.. doctest:: relativedelta
>>> TODAY+relativedelta(days=+1, weekday=WE(+1))
datetime.date(2003, 9, 24)
Following
`ISO year week number notation <https://www.cl.cam.ac.uk/~mgk25/iso-time.html>`_
find the first day of the 15th week of 1997.
.. doctest:: relativedelta
>>> datetime(1997,1,1)+relativedelta(day=4, weekday=MO(-1), weeks=+14)
datetime.datetime(1997, 4, 7, 0, 0)
How long ago has the millennium changed?
.. doctest:: relativedelta
:options: +NORMALIZE_WHITESPACE
>>> relativedelta(NOW, date(2001,1,1))
relativedelta(years=+2, months=+8, days=+16,
hours=+20, minutes=+54, seconds=+47, microseconds=+282310)
How old is John?
.. doctest:: relativedelta
:options: +NORMALIZE_WHITESPACE
>>> johnbirthday = datetime(1978, 4, 5, 12, 0)
>>> relativedelta(NOW, johnbirthday)
relativedelta(years=+25, months=+5, days=+12,
hours=+8, minutes=+54, seconds=+47, microseconds=+282310)
It works with dates too.
.. doctest:: relativedelta
>>> relativedelta(TODAY, johnbirthday)
relativedelta(years=+25, months=+5, days=+11, hours=+12)
Obtain today's date using the yearday:
.. doctest:: relativedelta
>>> date(2003, 1, 1)+relativedelta(yearday=260)
datetime.date(2003, 9, 17)
We can use today's date, since yearday should be absolute
in the given year:
.. doctest:: relativedelta
>>> TODAY+relativedelta(yearday=260)
datetime.date(2003, 9, 17)
Last year it should be in the same day:
.. doctest:: relativedelta
>>> date(2002, 1, 1)+relativedelta(yearday=260)
datetime.date(2002, 9, 17)
But not in a leap year:
.. doctest:: relativedelta
>>> date(2000, 1, 1)+relativedelta(yearday=260)
datetime.date(2000, 9, 16)
We can use the non-leap year day to ignore this:
.. doctest:: relativedelta
>>> date(2000, 1, 1)+relativedelta(nlyearday=260)
datetime.date(2000, 9, 17)
rrule examples
--------------
These examples were converted from the RFC.
Prepare the environment.
.. testsetup:: rrule
from dateutil.rrule import *
from dateutil.parser import *
from datetime import *
import pprint
import sys
sys.displayhook = pprint.pprint
.. doctest:: rrule
>>> from dateutil.rrule import *
>>> from dateutil.parser import *
>>> from datetime import *
>>> import pprint
>>> import sys
>>> sys.displayhook = pprint.pprint
Daily, for 10 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(DAILY, count=10,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 3, 9, 0),
datetime.datetime(1997, 9, 4, 9, 0),
datetime.datetime(1997, 9, 5, 9, 0),
datetime.datetime(1997, 9, 6, 9, 0),
datetime.datetime(1997, 9, 7, 9, 0),
datetime.datetime(1997, 9, 8, 9, 0),
datetime.datetime(1997, 9, 9, 9, 0),
datetime.datetime(1997, 9, 10, 9, 0),
datetime.datetime(1997, 9, 11, 9, 0)]
Daily until December 24, 1997
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE, +ELLIPSIS
>>> list(rrule(DAILY,
... dtstart=parse("19970902T090000"),
... until=parse("19971224T000000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 3, 9, 0),
datetime.datetime(1997, 9, 4, 9, 0),
...
datetime.datetime(1997, 12, 21, 9, 0),
datetime.datetime(1997, 12, 22, 9, 0),
datetime.datetime(1997, 12, 23, 9, 0)]
Every other day, 5 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(DAILY, interval=2, count=5,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 4, 9, 0),
datetime.datetime(1997, 9, 6, 9, 0),
datetime.datetime(1997, 9, 8, 9, 0),
datetime.datetime(1997, 9, 10, 9, 0)]
Every 10 days, 5 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(DAILY, interval=10, count=5,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 12, 9, 0),
datetime.datetime(1997, 9, 22, 9, 0),
datetime.datetime(1997, 10, 2, 9, 0),
datetime.datetime(1997, 10, 12, 9, 0)]
Everyday in January, for 3 years.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE, +ELLIPSIS
>>> list(rrule(YEARLY, bymonth=1, byweekday=range(7),
... dtstart=parse("19980101T090000"),
... until=parse("20000131T090000")))
[datetime.datetime(1998, 1, 1, 9, 0),
datetime.datetime(1998, 1, 2, 9, 0),
...
datetime.datetime(1998, 1, 30, 9, 0),
datetime.datetime(1998, 1, 31, 9, 0),
datetime.datetime(1999, 1, 1, 9, 0),
datetime.datetime(1999, 1, 2, 9, 0),
...
datetime.datetime(1999, 1, 30, 9, 0),
datetime.datetime(1999, 1, 31, 9, 0),
datetime.datetime(2000, 1, 1, 9, 0),
datetime.datetime(2000, 1, 2, 9, 0),
...
datetime.datetime(2000, 1, 30, 9, 0),
datetime.datetime(2000, 1, 31, 9, 0)]
Same thing, in another way.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE, +ELLIPSIS
>>> list(rrule(DAILY, bymonth=1,
... dtstart=parse("19980101T090000"),
... until=parse("20000131T090000")))
[datetime.datetime(1998, 1, 1, 9, 0),
...
datetime.datetime(2000, 1, 31, 9, 0)]
Weekly for 10 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(WEEKLY, count=10,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 9, 9, 0),
datetime.datetime(1997, 9, 16, 9, 0),
datetime.datetime(1997, 9, 23, 9, 0),
datetime.datetime(1997, 9, 30, 9, 0),
datetime.datetime(1997, 10, 7, 9, 0),
datetime.datetime(1997, 10, 14, 9, 0),
datetime.datetime(1997, 10, 21, 9, 0),
datetime.datetime(1997, 10, 28, 9, 0),
datetime.datetime(1997, 11, 4, 9, 0)]
Every other week, 6 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(WEEKLY, interval=2, count=6,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 16, 9, 0),
datetime.datetime(1997, 9, 30, 9, 0),
datetime.datetime(1997, 10, 14, 9, 0),
datetime.datetime(1997, 10, 28, 9, 0),
datetime.datetime(1997, 11, 11, 9, 0)]
Weekly on Tuesday and Thursday for 5 weeks.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(WEEKLY, count=10, wkst=SU, byweekday=(TU,TH),
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 4, 9, 0),
datetime.datetime(1997, 9, 9, 9, 0),
datetime.datetime(1997, 9, 11, 9, 0),
datetime.datetime(1997, 9, 16, 9, 0),
datetime.datetime(1997, 9, 18, 9, 0),
datetime.datetime(1997, 9, 23, 9, 0),
datetime.datetime(1997, 9, 25, 9, 0),
datetime.datetime(1997, 9, 30, 9, 0),
datetime.datetime(1997, 10, 2, 9, 0)]
Every other week on Tuesday and Thursday, for 8 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(WEEKLY, interval=2, count=8,
... wkst=SU, byweekday=(TU,TH),
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 4, 9, 0),
datetime.datetime(1997, 9, 16, 9, 0),
datetime.datetime(1997, 9, 18, 9, 0),
datetime.datetime(1997, 9, 30, 9, 0),
datetime.datetime(1997, 10, 2, 9, 0),
datetime.datetime(1997, 10, 14, 9, 0),
datetime.datetime(1997, 10, 16, 9, 0)]
Monthly on the 1st Friday for ten occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, count=10, byweekday=FR(1),
... dtstart=parse("19970905T090000")))
[datetime.datetime(1997, 9, 5, 9, 0),
datetime.datetime(1997, 10, 3, 9, 0),
datetime.datetime(1997, 11, 7, 9, 0),
datetime.datetime(1997, 12, 5, 9, 0),
datetime.datetime(1998, 1, 2, 9, 0),
datetime.datetime(1998, 2, 6, 9, 0),
datetime.datetime(1998, 3, 6, 9, 0),
datetime.datetime(1998, 4, 3, 9, 0),
datetime.datetime(1998, 5, 1, 9, 0),
datetime.datetime(1998, 6, 5, 9, 0)]
Every other month on the 1st and last Sunday of the month for 10 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, interval=2, count=10,
... byweekday=(SU(1), SU(-1)),
... dtstart=parse("19970907T090000")))
[datetime.datetime(1997, 9, 7, 9, 0),
datetime.datetime(1997, 9, 28, 9, 0),
datetime.datetime(1997, 11, 2, 9, 0),
datetime.datetime(1997, 11, 30, 9, 0),
datetime.datetime(1998, 1, 4, 9, 0),
datetime.datetime(1998, 1, 25, 9, 0),
datetime.datetime(1998, 3, 1, 9, 0),
datetime.datetime(1998, 3, 29, 9, 0),
datetime.datetime(1998, 5, 3, 9, 0),
datetime.datetime(1998, 5, 31, 9, 0)]
Monthly on the second to last Monday of the month for 6 months.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, count=6, byweekday=MO(-2),
... dtstart=parse("19970922T090000")))
[datetime.datetime(1997, 9, 22, 9, 0),
datetime.datetime(1997, 10, 20, 9, 0),
datetime.datetime(1997, 11, 17, 9, 0),
datetime.datetime(1997, 12, 22, 9, 0),
datetime.datetime(1998, 1, 19, 9, 0),
datetime.datetime(1998, 2, 16, 9, 0)]
Monthly on the third to the last day of the month, for 6 months.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, count=6, bymonthday=-3,
... dtstart=parse("19970928T090000")))
[datetime.datetime(1997, 9, 28, 9, 0),
datetime.datetime(1997, 10, 29, 9, 0),
datetime.datetime(1997, 11, 28, 9, 0),
datetime.datetime(1997, 12, 29, 9, 0),
datetime.datetime(1998, 1, 29, 9, 0),
datetime.datetime(1998, 2, 26, 9, 0)]
Monthly on the 2nd and 15th of the month for 5 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, count=5, bymonthday=(2,15),
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 15, 9, 0),
datetime.datetime(1997, 10, 2, 9, 0),
datetime.datetime(1997, 10, 15, 9, 0),
datetime.datetime(1997, 11, 2, 9, 0)]
Monthly on the first and last day of the month for 3 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, count=5, bymonthday=(-1,1,),
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 30, 9, 0),
datetime.datetime(1997, 10, 1, 9, 0),
datetime.datetime(1997, 10, 31, 9, 0),
datetime.datetime(1997, 11, 1, 9, 0),
datetime.datetime(1997, 11, 30, 9, 0)]
Every 18 months on the 10th thru 15th of the month for 10 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, interval=18, count=10,
... bymonthday=range(10,16),
... dtstart=parse("19970910T090000")))
[datetime.datetime(1997, 9, 10, 9, 0),
datetime.datetime(1997, 9, 11, 9, 0),
datetime.datetime(1997, 9, 12, 9, 0),
datetime.datetime(1997, 9, 13, 9, 0),
datetime.datetime(1997, 9, 14, 9, 0),
datetime.datetime(1997, 9, 15, 9, 0),
datetime.datetime(1999, 3, 10, 9, 0),
datetime.datetime(1999, 3, 11, 9, 0),
datetime.datetime(1999, 3, 12, 9, 0),
datetime.datetime(1999, 3, 13, 9, 0)]
Every Tuesday, every other month, 6 occurences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, interval=2, count=6, byweekday=TU,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 9, 9, 0),
datetime.datetime(1997, 9, 16, 9, 0),
datetime.datetime(1997, 9, 23, 9, 0),
datetime.datetime(1997, 9, 30, 9, 0),
datetime.datetime(1997, 11, 4, 9, 0)]
Yearly in June and July for 10 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(YEARLY, count=4, bymonth=(6,7),
... dtstart=parse("19970610T090000")))
[datetime.datetime(1997, 6, 10, 9, 0),
datetime.datetime(1997, 7, 10, 9, 0),
datetime.datetime(1998, 6, 10, 9, 0),
datetime.datetime(1998, 7, 10, 9, 0)]
Every 3rd year on the 1st, 100th and 200th day for 4 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(YEARLY, count=4, interval=3, byyearday=(1,100,200),
... dtstart=parse("19970101T090000")))
[datetime.datetime(1997, 1, 1, 9, 0),
datetime.datetime(1997, 4, 10, 9, 0),
datetime.datetime(1997, 7, 19, 9, 0),
datetime.datetime(2000, 1, 1, 9, 0)]
Every 20th Monday of the year, 3 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(YEARLY, count=3, byweekday=MO(20),
... dtstart=parse("19970519T090000")))
[datetime.datetime(1997, 5, 19, 9, 0),
datetime.datetime(1998, 5, 18, 9, 0),
datetime.datetime(1999, 5, 17, 9, 0)]
Monday of week number 20 (where the default start of the week is Monday),
3 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(YEARLY, count=3, byweekno=20, byweekday=MO,
... dtstart=parse("19970512T090000")))
[datetime.datetime(1997, 5, 12, 9, 0),
datetime.datetime(1998, 5, 11, 9, 0),
datetime.datetime(1999, 5, 17, 9, 0)]
The week number 1 may be in the last year.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(WEEKLY, count=3, byweekno=1, byweekday=MO,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 12, 29, 9, 0),
datetime.datetime(1999, 1, 4, 9, 0),
datetime.datetime(2000, 1, 3, 9, 0)]
And the week numbers greater than 51 may be in the next year.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(WEEKLY, count=3, byweekno=52, byweekday=SU,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 12, 28, 9, 0),
datetime.datetime(1998, 12, 27, 9, 0),
datetime.datetime(2000, 1, 2, 9, 0)]
Only some years have week number 53:
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(WEEKLY, count=3, byweekno=53, byweekday=MO,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1998, 12, 28, 9, 0),
datetime.datetime(2004, 12, 27, 9, 0),
datetime.datetime(2009, 12, 28, 9, 0)]
Every Friday the 13th, 4 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(YEARLY, count=4, byweekday=FR, bymonthday=13,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1998, 2, 13, 9, 0),
datetime.datetime(1998, 3, 13, 9, 0),
datetime.datetime(1998, 11, 13, 9, 0),
datetime.datetime(1999, 8, 13, 9, 0)]
Every four years, the first Tuesday after a Monday in November,
3 occurrences (U.S. Presidential Election day):
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(YEARLY, interval=4, count=3, bymonth=11,
... byweekday=TU, bymonthday=(2,3,4,5,6,7,8),
... dtstart=parse("19961105T090000")))
[datetime.datetime(1996, 11, 5, 9, 0),
datetime.datetime(2000, 11, 7, 9, 0),
datetime.datetime(2004, 11, 2, 9, 0)]
The 3rd instance into the month of one of Tuesday, Wednesday or
Thursday, for the next 3 months:
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, count=3, byweekday=(TU,WE,TH),
... bysetpos=3, dtstart=parse("19970904T090000")))
[datetime.datetime(1997, 9, 4, 9, 0),
datetime.datetime(1997, 10, 7, 9, 0),
datetime.datetime(1997, 11, 6, 9, 0)]
The 2nd to last weekday of the month, 3 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MONTHLY, count=3, byweekday=(MO,TU,WE,TH,FR),
... bysetpos=-2, dtstart=parse("19970929T090000")))
[datetime.datetime(1997, 9, 29, 9, 0),
datetime.datetime(1997, 10, 30, 9, 0),
datetime.datetime(1997, 11, 27, 9, 0)]
Every 3 hours from 9:00 AM to 5:00 PM on a specific day.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(HOURLY, interval=3,
... dtstart=parse("19970902T090000"),
... until=parse("19970902T170000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 2, 12, 0),
datetime.datetime(1997, 9, 2, 15, 0)]
Every 15 minutes for 6 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MINUTELY, interval=15, count=6,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 2, 9, 15),
datetime.datetime(1997, 9, 2, 9, 30),
datetime.datetime(1997, 9, 2, 9, 45),
datetime.datetime(1997, 9, 2, 10, 0),
datetime.datetime(1997, 9, 2, 10, 15)]
Every hour and a half for 4 occurrences.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(MINUTELY, interval=90, count=4,
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 2, 10, 30),
datetime.datetime(1997, 9, 2, 12, 0),
datetime.datetime(1997, 9, 2, 13, 30)]
Every 20 minutes from 9:00 AM to 4:40 PM for two days.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE, +ELLIPSIS
>>> list(rrule(MINUTELY, interval=20, count=48,
... byhour=range(9,17), byminute=(0,20,40),
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 2, 9, 20),
...
datetime.datetime(1997, 9, 2, 16, 20),
datetime.datetime(1997, 9, 2, 16, 40),
datetime.datetime(1997, 9, 3, 9, 0),
datetime.datetime(1997, 9, 3, 9, 20),
...
datetime.datetime(1997, 9, 3, 16, 20),
datetime.datetime(1997, 9, 3, 16, 40)]
An example where the days generated makes a difference because of `wkst`.
.. doctest:: rrule
:options: +NORMALIZE_WHITESPACE
>>> list(rrule(WEEKLY, interval=2, count=4,
... byweekday=(TU,SU), wkst=MO,
... dtstart=parse("19970805T090000")))
[datetime.datetime(1997, 8, 5, 9, 0),
datetime.datetime(1997, 8, 10, 9, 0),
datetime.datetime(1997, 8, 19, 9, 0),
datetime.datetime(1997, 8, 24, 9, 0)]
>>> list(rrule(WEEKLY, interval=2, count=4,
... byweekday=(TU,SU), wkst=SU,
... dtstart=parse("19970805T090000")))
[datetime.datetime(1997, 8, 5, 9, 0),
datetime.datetime(1997, 8, 17, 9, 0),
datetime.datetime(1997, 8, 19, 9, 0),
datetime.datetime(1997, 8, 31, 9, 0)]
rruleset examples
-----------------
Daily, for 7 days, jumping Saturday and Sunday occurrences.
.. testsetup:: rruleset
import datetime
from dateutil.parser import parse
from dateutil.rrule import rrule, rruleset
from dateutil.rrule import YEARLY, MONTHLY, WEEKLY, DAILY
from dateutil.rrule import MO, TU, WE, TH, FR, SA, SU
import pprint
import sys
sys.displayhook = pprint.pprint
.. doctest:: rruleset
:options: +NORMALIZE_WHITESPACE
>>> set = rruleset()
>>> set.rrule(rrule(DAILY, count=7,
... dtstart=parse("19970902T090000")))
>>> set.exrule(rrule(YEARLY, byweekday=(SA,SU),
... dtstart=parse("19970902T090000")))
>>> list(set)
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 3, 9, 0),
datetime.datetime(1997, 9, 4, 9, 0),
datetime.datetime(1997, 9, 5, 9, 0),
datetime.datetime(1997, 9, 8, 9, 0)]
Weekly, for 4 weeks, plus one time on day 7, and not on day 16.
.. doctest:: rruleset
:options: +NORMALIZE_WHITESPACE
>>> set = rruleset()
>>> set.rrule(rrule(WEEKLY, count=4,
... dtstart=parse("19970902T090000")))
>>> set.rdate(datetime.datetime(1997, 9, 7, 9, 0))
>>> set.exdate(datetime.datetime(1997, 9, 16, 9, 0))
>>> list(set)
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 7, 9, 0),
datetime.datetime(1997, 9, 9, 9, 0),
datetime.datetime(1997, 9, 23, 9, 0)]
rrulestr() examples
-------------------
Every 10 days, 5 occurrences.
.. testsetup:: rrulestr
from dateutil.parser import parse
from dateutil.rrule import rruleset, rrulestr
import pprint
import sys
sys.displayhook = pprint.pprint
.. doctest:: rrulestr
:options: +NORMALIZE_WHITESPACE
>>> list(rrulestr("""
... DTSTART:19970902T090000
... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
... """))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 12, 9, 0),
datetime.datetime(1997, 9, 22, 9, 0),
datetime.datetime(1997, 10, 2, 9, 0),
datetime.datetime(1997, 10, 12, 9, 0)]
Same thing, but passing only the `RRULE` value.
.. doctest:: rrulestr
:options: +NORMALIZE_WHITESPACE
>>> list(rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5",
... dtstart=parse("19970902T090000")))
[datetime.datetime(1997, 9, 2, 9, 0),
datetime.datetime(1997, 9, 12, 9, 0),
datetime.datetime(1997, 9, 22, 9, 0),
datetime.datetime(1997, 10, 2, 9, 0),
datetime.datetime(1997, 10, 12, 9, 0)]
Notice that when using a single rule, it returns an
`rrule` instance, unless `forceset` was used.
.. doctest:: rrulestr
:options: +ELLIPSIS
>>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5")
<dateutil.rrule.rrule object at 0x...>
>>> rrulestr("""
... DTSTART:19970902T090000
... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
... """)
<dateutil.rrule.rrule object at 0x...>
>>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", forceset=True)
<dateutil.rrule.rruleset object at 0x...>
But when an `rruleset` is needed, it is automatically used.
.. doctest:: rrulestr
:options: +ELLIPSIS
>>> rrulestr("""
... DTSTART:19970902T090000
... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
... RRULE:FREQ=DAILY;INTERVAL=5;COUNT=3
... """)
<dateutil.rrule.rruleset object at 0x...>
parse examples
--------------
The following code will prepare the environment:
.. doctest:: tz
>>> from dateutil.parser import *
>>> from dateutil.tz import *
>>> from datetime import *
>>> TZOFFSETS = {"BRST": -10800}
>>> BRSTTZ = tzoffset("BRST", -10800)
>>> DEFAULT = datetime(2003, 9, 25)
Some simple examples based on the `date` command, using the
`ZOFFSET` dictionary to provide the BRST timezone offset.
.. doctest:: tz
:options: +NORMALIZE_WHITESPACE
>>> parse("Thu Sep 25 10:36:28 BRST 2003", tzinfos=TZOFFSETS)
datetime.datetime(2003, 9, 25, 10, 36, 28,
tzinfo=tzoffset('BRST', -10800))
>>> parse("2003 10:36:28 BRST 25 Sep Thu", tzinfos=TZOFFSETS)
datetime.datetime(2003, 9, 25, 10, 36, 28,
tzinfo=tzoffset('BRST', -10800))
Notice that since BRST is my local timezone, parsing it without
further timezone settings will yield a `tzlocal` timezone.
.. doctest:: tz
>>> parse("Thu Sep 25 10:36:28 BRST 2003")
datetime.datetime(2003, 9, 25, 10, 36, 28, tzinfo=tzlocal())
We can also ask to ignore the timezone explicitly:
.. doctest:: tz
>>> parse("Thu Sep 25 10:36:28 BRST 2003", ignoretz=True)
datetime.datetime(2003, 9, 25, 10, 36, 28)
That's the same as processing a string without timezone:
.. doctest:: tz
>>> parse("Thu Sep 25 10:36:28 2003")
datetime.datetime(2003, 9, 25, 10, 36, 28)
Without the year, but passing our `DEFAULT` datetime to return
the same year, no mattering what year we currently are in:
.. doctest:: tz
>>> parse("Thu Sep 25 10:36:28", default=DEFAULT)
datetime.datetime(2003, 9, 25, 10, 36, 28)
Strip it further:
.. doctest:: tz
>>> parse("Thu Sep 10:36:28", default=DEFAULT)
datetime.datetime(2003, 9, 25, 10, 36, 28)
>>> parse("Thu 10:36:28", default=DEFAULT)
datetime.datetime(2003, 9, 25, 10, 36, 28)
>>> parse("Thu 10:36", default=DEFAULT)
datetime.datetime(2003, 9, 25, 10, 36)
>>> parse("10:36", default=DEFAULT)
datetime.datetime(2003, 9, 25, 10, 36)
Strip in a different way:
.. doctest:: tz
>>> parse("Thu Sep 25 2003")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("Sep 25 2003")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("Sep 2003", default=DEFAULT)
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("Sep", default=DEFAULT)
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("2003", default=DEFAULT)
datetime.datetime(2003, 9, 25, 0, 0)
Another format, based on `date -R` (RFC822):
.. doctest:: tz
:options: +NORMALIZE_WHITESPACE
>>> parse("Thu, 25 Sep 2003 10:49:41 -0300")
datetime.datetime(2003, 9, 25, 10, 49, 41,
tzinfo=tzoffset(None, -10800))
ISO format:
.. doctest:: tz
:options: +NORMALIZE_WHITESPACE
>>> parse("2003-09-25T10:49:41.5-03:00")
datetime.datetime(2003, 9, 25, 10, 49, 41, 500000,
tzinfo=tzoffset(None, -10800))
Some variations:
.. doctest:: tz
>>> parse("2003-09-25T10:49:41")
datetime.datetime(2003, 9, 25, 10, 49, 41)
>>> parse("2003-09-25T10:49")
datetime.datetime(2003, 9, 25, 10, 49)
>>> parse("2003-09-25T10")
datetime.datetime(2003, 9, 25, 10, 0)
>>> parse("2003-09-25")
datetime.datetime(2003, 9, 25, 0, 0)
ISO format, without separators:
.. doctest:: tz
:options: +NORMALIZE_WHITESPACE
>>> parse("20030925T104941.5-0300")
datetime.datetime(2003, 9, 25, 10, 49, 41, 500000,
tzinfo=tzoffset(None, -10800))
>>> parse("20030925T104941-0300")
datetime.datetime(2003, 9, 25, 10, 49, 41,
tzinfo=tzoffset(None, -10800))
>>> parse("20030925T104941")
datetime.datetime(2003, 9, 25, 10, 49, 41)
>>> parse("20030925T1049")
datetime.datetime(2003, 9, 25, 10, 49)
>>> parse("20030925T10")
datetime.datetime(2003, 9, 25, 10, 0)
>>> parse("20030925")
datetime.datetime(2003, 9, 25, 0, 0)
Everything together.
.. doctest:: tz
>>> parse("199709020900")
datetime.datetime(1997, 9, 2, 9, 0)
>>> parse("19970902090059")
datetime.datetime(1997, 9, 2, 9, 0, 59)
Different date orderings:
.. doctest:: tz
>>> parse("2003-09-25")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("2003-Sep-25")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("25-Sep-2003")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("Sep-25-2003")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("09-25-2003")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("25-09-2003")
datetime.datetime(2003, 9, 25, 0, 0)
Check some ambiguous dates:
.. doctest:: tz
>>> parse("10-09-2003")
datetime.datetime(2003, 10, 9, 0, 0)
>>> parse("10-09-2003", dayfirst=True)
datetime.datetime(2003, 9, 10, 0, 0)
>>> parse("10-09-03")
datetime.datetime(2003, 10, 9, 0, 0)
>>> parse("10-09-03", yearfirst=True)
datetime.datetime(2010, 9, 3, 0, 0)
Other date separators are allowed:
.. doctest:: tz
>>> parse("2003.Sep.25")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("2003/09/25")
datetime.datetime(2003, 9, 25, 0, 0)
Even with spaces:
.. doctest:: tz
>>> parse("2003 Sep 25")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("2003 09 25")
datetime.datetime(2003, 9, 25, 0, 0)
Hours with letters work:
.. doctest:: tz
>>> parse("10h36m28.5s", default=DEFAULT)
datetime.datetime(2003, 9, 25, 10, 36, 28, 500000)
>>> parse("01s02h03m", default=DEFAULT)
datetime.datetime(2003, 9, 25, 2, 3, 1)
>>> parse("01h02m03", default=DEFAULT)
datetime.datetime(2003, 9, 25, 1, 2, 3)
>>> parse("01h02", default=DEFAULT)
datetime.datetime(2003, 9, 25, 1, 2)
>>> parse("01h02s", default=DEFAULT)
datetime.datetime(2003, 9, 25, 1, 0, 2)
With AM/PM:
.. doctest:: tz
>>> parse("10h am", default=DEFAULT)
datetime.datetime(2003, 9, 25, 10, 0)
>>> parse("10pm", default=DEFAULT)
datetime.datetime(2003, 9, 25, 22, 0)
>>> parse("12:00am", default=DEFAULT)
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("12pm", default=DEFAULT)
datetime.datetime(2003, 9, 25, 12, 0)
Some special treating for ''pertain'' relations:
.. doctest:: tz
>>> parse("Sep 03", default=DEFAULT)
datetime.datetime(2003, 9, 3, 0, 0)
>>> parse("Sep of 03", default=DEFAULT)
datetime.datetime(2003, 9, 25, 0, 0)
Fuzzy parsing:
.. doctest:: tz
:options: +NORMALIZE_WHITESPACE
>>> s = "Today is 25 of September of 2003, exactly " \
... "at 10:49:41 with timezone -03:00."
>>> parse(s, fuzzy=True)
datetime.datetime(2003, 9, 25, 10, 49, 41,
tzinfo=tzoffset(None, -10800))
Other random formats:
.. doctest:: tz
>>> parse("Wed, July 10, '96")
datetime.datetime(1996, 7, 10, 0, 0)
>>> parse("1996.07.10 AD at 15:08:56 PDT", ignoretz=True)
datetime.datetime(1996, 7, 10, 15, 8, 56)
>>> parse("Tuesday, April 12, 1952 AD 3:30:42pm PST", ignoretz=True)
datetime.datetime(1952, 4, 12, 15, 30, 42)
>>> parse("November 5, 1994, 8:15:30 am EST", ignoretz=True)
datetime.datetime(1994, 11, 5, 8, 15, 30)
>>> parse("3rd of May 2001")
datetime.datetime(2001, 5, 3, 0, 0)
>>> parse("5:50 A.M. on June 13, 1990")
datetime.datetime(1990, 6, 13, 5, 50)
Override parserinfo with a custom parserinfo
.. doctest:: tz
>>> from dateutil.parser import parse, parserinfo
>>> class CustomParserInfo(parserinfo):
... # e.g. edit a property of parserinfo to allow a custom 12 hour format
... AMPM = [("am", "a", "xm"), ("pm", "p")]
>>> parse('2018-06-08 12:06:58 XM', parserinfo=CustomParserInfo())
datetime.datetime(2018, 6, 8, 0, 6, 58)
tzutc examples
--------------
.. doctest:: tzutc
>>> from datetime import *
>>> from dateutil.tz import *
>>> datetime.now()
datetime.datetime(2003, 9, 27, 9, 40, 1, 521290)
>>> datetime.now(tzutc())
datetime.datetime(2003, 9, 27, 12, 40, 12, 156379, tzinfo=tzutc())
>>> datetime.now(tzutc()).tzname()
'UTC'
tzoffset examples
-----------------
.. doctest:: tzoffset
:options: +NORMALIZE_WHITESPACE
>>> from datetime import *
>>> from dateutil.tz import *
>>> datetime.now(tzoffset("BRST", -10800))
datetime.datetime(2003, 9, 27, 9, 52, 43, 624904,
tzinfo=tzinfo=tzoffset('BRST', -10800))
>>> datetime.now(tzoffset("BRST", -10800)).tzname()
'BRST'
>>> datetime.now(tzoffset("BRST", -10800)).astimezone(tzutc())
datetime.datetime(2003, 9, 27, 12, 53, 11, 446419,
tzinfo=tzutc())
tzlocal examples
----------------
.. doctest:: tzlocal
>>> from datetime import *
>>> from dateutil.tz import *
>>> datetime.now(tzlocal())
datetime.datetime(2003, 9, 27, 10, 1, 43, 673605,
tzinfo=tzlocal())
>>> datetime.now(tzlocal()).tzname()
'BRST'
>>> datetime.now(tzlocal()).astimezone(tzoffset(None, 0))
datetime.datetime(2003, 9, 27, 13, 3, 0, 11493,
tzinfo=tzoffset(None, 0))
tzstr examples
--------------
Here are examples of the recognized formats:
* `EST5EDT`
* `EST5EDT4,M4.1.0/02:00:00,M10-5-0/02:00`
* `EST5EDT4,95/02:00:00,298/02:00`
* `EST5EDT4,J96/02:00:00,J299/02:00`
Notice that if daylight information is not present, but a
daylight abbreviation was provided, `tzstr` will follow the
convention of using the first sunday of April to start daylight
saving, and the last sunday of October to end it. If start or
end time is not present, 2AM will be used, and if the daylight
offset is not present, the standard offset plus one hour will
be used. This convention is the same as used in the GNU libc.
This also means that some of the above examples are exactly
equivalent, and all of these examples are equivalent
in the year of 2003.
Here is the example mentioned in the
[https://docs.python.org/3/library/time.html time module documentation].
.. testsetup:: tzstr
import os
import time
from datetime import datetime
from dateutil.tz import tzstr
.. doctest:: tzstr
>>> os.environ['TZ'] = 'EST+05EDT,M4.1.0,M10.5.0'
>>> time.tzset()
>>> time.strftime('%X %x %Z')
'02:07:36 05/08/03 EDT'
>>> os.environ['TZ'] = 'AEST-10AEDT-11,M10.5.0,M3.5.0'
>>> time.tzset()
>>> time.strftime('%X %x %Z')
'16:08:12 05/08/03 AEST'
And here is an example showing the same information using `tzstr`,
without touching system settings.
.. doctest:: tzstr
>>> tz1 = tzstr('EST+05EDT,M4.1.0,M10.5.0')
>>> tz2 = tzstr('AEST-10AEDT-11,M10.5.0,M3.5.0')
>>> dt = datetime(2003, 5, 8, 2, 7, 36, tzinfo=tz1)
>>> dt.strftime('%X %x %Z')
'02:07:36 05/08/03 EDT'
>>> dt.astimezone(tz2).strftime('%X %x %Z')
'16:07:36 05/08/03 AEST'
Are these really equivalent?
.. doctest:: tzstr
>>> tzstr('EST5EDT') == tzstr('EST5EDT,M4.1.0,M10.5.0')
True
Check the daylight limit.
.. doctest:: tzstr
>>> tz = tzstr('EST+05EDT,M4.1.0,M10.5.0')
>>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname()
'EST'
>>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname()
'EDT'
>>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname()
'EDT'
>>> datetime(2003, 10, 26, 2, 00, tzinfo=tz).tzname()
'EST'
tzrange examples
----------------
.. testsetup:: tzrange
from dateutil.tz import tzrange, tzstr
.. doctest:: tzrange
>>> tzstr('EST5EDT') == tzrange("EST", -18000, "EDT")
True
>>> from dateutil.relativedelta import *
>>> range1 = tzrange("EST", -18000, "EDT")
>>> range2 = tzrange("EST", -18000, "EDT", -14400,
... relativedelta(hours=+2, month=4, day=1,
... weekday=SU(+1)),
... relativedelta(hours=+1, month=10, day=31,
... weekday=SU(-1)))
>>> tzstr('EST5EDT') == range1 == range2
True
Notice a minor detail in the last example: while the DST should end
at 2AM, the delta will catch 1AM. That's because the daylight saving
time should end at 2AM standard time (the difference between STD and
DST is 1h in the given example) instead of the DST time. That's how
the `tzinfo` subtypes should deal with the extra hour that happens
when going back to the standard time. Check
[https://docs.python.org/3/library/datetime.html#datetime.tzinfo tzinfo documentation]
for more information.
tzfile examples
---------------
.. testsetup:: tzfile
from datetime import datetime
from dateutil.tz import tzfile, tzutc
.. doctest:: tzfile
:options: +NORMALIZE_WHITESPACE
>>> tz = tzfile("/etc/localtime")
>>> datetime.now(tz)
datetime.datetime(2003, 9, 27, 12, 3, 48, 392138,
tzinfo=tzfile('/etc/localtime'))
>>> datetime.now(tz).astimezone(tzutc())
datetime.datetime(2003, 9, 27, 15, 3, 53, 70863,
tzinfo=tzutc())
>>> datetime.now(tz).tzname()
'BRST'
>>> datetime(2003, 1, 1, tzinfo=tz).tzname()
'BRDT'
Check the daylight limit.
.. doctest:: tzfile
>>> tz = tzfile('/usr/share/zoneinfo/EST5EDT')
>>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname()
'EST'
>>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname()
'EDT'
>>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname()
'EDT'
>>> datetime(2003, 10, 26, 1, 00, tzinfo=tz).tzname()
'EST'
tzical examples
---------------
Here is a sample file extracted from the RFC. This file defines
the `EST5EDT` timezone, and will be used in the following example.
.. include:: samples/EST5EDT.ics
:literal:
And here is an example exploring a `tzical` type:
.. doctest:: tzfile
>>> from dateutil.tz import *; from datetime import *
>>> tz = tzical('samples/EST5EDT.ics')
>>> tz.keys()
['US-Eastern']
>>> est = tz.get('US-Eastern')
>>> est
<tzicalvtz 'US-Eastern'>
>>> datetime.now(est)
datetime.datetime(2003, 10, 6, 19, 44, 18, 667987,
tzinfo=<tzicalvtz 'US-Eastern'>)
>>> est == tz.get()
True
Let's check the daylight ranges, as usual:
.. doctest:: tzfile
>>> datetime(2003, 4, 6, 1, 59, tzinfo=est).tzname()
'EST'
>>> datetime(2003, 4, 6, 2, 00, tzinfo=est).tzname()
'EDT'
>>> datetime(2003, 10, 26, 0, 59, tzinfo=est).tzname()
'EDT'
>>> datetime(2003, 10, 26, 1, 00, tzinfo=est).tzname()
'EST'
tzwin examples
--------------
.. doctest:: tzwin
>>> tz = tzwin("E. South America Standard Time")
tzwinlocal examples
-------------------
.. doctest:: tzwinlocal
>>> tz = tzwinlocal()
# vim:ts=4:sw=4:et