Home | History | Annotate | Download | only in docs
      1 dateutil examples
      2 =================
      3 
      4 .. contents::
      5 
      6 relativedelta examples
      7 ----------------------
      8 
      9 .. testsetup:: relativedelta
     10 
     11     from datetime import *; from dateutil.relativedelta import *
     12     import calendar
     13     NOW = datetime(2003, 9, 17, 20, 54, 47, 282310)
     14     TODAY = date(2003, 9, 17)
     15 
     16 Let's begin our trip::
     17 
     18     >>> from datetime import *; from dateutil.relativedelta import *
     19     >>> import calendar
     20 
     21 Store some values::
     22 
     23     >>> NOW = datetime.now()
     24     >>> TODAY = date.today()
     25     >>> NOW
     26     datetime.datetime(2003, 9, 17, 20, 54, 47, 282310)
     27     >>> TODAY
     28     datetime.date(2003, 9, 17)
     29 
     30 Next month
     31 
     32 .. doctest:: relativedelta
     33 
     34     >>> NOW+relativedelta(months=+1)
     35     datetime.datetime(2003, 10, 17, 20, 54, 47, 282310)
     36 
     37 Next month, plus one week.
     38 
     39 .. doctest:: relativedelta
     40 
     41     >>> NOW+relativedelta(months=+1, weeks=+1)
     42     datetime.datetime(2003, 10, 24, 20, 54, 47, 282310)
     43 
     44 Next month, plus one week, at 10am.
     45 
     46 .. doctest:: relativedelta
     47 
     48     >>> TODAY+relativedelta(months=+1, weeks=+1, hour=10)
     49     datetime.datetime(2003, 10, 24, 10, 0)
     50 
     51 Here is another example using an absolute relativedelta.  Notice the use of
     52 year and month (both singular) which causes the values to be *replaced* in the
     53 original datetime rather than performing an arithmetic operation on them.
     54 
     55 .. doctest:: relativedelta
     56 
     57     >>> NOW+relativedelta(year=1, month=1)
     58     datetime.datetime(1, 1, 17, 20, 54, 47, 282310)
     59 
     60 Let's try the other way around. Notice that the
     61 hour setting we get in the relativedelta is relative,
     62 since it's a difference, and the weeks parameter
     63 has gone.
     64 
     65 .. doctest:: relativedelta
     66 
     67     >>> relativedelta(datetime(2003, 10, 24, 10, 0), TODAY)
     68     relativedelta(months=+1, days=+7, hours=+10)
     69 
     70 One month before one year.
     71 
     72 .. doctest:: relativedelta
     73 
     74     >>> NOW+relativedelta(years=+1, months=-1)
     75     datetime.datetime(2004, 8, 17, 20, 54, 47, 282310)
     76 
     77 How does it handle months with different numbers of days?
     78 Notice that adding one month will never cross the month
     79 boundary.
     80 
     81 .. doctest:: relativedelta
     82 
     83     >>> date(2003,1,27)+relativedelta(months=+1)
     84     datetime.date(2003, 2, 27)
     85     >>> date(2003,1,31)+relativedelta(months=+1)
     86     datetime.date(2003, 2, 28)
     87     >>> date(2003,1,31)+relativedelta(months=+2)
     88     datetime.date(2003, 3, 31)
     89 
     90 The logic for years is the same, even on leap years.
     91 
     92 .. doctest:: relativedelta
     93 
     94     >>> date(2000,2,28)+relativedelta(years=+1)
     95     datetime.date(2001, 2, 28)
     96     >>> date(2000,2,29)+relativedelta(years=+1)
     97     datetime.date(2001, 2, 28)
     98 
     99     >>> date(1999,2,28)+relativedelta(years=+1)
    100     datetime.date(2000, 2, 28)
    101     >>> date(1999,3,1)+relativedelta(years=+1)
    102     datetime.date(2000, 3, 1)
    103 
    104     >>> date(2001,2,28)+relativedelta(years=-1)
    105     datetime.date(2000, 2, 28)
    106     >>> date(2001,3,1)+relativedelta(years=-1)
    107     datetime.date(2000, 3, 1)
    108 
    109 Next friday
    110 
    111 .. doctest:: relativedelta
    112 
    113     >>> TODAY+relativedelta(weekday=FR)
    114     datetime.date(2003, 9, 19)
    115 
    116     >>> TODAY+relativedelta(weekday=calendar.FRIDAY)
    117     datetime.date(2003, 9, 19)
    118 
    119 Last friday in this month.
    120 
    121 .. doctest:: relativedelta
    122 
    123     >>> TODAY+relativedelta(day=31, weekday=FR(-1))
    124     datetime.date(2003, 9, 26)
    125 
    126 Next wednesday (it's today!).
    127 
    128 .. doctest:: relativedelta
    129 
    130     >>> TODAY+relativedelta(weekday=WE(+1))
    131     datetime.date(2003, 9, 17)
    132 
    133 Next wednesday, but not today.
    134 
    135 .. doctest:: relativedelta
    136 
    137     >>> TODAY+relativedelta(days=+1, weekday=WE(+1))
    138     datetime.date(2003, 9, 24)
    139 
    140 Following
    141 [http://www.cl.cam.ac.uk/~mgk25/iso-time.html ISO year week number notation]
    142 find the first day of the 15th week of 1997.
    143 
    144 .. doctest:: relativedelta
    145 
    146     >>> datetime(1997,1,1)+relativedelta(day=4, weekday=MO(-1), weeks=+14)
    147     datetime.datetime(1997, 4, 7, 0, 0)
    148 
    149 How long ago has the millennium changed?
    150 
    151 .. doctest:: relativedelta
    152     :options: +NORMALIZE_WHITESPACE
    153 
    154     >>> relativedelta(NOW, date(2001,1,1))
    155     relativedelta(years=+2, months=+8, days=+16,
    156                   hours=+20, minutes=+54, seconds=+47, microseconds=+282310)
    157 
    158 How old is John?
    159 
    160 .. doctest:: relativedelta
    161     :options: +NORMALIZE_WHITESPACE
    162 
    163     >>> johnbirthday = datetime(1978, 4, 5, 12, 0)
    164     >>> relativedelta(NOW, johnbirthday)
    165     relativedelta(years=+25, months=+5, days=+12,
    166               hours=+8, minutes=+54, seconds=+47, microseconds=+282310)
    167 
    168 It works with dates too.
    169 
    170 .. doctest:: relativedelta
    171 
    172     >>> relativedelta(TODAY, johnbirthday)
    173     relativedelta(years=+25, months=+5, days=+11, hours=+12)
    174 
    175 Obtain today's date using the yearday:
    176 
    177 .. doctest:: relativedelta
    178 
    179     >>> date(2003, 1, 1)+relativedelta(yearday=260)
    180     datetime.date(2003, 9, 17)
    181 
    182 We can use today's date, since yearday should be absolute
    183 in the given year:
    184 
    185 .. doctest:: relativedelta
    186 
    187     >>> TODAY+relativedelta(yearday=260)
    188     datetime.date(2003, 9, 17)
    189 
    190 Last year it should be in the same day:
    191 
    192 .. doctest:: relativedelta
    193 
    194     >>> date(2002, 1, 1)+relativedelta(yearday=260)
    195     datetime.date(2002, 9, 17)
    196 
    197 But not in a leap year:
    198 
    199 .. doctest:: relativedelta
    200 
    201     >>> date(2000, 1, 1)+relativedelta(yearday=260)
    202     datetime.date(2000, 9, 16)
    203 
    204 We can use the non-leap year day to ignore this:
    205 
    206 .. doctest:: relativedelta
    207 
    208     >>> date(2000, 1, 1)+relativedelta(nlyearday=260)
    209     datetime.date(2000, 9, 17)
    210 
    211 rrule examples
    212 --------------
    213 These examples were converted from the RFC.
    214 
    215 Prepare the environment.
    216 
    217 .. testsetup:: rrule
    218 
    219     from dateutil.rrule import *
    220     from dateutil.parser import *
    221     from datetime import *
    222     import pprint
    223     import sys
    224     sys.displayhook = pprint.pprint
    225 
    226 .. doctest:: rrule
    227 
    228     >>> from dateutil.rrule import *
    229     >>> from dateutil.parser import *
    230     >>> from datetime import *
    231 
    232     >>> import pprint
    233     >>> import sys
    234     >>> sys.displayhook = pprint.pprint
    235 
    236 Daily, for 10 occurrences.
    237 
    238 .. doctest:: rrule
    239    :options: +NORMALIZE_WHITESPACE
    240 
    241     >>> list(rrule(DAILY, count=10,
    242     ...            dtstart=parse("19970902T090000")))
    243     [datetime.datetime(1997, 9, 2, 9, 0),
    244      datetime.datetime(1997, 9, 3, 9, 0),
    245      datetime.datetime(1997, 9, 4, 9, 0),
    246      datetime.datetime(1997, 9, 5, 9, 0),
    247      datetime.datetime(1997, 9, 6, 9, 0),
    248      datetime.datetime(1997, 9, 7, 9, 0),
    249      datetime.datetime(1997, 9, 8, 9, 0),
    250      datetime.datetime(1997, 9, 9, 9, 0),
    251      datetime.datetime(1997, 9, 10, 9, 0),
    252      datetime.datetime(1997, 9, 11, 9, 0)]
    253 
    254 Daily until December 24, 1997
    255 
    256 .. doctest:: rrule
    257    :options: +NORMALIZE_WHITESPACE, +ELLIPSIS
    258 
    259     >>> list(rrule(DAILY,
    260     ...            dtstart=parse("19970902T090000"),
    261     ...            until=parse("19971224T000000")))
    262     [datetime.datetime(1997, 9, 2, 9, 0),
    263      datetime.datetime(1997, 9, 3, 9, 0),
    264      datetime.datetime(1997, 9, 4, 9, 0),
    265      ...
    266      datetime.datetime(1997, 12, 21, 9, 0),
    267      datetime.datetime(1997, 12, 22, 9, 0),
    268      datetime.datetime(1997, 12, 23, 9, 0)]
    269 
    270 Every other day, 5 occurrences.
    271 
    272 .. doctest:: rrule
    273    :options: +NORMALIZE_WHITESPACE
    274 
    275     >>> list(rrule(DAILY, interval=2, count=5,
    276     ...            dtstart=parse("19970902T090000")))
    277     [datetime.datetime(1997, 9, 2, 9, 0),
    278      datetime.datetime(1997, 9, 4, 9, 0),
    279      datetime.datetime(1997, 9, 6, 9, 0),
    280      datetime.datetime(1997, 9, 8, 9, 0),
    281      datetime.datetime(1997, 9, 10, 9, 0)]
    282 
    283 Every 10 days, 5 occurrences.
    284 
    285 .. doctest:: rrule
    286    :options: +NORMALIZE_WHITESPACE
    287 
    288     >>> list(rrule(DAILY, interval=10, count=5,
    289     ...            dtstart=parse("19970902T090000")))
    290     [datetime.datetime(1997, 9, 2, 9, 0),
    291      datetime.datetime(1997, 9, 12, 9, 0),
    292      datetime.datetime(1997, 9, 22, 9, 0),
    293      datetime.datetime(1997, 10, 2, 9, 0),
    294      datetime.datetime(1997, 10, 12, 9, 0)]
    295 
    296 Everyday in January, for 3 years.
    297 
    298 .. doctest:: rrule
    299    :options: +NORMALIZE_WHITESPACE, +ELLIPSIS
    300 
    301     >>> list(rrule(YEARLY, bymonth=1, byweekday=range(7),
    302     ...            dtstart=parse("19980101T090000"),
    303     ...            until=parse("20000131T090000")))
    304     [datetime.datetime(1998, 1, 1, 9, 0),
    305      datetime.datetime(1998, 1, 2, 9, 0),
    306      ...
    307      datetime.datetime(1998, 1, 30, 9, 0),
    308      datetime.datetime(1998, 1, 31, 9, 0),
    309      datetime.datetime(1999, 1, 1, 9, 0),
    310      datetime.datetime(1999, 1, 2, 9, 0),
    311      ...
    312      datetime.datetime(1999, 1, 30, 9, 0),
    313      datetime.datetime(1999, 1, 31, 9, 0),
    314      datetime.datetime(2000, 1, 1, 9, 0),
    315      datetime.datetime(2000, 1, 2, 9, 0),
    316      ...
    317      datetime.datetime(2000, 1, 30, 9, 0),
    318      datetime.datetime(2000, 1, 31, 9, 0)]
    319 
    320 Same thing, in another way.
    321 
    322 .. doctest:: rrule
    323    :options: +NORMALIZE_WHITESPACE, +ELLIPSIS
    324 
    325     >>> list(rrule(DAILY, bymonth=1,
    326     ...            dtstart=parse("19980101T090000"),
    327     ...            until=parse("20000131T090000")))
    328     [datetime.datetime(1998, 1, 1, 9, 0),
    329      ...
    330      datetime.datetime(2000, 1, 31, 9, 0)]
    331 
    332 Weekly for 10 occurrences.
    333 
    334 .. doctest:: rrule
    335    :options: +NORMALIZE_WHITESPACE
    336 
    337     >>> list(rrule(WEEKLY, count=10,
    338     ...            dtstart=parse("19970902T090000")))
    339     [datetime.datetime(1997, 9, 2, 9, 0),
    340      datetime.datetime(1997, 9, 9, 9, 0),
    341      datetime.datetime(1997, 9, 16, 9, 0),
    342      datetime.datetime(1997, 9, 23, 9, 0),
    343      datetime.datetime(1997, 9, 30, 9, 0),
    344      datetime.datetime(1997, 10, 7, 9, 0),
    345      datetime.datetime(1997, 10, 14, 9, 0),
    346      datetime.datetime(1997, 10, 21, 9, 0),
    347      datetime.datetime(1997, 10, 28, 9, 0),
    348      datetime.datetime(1997, 11, 4, 9, 0)]
    349 
    350 Every other week, 6 occurrences.
    351 
    352 .. doctest:: rrule
    353    :options: +NORMALIZE_WHITESPACE
    354 
    355     >>> list(rrule(WEEKLY, interval=2, count=6,
    356     ...            dtstart=parse("19970902T090000")))
    357     [datetime.datetime(1997, 9, 2, 9, 0),
    358      datetime.datetime(1997, 9, 16, 9, 0),
    359      datetime.datetime(1997, 9, 30, 9, 0),
    360      datetime.datetime(1997, 10, 14, 9, 0),
    361      datetime.datetime(1997, 10, 28, 9, 0),
    362      datetime.datetime(1997, 11, 11, 9, 0)]
    363 
    364 Weekly on Tuesday and Thursday for 5 weeks.
    365 
    366 .. doctest:: rrule
    367    :options: +NORMALIZE_WHITESPACE
    368 
    369     >>> list(rrule(WEEKLY, count=10, wkst=SU, byweekday=(TU,TH),
    370     ...            dtstart=parse("19970902T090000")))
    371     [datetime.datetime(1997, 9, 2, 9, 0),
    372      datetime.datetime(1997, 9, 4, 9, 0),
    373      datetime.datetime(1997, 9, 9, 9, 0),
    374      datetime.datetime(1997, 9, 11, 9, 0),
    375      datetime.datetime(1997, 9, 16, 9, 0),
    376      datetime.datetime(1997, 9, 18, 9, 0),
    377      datetime.datetime(1997, 9, 23, 9, 0),
    378      datetime.datetime(1997, 9, 25, 9, 0),
    379      datetime.datetime(1997, 9, 30, 9, 0),
    380      datetime.datetime(1997, 10, 2, 9, 0)]
    381 
    382 Every other week on Tuesday and Thursday, for 8 occurrences.
    383 
    384 .. doctest:: rrule
    385    :options: +NORMALIZE_WHITESPACE
    386 
    387     >>> list(rrule(WEEKLY, interval=2, count=8,
    388     ...            wkst=SU, byweekday=(TU,TH),
    389     ...            dtstart=parse("19970902T090000")))
    390     [datetime.datetime(1997, 9, 2, 9, 0),
    391      datetime.datetime(1997, 9, 4, 9, 0),
    392      datetime.datetime(1997, 9, 16, 9, 0),
    393      datetime.datetime(1997, 9, 18, 9, 0),
    394      datetime.datetime(1997, 9, 30, 9, 0),
    395      datetime.datetime(1997, 10, 2, 9, 0),
    396      datetime.datetime(1997, 10, 14, 9, 0),
    397      datetime.datetime(1997, 10, 16, 9, 0)]
    398 
    399 Monthly on the 1st Friday for ten occurrences.
    400 
    401 .. doctest:: rrule
    402    :options: +NORMALIZE_WHITESPACE
    403 
    404     >>> list(rrule(MONTHLY, count=10, byweekday=FR(1),
    405     ...            dtstart=parse("19970905T090000")))
    406     [datetime.datetime(1997, 9, 5, 9, 0),
    407      datetime.datetime(1997, 10, 3, 9, 0),
    408      datetime.datetime(1997, 11, 7, 9, 0),
    409      datetime.datetime(1997, 12, 5, 9, 0),
    410      datetime.datetime(1998, 1, 2, 9, 0),
    411      datetime.datetime(1998, 2, 6, 9, 0),
    412      datetime.datetime(1998, 3, 6, 9, 0),
    413      datetime.datetime(1998, 4, 3, 9, 0),
    414      datetime.datetime(1998, 5, 1, 9, 0),
    415      datetime.datetime(1998, 6, 5, 9, 0)]
    416 
    417 Every other month on the 1st and last Sunday of the month for 10 occurrences.
    418 
    419 .. doctest:: rrule
    420    :options: +NORMALIZE_WHITESPACE
    421 
    422     >>> list(rrule(MONTHLY, interval=2, count=10,
    423     ...            byweekday=(SU(1), SU(-1)),
    424     ...            dtstart=parse("19970907T090000")))
    425     [datetime.datetime(1997, 9, 7, 9, 0),
    426      datetime.datetime(1997, 9, 28, 9, 0),
    427      datetime.datetime(1997, 11, 2, 9, 0),
    428      datetime.datetime(1997, 11, 30, 9, 0),
    429      datetime.datetime(1998, 1, 4, 9, 0),
    430      datetime.datetime(1998, 1, 25, 9, 0),
    431      datetime.datetime(1998, 3, 1, 9, 0),
    432      datetime.datetime(1998, 3, 29, 9, 0),
    433      datetime.datetime(1998, 5, 3, 9, 0),
    434      datetime.datetime(1998, 5, 31, 9, 0)]
    435 
    436 Monthly on the second to last Monday of the month for 6 months.
    437 
    438 .. doctest:: rrule
    439    :options: +NORMALIZE_WHITESPACE
    440 
    441     >>> list(rrule(MONTHLY, count=6, byweekday=MO(-2),
    442     ...            dtstart=parse("19970922T090000")))
    443     [datetime.datetime(1997, 9, 22, 9, 0),
    444      datetime.datetime(1997, 10, 20, 9, 0),
    445      datetime.datetime(1997, 11, 17, 9, 0),
    446      datetime.datetime(1997, 12, 22, 9, 0),
    447      datetime.datetime(1998, 1, 19, 9, 0),
    448      datetime.datetime(1998, 2, 16, 9, 0)]
    449 
    450 
    451 Monthly on the third to the last day of the month, for 6 months.
    452 
    453 .. doctest:: rrule
    454    :options: +NORMALIZE_WHITESPACE
    455 
    456     >>> list(rrule(MONTHLY, count=6, bymonthday=-3,
    457     ...            dtstart=parse("19970928T090000")))
    458     [datetime.datetime(1997, 9, 28, 9, 0),
    459      datetime.datetime(1997, 10, 29, 9, 0),
    460      datetime.datetime(1997, 11, 28, 9, 0),
    461      datetime.datetime(1997, 12, 29, 9, 0),
    462      datetime.datetime(1998, 1, 29, 9, 0),
    463      datetime.datetime(1998, 2, 26, 9, 0)]
    464 
    465 
    466 Monthly on the 2nd and 15th of the month for 5 occurrences.
    467 
    468 .. doctest:: rrule
    469    :options: +NORMALIZE_WHITESPACE
    470 
    471     >>> list(rrule(MONTHLY, count=5, bymonthday=(2,15),
    472     ...            dtstart=parse("19970902T090000")))
    473     [datetime.datetime(1997, 9, 2, 9, 0),
    474      datetime.datetime(1997, 9, 15, 9, 0),
    475      datetime.datetime(1997, 10, 2, 9, 0),
    476      datetime.datetime(1997, 10, 15, 9, 0),
    477      datetime.datetime(1997, 11, 2, 9, 0)]
    478 
    479 
    480 Monthly on the first and last day of the month for 3 occurrences.
    481 
    482 .. doctest:: rrule
    483    :options: +NORMALIZE_WHITESPACE
    484 
    485     >>> list(rrule(MONTHLY, count=5, bymonthday=(-1,1,),
    486     ...            dtstart=parse("19970902T090000")))
    487     [datetime.datetime(1997, 9, 30, 9, 0),
    488      datetime.datetime(1997, 10, 1, 9, 0),
    489      datetime.datetime(1997, 10, 31, 9, 0),
    490      datetime.datetime(1997, 11, 1, 9, 0),
    491      datetime.datetime(1997, 11, 30, 9, 0)]
    492 
    493 
    494 Every 18 months on the 10th thru 15th of the month for 10 occurrences.
    495 
    496 .. doctest:: rrule
    497    :options: +NORMALIZE_WHITESPACE
    498 
    499     >>> list(rrule(MONTHLY, interval=18, count=10,
    500     ...            bymonthday=range(10,16),
    501     ...            dtstart=parse("19970910T090000")))
    502     [datetime.datetime(1997, 9, 10, 9, 0),
    503      datetime.datetime(1997, 9, 11, 9, 0),
    504      datetime.datetime(1997, 9, 12, 9, 0),
    505      datetime.datetime(1997, 9, 13, 9, 0),
    506      datetime.datetime(1997, 9, 14, 9, 0),
    507      datetime.datetime(1997, 9, 15, 9, 0),
    508      datetime.datetime(1999, 3, 10, 9, 0),
    509      datetime.datetime(1999, 3, 11, 9, 0),
    510      datetime.datetime(1999, 3, 12, 9, 0),
    511      datetime.datetime(1999, 3, 13, 9, 0)]
    512 
    513 
    514 Every Tuesday, every other month, 6 occurences.
    515 
    516 .. doctest:: rrule
    517    :options: +NORMALIZE_WHITESPACE
    518 
    519     >>> list(rrule(MONTHLY, interval=2, count=6, byweekday=TU,
    520     ...            dtstart=parse("19970902T090000")))
    521     [datetime.datetime(1997, 9, 2, 9, 0),
    522      datetime.datetime(1997, 9, 9, 9, 0),
    523      datetime.datetime(1997, 9, 16, 9, 0),
    524      datetime.datetime(1997, 9, 23, 9, 0),
    525      datetime.datetime(1997, 9, 30, 9, 0),
    526      datetime.datetime(1997, 11, 4, 9, 0)]
    527 
    528 
    529 Yearly in June and July for 10 occurrences.
    530 
    531 .. doctest:: rrule
    532    :options: +NORMALIZE_WHITESPACE
    533 
    534     >>> list(rrule(YEARLY, count=4, bymonth=(6,7),
    535     ...            dtstart=parse("19970610T090000")))
    536     [datetime.datetime(1997, 6, 10, 9, 0),
    537      datetime.datetime(1997, 7, 10, 9, 0),
    538      datetime.datetime(1998, 6, 10, 9, 0),
    539      datetime.datetime(1998, 7, 10, 9, 0)]
    540 
    541 
    542 Every 3rd year on the 1st, 100th and 200th day for 4 occurrences.
    543 
    544 .. doctest:: rrule
    545    :options: +NORMALIZE_WHITESPACE
    546 
    547     >>> list(rrule(YEARLY, count=4, interval=3, byyearday=(1,100,200),
    548     ...            dtstart=parse("19970101T090000")))
    549     [datetime.datetime(1997, 1, 1, 9, 0),
    550      datetime.datetime(1997, 4, 10, 9, 0),
    551      datetime.datetime(1997, 7, 19, 9, 0),
    552      datetime.datetime(2000, 1, 1, 9, 0)]
    553 
    554 
    555 Every 20th Monday of the year, 3 occurrences.
    556 
    557 .. doctest:: rrule
    558    :options: +NORMALIZE_WHITESPACE
    559 
    560     >>> list(rrule(YEARLY, count=3, byweekday=MO(20),
    561     ...            dtstart=parse("19970519T090000")))
    562     [datetime.datetime(1997, 5, 19, 9, 0),
    563      datetime.datetime(1998, 5, 18, 9, 0),
    564      datetime.datetime(1999, 5, 17, 9, 0)]
    565 
    566 
    567 Monday of week number 20 (where the default start of the week is Monday),
    568 3 occurrences.
    569 
    570 .. doctest:: rrule
    571    :options: +NORMALIZE_WHITESPACE
    572 
    573     >>> list(rrule(YEARLY, count=3, byweekno=20, byweekday=MO,
    574     ...            dtstart=parse("19970512T090000")))
    575     [datetime.datetime(1997, 5, 12, 9, 0),
    576      datetime.datetime(1998, 5, 11, 9, 0),
    577      datetime.datetime(1999, 5, 17, 9, 0)]
    578 
    579 
    580 The week number 1 may be in the last year.
    581 
    582 .. doctest:: rrule
    583    :options: +NORMALIZE_WHITESPACE
    584 
    585     >>> list(rrule(WEEKLY, count=3, byweekno=1, byweekday=MO,
    586     ...            dtstart=parse("19970902T090000")))
    587     [datetime.datetime(1997, 12, 29, 9, 0),
    588      datetime.datetime(1999, 1, 4, 9, 0),
    589      datetime.datetime(2000, 1, 3, 9, 0)]
    590 
    591 
    592 And the week numbers greater than 51 may be in the next year.
    593 
    594 .. doctest:: rrule
    595    :options: +NORMALIZE_WHITESPACE
    596 
    597     >>> list(rrule(WEEKLY, count=3, byweekno=52, byweekday=SU,
    598     ...            dtstart=parse("19970902T090000")))
    599     [datetime.datetime(1997, 12, 28, 9, 0),
    600      datetime.datetime(1998, 12, 27, 9, 0),
    601      datetime.datetime(2000, 1, 2, 9, 0)]
    602 
    603 
    604 Only some years have week number 53:
    605 
    606 .. doctest:: rrule
    607    :options: +NORMALIZE_WHITESPACE
    608 
    609     >>> list(rrule(WEEKLY, count=3, byweekno=53, byweekday=MO,
    610     ...            dtstart=parse("19970902T090000")))
    611     [datetime.datetime(1998, 12, 28, 9, 0),
    612      datetime.datetime(2004, 12, 27, 9, 0),
    613      datetime.datetime(2009, 12, 28, 9, 0)]
    614 
    615 
    616 Every Friday the 13th, 4 occurrences.
    617 
    618 .. doctest:: rrule
    619    :options: +NORMALIZE_WHITESPACE
    620 
    621     >>> list(rrule(YEARLY, count=4, byweekday=FR, bymonthday=13,
    622     ...            dtstart=parse("19970902T090000")))
    623     [datetime.datetime(1998, 2, 13, 9, 0),
    624      datetime.datetime(1998, 3, 13, 9, 0),
    625      datetime.datetime(1998, 11, 13, 9, 0),
    626      datetime.datetime(1999, 8, 13, 9, 0)]
    627 
    628 
    629 Every four years, the first Tuesday after a Monday in November,
    630 3 occurrences (U.S. Presidential Election day):
    631 
    632 .. doctest:: rrule
    633    :options: +NORMALIZE_WHITESPACE
    634 
    635     >>> list(rrule(YEARLY, interval=4, count=3, bymonth=11,
    636     ...            byweekday=TU, bymonthday=(2,3,4,5,6,7,8),
    637     ...            dtstart=parse("19961105T090000")))
    638     [datetime.datetime(1996, 11, 5, 9, 0),
    639      datetime.datetime(2000, 11, 7, 9, 0),
    640      datetime.datetime(2004, 11, 2, 9, 0)]
    641 
    642 
    643 The 3rd instance into the month of one of Tuesday, Wednesday or
    644 Thursday, for the next 3 months:
    645 
    646 .. doctest:: rrule
    647    :options: +NORMALIZE_WHITESPACE
    648 
    649     >>> list(rrule(MONTHLY, count=3, byweekday=(TU,WE,TH),
    650     ...            bysetpos=3, dtstart=parse("19970904T090000")))
    651     [datetime.datetime(1997, 9, 4, 9, 0),
    652      datetime.datetime(1997, 10, 7, 9, 0),
    653      datetime.datetime(1997, 11, 6, 9, 0)]
    654 
    655 
    656 The 2nd to last weekday of the month, 3 occurrences.
    657 
    658 .. doctest:: rrule
    659    :options: +NORMALIZE_WHITESPACE
    660 
    661     >>> list(rrule(MONTHLY, count=3, byweekday=(MO,TU,WE,TH,FR),
    662     ...            bysetpos=-2, dtstart=parse("19970929T090000")))
    663     [datetime.datetime(1997, 9, 29, 9, 0),
    664      datetime.datetime(1997, 10, 30, 9, 0),
    665      datetime.datetime(1997, 11, 27, 9, 0)]
    666 
    667 
    668 Every 3 hours from 9:00 AM to 5:00 PM on a specific day.
    669 
    670 .. doctest:: rrule
    671    :options: +NORMALIZE_WHITESPACE
    672 
    673     >>> list(rrule(HOURLY, interval=3,
    674     ...            dtstart=parse("19970902T090000"),
    675     ...            until=parse("19970902T170000")))
    676     [datetime.datetime(1997, 9, 2, 9, 0),
    677      datetime.datetime(1997, 9, 2, 12, 0),
    678      datetime.datetime(1997, 9, 2, 15, 0)]
    679 
    680 
    681 Every 15 minutes for 6 occurrences.
    682 
    683 .. doctest:: rrule
    684    :options: +NORMALIZE_WHITESPACE
    685 
    686     >>> list(rrule(MINUTELY, interval=15, count=6,
    687     ...            dtstart=parse("19970902T090000")))
    688     [datetime.datetime(1997, 9, 2, 9, 0),
    689      datetime.datetime(1997, 9, 2, 9, 15),
    690      datetime.datetime(1997, 9, 2, 9, 30),
    691      datetime.datetime(1997, 9, 2, 9, 45),
    692      datetime.datetime(1997, 9, 2, 10, 0),
    693      datetime.datetime(1997, 9, 2, 10, 15)]
    694 
    695 
    696 Every hour and a half for 4 occurrences.
    697 
    698 .. doctest:: rrule
    699    :options: +NORMALIZE_WHITESPACE
    700 
    701     >>> list(rrule(MINUTELY, interval=90, count=4,
    702     ...            dtstart=parse("19970902T090000")))
    703     [datetime.datetime(1997, 9, 2, 9, 0),
    704      datetime.datetime(1997, 9, 2, 10, 30),
    705      datetime.datetime(1997, 9, 2, 12, 0),
    706      datetime.datetime(1997, 9, 2, 13, 30)]
    707 
    708 
    709 Every 20 minutes from 9:00 AM to 4:40 PM for two days.
    710 
    711 .. doctest:: rrule
    712    :options: +NORMALIZE_WHITESPACE, +ELLIPSIS
    713 
    714     >>> list(rrule(MINUTELY, interval=20, count=48,
    715     ...            byhour=range(9,17), byminute=(0,20,40),
    716     ...            dtstart=parse("19970902T090000")))
    717     [datetime.datetime(1997, 9, 2, 9, 0),
    718      datetime.datetime(1997, 9, 2, 9, 20),
    719      ...
    720      datetime.datetime(1997, 9, 2, 16, 20),
    721      datetime.datetime(1997, 9, 2, 16, 40),
    722      datetime.datetime(1997, 9, 3, 9, 0),
    723      datetime.datetime(1997, 9, 3, 9, 20),
    724      ...
    725      datetime.datetime(1997, 9, 3, 16, 20),
    726      datetime.datetime(1997, 9, 3, 16, 40)]
    727 
    728 
    729 An example where the days generated makes a difference because of `wkst`.
    730 
    731 .. doctest:: rrule
    732    :options: +NORMALIZE_WHITESPACE
    733 
    734     >>> list(rrule(WEEKLY, interval=2, count=4,
    735     ...            byweekday=(TU,SU), wkst=MO,
    736     ...            dtstart=parse("19970805T090000")))
    737     [datetime.datetime(1997, 8, 5, 9, 0),
    738      datetime.datetime(1997, 8, 10, 9, 0),
    739      datetime.datetime(1997, 8, 19, 9, 0),
    740      datetime.datetime(1997, 8, 24, 9, 0)]
    741 
    742     >>> list(rrule(WEEKLY, interval=2, count=4,
    743     ...            byweekday=(TU,SU), wkst=SU,
    744     ...            dtstart=parse("19970805T090000")))
    745     [datetime.datetime(1997, 8, 5, 9, 0),
    746      datetime.datetime(1997, 8, 17, 9, 0),
    747      datetime.datetime(1997, 8, 19, 9, 0),
    748      datetime.datetime(1997, 8, 31, 9, 0)]
    749 
    750 
    751 rruleset examples
    752 -----------------
    753 Daily, for 7 days, jumping Saturday and Sunday occurrences.
    754 
    755 .. testsetup:: rruleset
    756 
    757     import datetime
    758 
    759     from dateutil.parser import parse
    760     from dateutil.rrule import rrule, rruleset
    761     from dateutil.rrule import YEARLY, MONTHLY, WEEKLY, DAILY
    762     from dateutil.rrule import MO, TU, WE, TH, FR, SA, SU
    763 
    764     import pprint
    765     import sys
    766     sys.displayhook = pprint.pprint
    767 
    768 .. doctest:: rruleset
    769    :options: +NORMALIZE_WHITESPACE
    770 
    771     >>> set = rruleset()
    772     >>> set.rrule(rrule(DAILY, count=7,
    773     ...                 dtstart=parse("19970902T090000")))
    774     >>> set.exrule(rrule(YEARLY, byweekday=(SA,SU),
    775     ...                  dtstart=parse("19970902T090000")))
    776     >>> list(set)
    777     [datetime.datetime(1997, 9, 2, 9, 0),
    778      datetime.datetime(1997, 9, 3, 9, 0),
    779      datetime.datetime(1997, 9, 4, 9, 0),
    780      datetime.datetime(1997, 9, 5, 9, 0),
    781      datetime.datetime(1997, 9, 8, 9, 0)]
    782 
    783 
    784 Weekly, for 4 weeks, plus one time on day 7, and not on day 16.
    785 
    786 .. doctest:: rruleset
    787    :options: +NORMALIZE_WHITESPACE
    788 
    789     >>> set = rruleset()
    790     >>> set.rrule(rrule(WEEKLY, count=4,
    791     ...           dtstart=parse("19970902T090000")))
    792     >>> set.rdate(datetime.datetime(1997, 9, 7, 9, 0))
    793     >>> set.exdate(datetime.datetime(1997, 9, 16, 9, 0))
    794     >>> list(set)
    795     [datetime.datetime(1997, 9, 2, 9, 0),
    796      datetime.datetime(1997, 9, 7, 9, 0),
    797      datetime.datetime(1997, 9, 9, 9, 0),
    798      datetime.datetime(1997, 9, 23, 9, 0)]
    799 
    800 
    801 rrulestr() examples
    802 -------------------
    803 
    804 Every 10 days, 5 occurrences.
    805 
    806 .. testsetup:: rrulestr
    807 
    808     from dateutil.parser import parse
    809     from dateutil.rrule import rruleset, rrulestr
    810 
    811     import pprint
    812     import sys
    813     sys.displayhook = pprint.pprint
    814 
    815 .. doctest:: rrulestr
    816    :options: +NORMALIZE_WHITESPACE
    817 
    818     >>> list(rrulestr("""
    819     ... DTSTART:19970902T090000
    820     ... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
    821     ... """))
    822     [datetime.datetime(1997, 9, 2, 9, 0),
    823      datetime.datetime(1997, 9, 12, 9, 0),
    824      datetime.datetime(1997, 9, 22, 9, 0),
    825      datetime.datetime(1997, 10, 2, 9, 0),
    826      datetime.datetime(1997, 10, 12, 9, 0)]
    827 
    828 
    829 Same thing, but passing only the `RRULE` value.
    830 
    831 .. doctest:: rrulestr
    832    :options: +NORMALIZE_WHITESPACE
    833 
    834     >>> list(rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5",
    835     ...               dtstart=parse("19970902T090000")))
    836     [datetime.datetime(1997, 9, 2, 9, 0),
    837      datetime.datetime(1997, 9, 12, 9, 0),
    838      datetime.datetime(1997, 9, 22, 9, 0),
    839      datetime.datetime(1997, 10, 2, 9, 0),
    840      datetime.datetime(1997, 10, 12, 9, 0)]
    841 
    842 
    843 Notice that when using a single rule, it returns an
    844 `rrule` instance, unless `forceset` was used.
    845 
    846 .. doctest:: rrulestr
    847    :options: +ELLIPSIS
    848 
    849     >>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5")
    850     <dateutil.rrule.rrule object at 0x...>
    851 
    852     >>> rrulestr("""
    853     ... DTSTART:19970902T090000
    854     ... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
    855     ... """)
    856     <dateutil.rrule.rrule object at 0x...>
    857 
    858     >>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", forceset=True)
    859     <dateutil.rrule.rruleset object at 0x...>
    860 
    861 
    862 But when an `rruleset` is needed, it is automatically used.
    863 
    864 .. doctest:: rrulestr
    865    :options: +ELLIPSIS
    866 
    867     >>> rrulestr("""
    868     ... DTSTART:19970902T090000
    869     ... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
    870     ... RRULE:FREQ=DAILY;INTERVAL=5;COUNT=3
    871     ... """)
    872     <dateutil.rrule.rruleset object at 0x...>
    873 
    874 
    875 parse examples
    876 --------------
    877 The following code will prepare the environment:
    878 
    879 .. doctest:: tz
    880 
    881     >>> from dateutil.parser import *
    882     >>> from dateutil.tz import *
    883     >>> from datetime import *
    884     >>> TZOFFSETS = {"BRST": -10800}
    885     >>> BRSTTZ = tzoffset("BRST", -10800)
    886     >>> DEFAULT = datetime(2003, 9, 25)
    887 
    888 
    889 Some simple examples based on the `date` command, using the
    890 `ZOFFSET` dictionary to provide the BRST timezone offset.
    891 
    892 .. doctest:: tz
    893     :options: +NORMALIZE_WHITESPACE
    894 
    895     >>> parse("Thu Sep 25 10:36:28 BRST 2003", tzinfos=TZOFFSETS)
    896     datetime.datetime(2003, 9, 25, 10, 36, 28,
    897               tzinfo=tzoffset('BRST', -10800))
    898 
    899     >>> parse("2003 10:36:28 BRST 25 Sep Thu", tzinfos=TZOFFSETS)
    900     datetime.datetime(2003, 9, 25, 10, 36, 28,
    901               tzinfo=tzoffset('BRST', -10800))
    902 
    903 
    904 Notice that since BRST is my local timezone, parsing it without
    905 further timezone settings will yield a `tzlocal` timezone.
    906 
    907 .. doctest:: tz
    908 
    909     >>> parse("Thu Sep 25 10:36:28 BRST 2003")
    910     datetime.datetime(2003, 9, 25, 10, 36, 28, tzinfo=tzlocal())
    911 
    912 
    913 We can also ask to ignore the timezone explicitly:
    914 
    915 .. doctest:: tz
    916 
    917     >>> parse("Thu Sep 25 10:36:28 BRST 2003", ignoretz=True)
    918     datetime.datetime(2003, 9, 25, 10, 36, 28)
    919 
    920 
    921 That's the same as processing a string without timezone:
    922 
    923 .. doctest:: tz
    924 
    925     >>> parse("Thu Sep 25 10:36:28 2003")
    926     datetime.datetime(2003, 9, 25, 10, 36, 28)
    927 
    928 
    929 Without the year, but passing our `DEFAULT` datetime to return
    930 the same year, no mattering what year we currently are in:
    931 
    932 .. doctest:: tz
    933 
    934     >>> parse("Thu Sep 25 10:36:28", default=DEFAULT)
    935     datetime.datetime(2003, 9, 25, 10, 36, 28)
    936 
    937 
    938 Strip it further:
    939 
    940 .. doctest:: tz
    941 
    942     >>> parse("Thu Sep 10:36:28", default=DEFAULT)
    943     datetime.datetime(2003, 9, 25, 10, 36, 28)
    944 
    945     >>> parse("Thu 10:36:28", default=DEFAULT)
    946     datetime.datetime(2003, 9, 25, 10, 36, 28)
    947 
    948     >>> parse("Thu 10:36", default=DEFAULT)
    949     datetime.datetime(2003, 9, 25, 10, 36)
    950 
    951     >>> parse("10:36", default=DEFAULT)
    952     datetime.datetime(2003, 9, 25, 10, 36)
    953 
    954 
    955 Strip in a different way:
    956 
    957 .. doctest:: tz
    958 
    959     >>> parse("Thu Sep 25 2003")
    960     datetime.datetime(2003, 9, 25, 0, 0)
    961 
    962     >>> parse("Sep 25 2003")
    963     datetime.datetime(2003, 9, 25, 0, 0)
    964 
    965     >>> parse("Sep 2003", default=DEFAULT)
    966     datetime.datetime(2003, 9, 25, 0, 0)
    967 
    968     >>> parse("Sep", default=DEFAULT)
    969     datetime.datetime(2003, 9, 25, 0, 0)
    970 
    971     >>> parse("2003", default=DEFAULT)
    972     datetime.datetime(2003, 9, 25, 0, 0)
    973 
    974 
    975 Another format, based on `date -R` (RFC822):
    976 
    977 .. doctest:: tz
    978    :options: +NORMALIZE_WHITESPACE
    979 
    980     >>> parse("Thu, 25 Sep 2003 10:49:41 -0300")
    981     datetime.datetime(2003, 9, 25, 10, 49, 41,
    982               tzinfo=tzoffset(None, -10800))
    983 
    984 
    985 ISO format:
    986 
    987 .. doctest:: tz
    988    :options: +NORMALIZE_WHITESPACE
    989 
    990     >>> parse("2003-09-25T10:49:41.5-03:00")
    991     datetime.datetime(2003, 9, 25, 10, 49, 41, 500000,
    992               tzinfo=tzoffset(None, -10800))
    993 
    994 
    995 Some variations:
    996 
    997 .. doctest:: tz
    998 
    999     >>> parse("2003-09-25T10:49:41")
   1000     datetime.datetime(2003, 9, 25, 10, 49, 41)
   1001 
   1002     >>> parse("2003-09-25T10:49")
   1003     datetime.datetime(2003, 9, 25, 10, 49)
   1004 
   1005     >>> parse("2003-09-25T10")
   1006     datetime.datetime(2003, 9, 25, 10, 0)
   1007 
   1008     >>> parse("2003-09-25")
   1009     datetime.datetime(2003, 9, 25, 0, 0)
   1010 
   1011 
   1012 ISO format, without separators:
   1013 
   1014 .. doctest:: tz
   1015    :options: +NORMALIZE_WHITESPACE
   1016 
   1017     >>> parse("20030925T104941.5-0300")
   1018     datetime.datetime(2003, 9, 25, 10, 49, 41, 500000,
   1019                       tzinfo=tzoffset(None, -10800))
   1020 
   1021     >>> parse("20030925T104941-0300")
   1022     datetime.datetime(2003, 9, 25, 10, 49, 41,
   1023               tzinfo=tzoffset(None, -10800))
   1024 
   1025     >>> parse("20030925T104941")
   1026     datetime.datetime(2003, 9, 25, 10, 49, 41)
   1027 
   1028     >>> parse("20030925T1049")
   1029     datetime.datetime(2003, 9, 25, 10, 49)
   1030 
   1031     >>> parse("20030925T10")
   1032     datetime.datetime(2003, 9, 25, 10, 0)
   1033 
   1034     >>> parse("20030925")
   1035     datetime.datetime(2003, 9, 25, 0, 0)
   1036 
   1037 
   1038 Everything together.
   1039 
   1040 .. doctest:: tz
   1041 
   1042     >>> parse("199709020900")
   1043     datetime.datetime(1997, 9, 2, 9, 0)
   1044     >>> parse("19970902090059")
   1045     datetime.datetime(1997, 9, 2, 9, 0, 59)
   1046 
   1047 
   1048 Different date orderings:
   1049 
   1050 .. doctest:: tz
   1051 
   1052     >>> parse("2003-09-25")
   1053     datetime.datetime(2003, 9, 25, 0, 0)
   1054 
   1055     >>> parse("2003-Sep-25")
   1056     datetime.datetime(2003, 9, 25, 0, 0)
   1057 
   1058     >>> parse("25-Sep-2003")
   1059     datetime.datetime(2003, 9, 25, 0, 0)
   1060 
   1061     >>> parse("Sep-25-2003")
   1062     datetime.datetime(2003, 9, 25, 0, 0)
   1063 
   1064     >>> parse("09-25-2003")
   1065     datetime.datetime(2003, 9, 25, 0, 0)
   1066 
   1067     >>> parse("25-09-2003")
   1068     datetime.datetime(2003, 9, 25, 0, 0)
   1069 
   1070 
   1071 Check some ambiguous dates:
   1072 
   1073 .. doctest:: tz
   1074 
   1075     >>> parse("10-09-2003")
   1076     datetime.datetime(2003, 10, 9, 0, 0)
   1077 
   1078     >>> parse("10-09-2003", dayfirst=True)
   1079     datetime.datetime(2003, 9, 10, 0, 0)
   1080 
   1081     >>> parse("10-09-03")
   1082     datetime.datetime(2003, 10, 9, 0, 0)
   1083 
   1084     >>> parse("10-09-03", yearfirst=True)
   1085     datetime.datetime(2010, 9, 3, 0, 0)
   1086 
   1087 
   1088 Other date separators are allowed:
   1089 
   1090 .. doctest:: tz
   1091 
   1092     >>> parse("2003.Sep.25")
   1093     datetime.datetime(2003, 9, 25, 0, 0)
   1094 
   1095     >>> parse("2003/09/25")
   1096     datetime.datetime(2003, 9, 25, 0, 0)
   1097 
   1098 
   1099 Even with spaces:
   1100 
   1101 .. doctest:: tz
   1102 
   1103     >>> parse("2003 Sep 25")
   1104     datetime.datetime(2003, 9, 25, 0, 0)
   1105 
   1106     >>> parse("2003 09 25")
   1107     datetime.datetime(2003, 9, 25, 0, 0)
   1108 
   1109 
   1110 Hours with letters work:
   1111 
   1112 .. doctest:: tz
   1113 
   1114     >>> parse("10h36m28.5s", default=DEFAULT)
   1115     datetime.datetime(2003, 9, 25, 10, 36, 28, 500000)
   1116 
   1117     >>> parse("01s02h03m", default=DEFAULT)
   1118     datetime.datetime(2003, 9, 25, 2, 3, 1)
   1119 
   1120     >>> parse("01h02m03", default=DEFAULT)
   1121     datetime.datetime(2003, 9, 25, 1, 2, 3)
   1122 
   1123     >>> parse("01h02", default=DEFAULT)
   1124     datetime.datetime(2003, 9, 25, 1, 2)
   1125 
   1126     >>> parse("01h02s", default=DEFAULT)
   1127     datetime.datetime(2003, 9, 25, 1, 0, 2)
   1128 
   1129 
   1130 With AM/PM:
   1131 
   1132 .. doctest:: tz
   1133 
   1134     >>> parse("10h am", default=DEFAULT)
   1135     datetime.datetime(2003, 9, 25, 10, 0)
   1136 
   1137     >>> parse("10pm", default=DEFAULT)
   1138     datetime.datetime(2003, 9, 25, 22, 0)
   1139 
   1140     >>> parse("12:00am", default=DEFAULT)
   1141     datetime.datetime(2003, 9, 25, 0, 0)
   1142 
   1143     >>> parse("12pm", default=DEFAULT)
   1144     datetime.datetime(2003, 9, 25, 12, 0)
   1145 
   1146 
   1147 Some special treating for ''pertain'' relations:
   1148 
   1149 .. doctest:: tz
   1150 
   1151     >>> parse("Sep 03", default=DEFAULT)
   1152     datetime.datetime(2003, 9, 3, 0, 0)
   1153 
   1154     >>> parse("Sep of 03", default=DEFAULT)
   1155     datetime.datetime(2003, 9, 25, 0, 0)
   1156 
   1157 
   1158 Fuzzy parsing:
   1159 
   1160 .. doctest:: tz
   1161    :options: +NORMALIZE_WHITESPACE
   1162 
   1163     >>> s = "Today is 25 of September of 2003, exactly " \
   1164     ...     "at 10:49:41 with timezone -03:00."
   1165     >>> parse(s, fuzzy=True)
   1166     datetime.datetime(2003, 9, 25, 10, 49, 41,
   1167               tzinfo=tzoffset(None, -10800))
   1168 
   1169 
   1170 Other random formats:
   1171 
   1172 .. doctest:: tz
   1173 
   1174     >>> parse("Wed, July 10, '96")
   1175     datetime.datetime(1996, 7, 10, 0, 0)
   1176 
   1177     >>> parse("1996.07.10 AD at 15:08:56 PDT", ignoretz=True)
   1178     datetime.datetime(1996, 7, 10, 15, 8, 56)
   1179 
   1180     >>> parse("Tuesday, April 12, 1952 AD 3:30:42pm PST", ignoretz=True)
   1181     datetime.datetime(1952, 4, 12, 15, 30, 42)
   1182 
   1183     >>> parse("November 5, 1994, 8:15:30 am EST", ignoretz=True)
   1184     datetime.datetime(1994, 11, 5, 8, 15, 30)
   1185 
   1186     >>> parse("3rd of May 2001")
   1187     datetime.datetime(2001, 5, 3, 0, 0)
   1188 
   1189     >>> parse("5:50 A.M. on June 13, 1990")
   1190     datetime.datetime(1990, 6, 13, 5, 50)
   1191 
   1192 
   1193 tzutc examples
   1194 --------------
   1195 
   1196 .. doctest:: tzutc
   1197 
   1198     >>> from datetime import *
   1199     >>> from dateutil.tz import *
   1200 
   1201     >>> datetime.now()
   1202     datetime.datetime(2003, 9, 27, 9, 40, 1, 521290)
   1203 
   1204     >>> datetime.now(tzutc())
   1205     datetime.datetime(2003, 9, 27, 12, 40, 12, 156379, tzinfo=tzutc())
   1206 
   1207     >>> datetime.now(tzutc()).tzname()
   1208     'UTC'
   1209 
   1210 
   1211 tzoffset examples
   1212 -----------------
   1213 
   1214 .. doctest:: tzoffset
   1215    :options: +NORMALIZE_WHITESPACE
   1216 
   1217     >>> from datetime import *
   1218     >>> from dateutil.tz import *
   1219 
   1220     >>> datetime.now(tzoffset("BRST", -10800))
   1221     datetime.datetime(2003, 9, 27, 9, 52, 43, 624904,
   1222               tzinfo=tzinfo=tzoffset('BRST', -10800))
   1223 
   1224     >>> datetime.now(tzoffset("BRST", -10800)).tzname()
   1225     'BRST'
   1226 
   1227     >>> datetime.now(tzoffset("BRST", -10800)).astimezone(tzutc())
   1228     datetime.datetime(2003, 9, 27, 12, 53, 11, 446419,
   1229               tzinfo=tzutc())
   1230 
   1231 
   1232 tzlocal examples
   1233 ----------------
   1234 
   1235 .. doctest:: tzlocal
   1236 
   1237     >>> from datetime import *
   1238     >>> from dateutil.tz import *
   1239 
   1240     >>> datetime.now(tzlocal())
   1241     datetime.datetime(2003, 9, 27, 10, 1, 43, 673605,
   1242               tzinfo=tzlocal())
   1243 
   1244     >>> datetime.now(tzlocal()).tzname()
   1245     'BRST'
   1246 
   1247     >>> datetime.now(tzlocal()).astimezone(tzoffset(None, 0))
   1248     datetime.datetime(2003, 9, 27, 13, 3, 0, 11493,
   1249               tzinfo=tzoffset(None, 0))
   1250 
   1251 
   1252 tzstr examples
   1253 --------------
   1254 Here are examples of the recognized formats:
   1255 
   1256   * `EST5EDT`
   1257   * `EST5EDT4,M4.1.0/02:00:00,M10-5-0/02:00`
   1258   * `EST5EDT4,95/02:00:00,298/02:00`
   1259   * `EST5EDT4,J96/02:00:00,J299/02:00`
   1260 
   1261 Notice that if daylight information is not present, but a
   1262 daylight abbreviation was provided, `tzstr` will follow the
   1263 convention of using the first sunday of April to start daylight
   1264 saving, and the last sunday of October to end it. If start or
   1265 end time is not present, 2AM will be used, and if the daylight
   1266 offset is not present, the standard offset plus one hour will
   1267 be used. This convention is the same as used in the GNU libc.
   1268 
   1269 This also means that some of the above examples are exactly
   1270 equivalent, and all of these examples are equivalent
   1271 in the year of 2003.
   1272 
   1273 Here is the example mentioned in the
   1274 
   1275 [https://docs.python.org/3/library/time.html time module documentation].
   1276 
   1277 .. testsetup:: tzstr
   1278 
   1279     import os
   1280     import time
   1281     from datetime import datetime
   1282     from dateutil.tz import tzstr
   1283 
   1284 .. doctest:: tzstr
   1285 
   1286     >>> os.environ['TZ'] = 'EST+05EDT,M4.1.0,M10.5.0'
   1287     >>> time.tzset()
   1288     >>> time.strftime('%X %x %Z')
   1289     '02:07:36 05/08/03 EDT'
   1290     >>> os.environ['TZ'] = 'AEST-10AEDT-11,M10.5.0,M3.5.0'
   1291     >>> time.tzset()
   1292     >>> time.strftime('%X %x %Z')
   1293     '16:08:12 05/08/03 AEST'
   1294 
   1295 
   1296 And here is an example showing the same information using `tzstr`,
   1297 without touching system settings.
   1298 
   1299 .. doctest:: tzstr
   1300 
   1301     >>> tz1 = tzstr('EST+05EDT,M4.1.0,M10.5.0')
   1302     >>> tz2 = tzstr('AEST-10AEDT-11,M10.5.0,M3.5.0')
   1303     >>> dt = datetime(2003, 5, 8, 2, 7, 36, tzinfo=tz1)
   1304     >>> dt.strftime('%X %x %Z')
   1305     '02:07:36 05/08/03 EDT'
   1306     >>> dt.astimezone(tz2).strftime('%X %x %Z')
   1307     '16:07:36 05/08/03 AEST'
   1308 
   1309 
   1310 Are these really equivalent?
   1311 
   1312 .. doctest:: tzstr
   1313 
   1314     >>> tzstr('EST5EDT') == tzstr('EST5EDT,M4.1.0,M10.5.0')
   1315     True
   1316 
   1317 
   1318 Check the daylight limit.
   1319 
   1320 .. doctest:: tzstr
   1321 
   1322     >>> tz = tzstr('EST+05EDT,M4.1.0,M10.5.0')
   1323     >>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname()
   1324     'EST'
   1325     >>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname()
   1326     'EDT'
   1327     >>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname()
   1328     'EDT'
   1329     >>> datetime(2003, 10, 26, 2, 00, tzinfo=tz).tzname()
   1330     'EST'
   1331 
   1332 
   1333 tzrange examples
   1334 ----------------
   1335 
   1336 .. testsetup:: tzrange
   1337 
   1338     from dateutil.tz import tzrange, tzstr
   1339 
   1340 .. doctest:: tzrange
   1341 
   1342     >>> tzstr('EST5EDT') == tzrange("EST", -18000, "EDT")
   1343     True
   1344 
   1345     >>> from dateutil.relativedelta import *
   1346     >>> range1 = tzrange("EST", -18000, "EDT")
   1347     >>> range2 = tzrange("EST", -18000, "EDT", -14400,
   1348     ...                  relativedelta(hours=+2, month=4, day=1,
   1349     ...                                weekday=SU(+1)),
   1350     ...                  relativedelta(hours=+1, month=10, day=31,
   1351     ...                                weekday=SU(-1)))
   1352     >>> tzstr('EST5EDT') == range1 == range2
   1353     True
   1354 
   1355 
   1356 Notice a minor detail in the last example: while the DST should end
   1357 at 2AM, the delta will catch 1AM. That's because the daylight saving
   1358 time should end at 2AM standard time (the difference between STD and
   1359 DST is 1h in the given example) instead of the DST time. That's how
   1360 the `tzinfo` subtypes should deal with the extra hour that happens
   1361 when going back to the standard time. Check
   1362 
   1363 [https://docs.python.org/3/library/datetime.html#datetime.tzinfo tzinfo documentation]
   1364 
   1365 for more information.
   1366 
   1367 tzfile examples
   1368 ---------------
   1369 
   1370 .. testsetup:: tzfile
   1371 
   1372     from datetime import datetime
   1373     from dateutil.tz import tzfile, tzutc
   1374 
   1375 .. doctest:: tzfile
   1376    :options: +NORMALIZE_WHITESPACE
   1377 
   1378     >>> tz = tzfile("/etc/localtime")
   1379     >>> datetime.now(tz)
   1380     datetime.datetime(2003, 9, 27, 12, 3, 48, 392138,
   1381               tzinfo=tzfile('/etc/localtime'))
   1382 
   1383     >>> datetime.now(tz).astimezone(tzutc())
   1384     datetime.datetime(2003, 9, 27, 15, 3, 53, 70863,
   1385               tzinfo=tzutc())
   1386 
   1387     >>> datetime.now(tz).tzname()
   1388     'BRST'
   1389     >>> datetime(2003, 1, 1, tzinfo=tz).tzname()
   1390     'BRDT'
   1391 
   1392 
   1393 Check the daylight limit.
   1394 
   1395 .. doctest:: tzfile
   1396 
   1397     >>> tz = tzfile('/usr/share/zoneinfo/EST5EDT')
   1398     >>> datetime(2003, 4, 6, 1, 59, tzinfo=tz).tzname()
   1399     'EST'
   1400     >>> datetime(2003, 4, 6, 2, 00, tzinfo=tz).tzname()
   1401     'EDT'
   1402     >>> datetime(2003, 10, 26, 0, 59, tzinfo=tz).tzname()
   1403     'EDT'
   1404     >>> datetime(2003, 10, 26, 1, 00, tzinfo=tz).tzname()
   1405     'EST'
   1406 
   1407 
   1408 tzical examples
   1409 ---------------
   1410 Here is a sample file extracted from the RFC. This file defines
   1411 the `EST5EDT` timezone, and will be used in the following example.
   1412 
   1413 .. include:: samples/EST5EDT.ics
   1414    :literal:
   1415 
   1416 And here is an example exploring a `tzical` type:
   1417 
   1418 .. doctest:: tzfile
   1419 
   1420     >>> from dateutil.tz import *; from datetime import *
   1421 
   1422     >>> tz = tzical('samples/EST5EDT.ics')
   1423     >>> tz.keys()
   1424     ['US-Eastern']
   1425 
   1426     >>> est = tz.get('US-Eastern')
   1427     >>> est
   1428     <tzicalvtz 'US-Eastern'>
   1429 
   1430     >>> datetime.now(est)
   1431     datetime.datetime(2003, 10, 6, 19, 44, 18, 667987,
   1432               tzinfo=<tzicalvtz 'US-Eastern'>)
   1433 
   1434     >>> est == tz.get()
   1435     True
   1436 
   1437 
   1438 Let's check the daylight ranges, as usual:
   1439 
   1440 .. doctest:: tzfile
   1441 
   1442     >>> datetime(2003, 4, 6, 1, 59, tzinfo=est).tzname()
   1443     'EST'
   1444     >>> datetime(2003, 4, 6, 2, 00, tzinfo=est).tzname()
   1445     'EDT'
   1446 
   1447     >>> datetime(2003, 10, 26, 0, 59, tzinfo=est).tzname()
   1448     'EDT'
   1449     >>> datetime(2003, 10, 26, 1, 00, tzinfo=est).tzname()
   1450     'EST'
   1451 
   1452 
   1453 tzwin examples
   1454 --------------
   1455 
   1456 .. doctest:: tzwin
   1457 
   1458     >>> tz = tzwin("E. South America Standard Time")
   1459 
   1460 
   1461 tzwinlocal examples
   1462 -------------------
   1463 
   1464 
   1465 .. doctest:: tzwinlocal
   1466 
   1467     >>> tz = tzwinlocal()
   1468 
   1469 # vim:ts=4:sw=4:et
   1470