aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--README.md5
-rw-r--r--README.old2000
-rw-r--r--README.rst106
-rw-r--r--dateutil/rrule.py4
-rw-r--r--docs/examples.rst1393
-rw-r--r--docs/index.rst7
7 files changed, 1507 insertions, 2009 deletions
diff --git a/NEWS b/NEWS
index 0be457e..5dafbdc 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ Version 2.3
- Fixed tzwin silently not imported on windows python2
+- New maintainer, together with new hosting: GitHub, Travis, Read-The-Docs
Version 2.2
-----------
diff --git a/README.md b/README.md
deleted file mode 100644
index 365f308..0000000
--- a/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-[![Build Status](https://travis-ci.org/dateutil/dateutil.svg?branch=master)](https://travis-ci.org/dateutil/dateutil)
-= dateutil =
-== Description ==
-The dateutil module provides powerful extensions to
-the standard datetime module, available in Python.
diff --git a/README.old b/README.old
deleted file mode 100644
index b1afd9c..0000000
--- a/README.old
+++ /dev/null
@@ -1,2000 +0,0 @@
-## This file is in the moin format. The latest version is found
-## at https://moin.conectiva.com.br/DateUtil
-
-== Contents ==
-[[TableOfContents]]
-
-== Description ==
-The '''dateutil''' module provides powerful extensions to
-the standard '''datetime''' module, available in Python.
-
-== Features ==
-
- * Computing of relative deltas (next month, next year,
- next monday, last week of month, etc);
-
- * Computing of relative deltas between two given
- date and/or datetime objects;
-
- * Computing of dates based on very flexible recurrence rules,
- using a superset of the
- [ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar]
- specification. Parsing of RFC strings is supported as well.
-
- * Generic parsing of dates in almost any string format;
-
- * Timezone (tzinfo) implementations for tzfile(5) format
- files (/etc/localtime, /usr/share/zoneinfo, etc), TZ
- environment string (in all known formats), iCalendar
- format files, given ranges (with help from relative deltas),
- local machine timezone, fixed offset timezone, UTC timezone,
- and Windows registry-based time zones.
-
- * Internal up-to-date world timezone information based on
- Olson's database.
-
- * Computing of Easter Sunday dates for any given year,
- using Western, Orthodox or Julian algorithms;
-
- * More than 400 test cases.
-
-== Quick example ==
-Here's a snapshot, just to give an idea about the power of the
-package. For more examples, look at the documentation below.
-
-Suppose you want to know how much time is left, in
-years/months/days/etc, before the next easter happening on a
-year with a Friday 13th in August, and you want to get today's
-date out of the "date" unix system command. Here is the code:
-{{{
-from dateutil.relativedelta import *
-from dateutil.easter import *
-from dateutil.rrule import *
-from dateutil.parser import *
-from datetime import *
-import commands
-import os
-now = parse(commands.getoutput("date"))
-today = now.date()
-year = rrule(YEARLY,bymonth=8,bymonthday=13,byweekday=FR)[0].year
-rdelta = relativedelta(easter(year), today)
-print "Today is:", today
-print "Year with next Aug 13th on a Friday is:", year
-print "How far is the Easter of that year:", rdelta
-print "And the Easter of that year is:", today+rdelta
-}}}
-
-And here's the output:
-{{{
-Today is: 2003-10-11
-Year with next Aug 13th on a Friday is: 2004
-How far is the Easter of that year: relativedelta(months=+6)
-And the Easter of that year is: 2004-04-11
-}}}
-
-{i} Being exactly 6 months ahead was '''really''' a coincidence :)
-
-== Download ==
-The following files are available.
- * attachment:python-dateutil-1.0.tar.bz2
- * attachment:python-dateutil-1.0-1.noarch.rpm
-
-== Author ==
-The dateutil module was written by Gustavo Niemeyer <gustavo@niemeyer.net> and
-is currently maintained by Tomi Pieviläinen <tomi.pievilainen@iki.fi>. The latest
-code is available in [https://launchpad.net/dateutil Launchpad].
-
-== Documentation ==
-The following modules are available.
-
-=== relativedelta ===
-This module offers the '''relativedelta''' type, which is based
-on the specification of the excelent work done by M.-A. Lemburg in his
-[http://www.egenix.com/files/python/mxDateTime.html mxDateTime]
-extension. However, notice that this type '''does not''' implement the
-same algorithm as his work. Do not expect it to behave like
-{{{mxDateTime}}}'s counterpart.
-
-==== relativedelta type ====
-
-There's two different ways to build a relativedelta instance. The
-first one is passing it two {{{date}}}/{{{datetime}}} instances:
-{{{
-relativedelta(datetime1, datetime2)
-}}}
-
-This will build the relative difference between {{{datetime1}}} and
-{{{datetime2}}}, so that the following constraint is always true:
-{{{
-datetime2+relativedelta(datetime1, datetime2) == datetime1
-}}}
-
-Notice that instead of {{{datetime}}} instances, you may use
-{{{date}}} instances, or a mix of both.
-
-And the other way is to use any of the following keyword arguments:
-
- year, month, day, hour, minute, second, microsecond::
- Absolute information.
-
- years, months, weeks, days, hours, minutes, seconds, microseconds::
- Relative information, may be negative.
-
- weekday::
- One of the weekday instances ({{{MO}}}, {{{TU}}}, etc). These
- instances may receive a parameter {{{n}}}, specifying the {{{n}}}th
- weekday, which could be positive or negative (like {{{MO(+2)}}} or
- {{{MO(-3)}}}. Not specifying it is the same as specifying {{{+1}}}.
- You can also use an integer, where {{{0=MO}}}. Notice that,
- for example, if the calculated date is already Monday, using
- {{{MO}}} or {{{MO(+1)}}} (which is the same thing in this context),
- won't change the day.
-
- leapdays::
- Will add given days to the date found, but only if the computed
- year is a leap year and the computed date is post 28 of february.
-
- yearday, nlyearday::
- Set the yearday or the non-leap year day (jump leap days).
- These are converted to {{{day}}}/{{{month}}}/{{{leapdays}}}
- information.
-
-==== Behavior of operations ====
-If you're curious about exactly how the relative delta will act
-on operations, here is a description of its behavior.
-
- 1. Calculate the absolute year, using the {{{year}}} argument, or the
- original datetime year, if the argument is not present.
- 1. Add the relative {{{years}}} argument to the absolute year.
- 1. Do steps 1 and 2 for {{{month}}}/{{{months}}}.
- 1. Calculate the absolute day, using the {{{day}}} argument, or the
- original datetime day, if the argument is not present. Then, subtract
- from the day until it fits in the year and month found after their
- operations.
- 1. Add the relative {{{days}}} argument to the absolute day. Notice
- that the {{{weeks}}} argument is multiplied by 7 and added to {{{days}}}.
- 1. If {{{leapdays}}} is present, the computed year is a leap year, and
- the computed month is after february, remove one day from the found date.
- 1. Do steps 1 and 2 for {{{hour}}}/{{{hours}}}, {{{minute}}}/{{{minutes}}},
- {{{second}}}/{{{seconds}}}, {{{microsecond}}}/{{{microseconds}}}.
- 1. If the {{{weekday}}} argument is present, calculate the {{{n}}}th
- occurrence of the given weekday.
-
-==== Examples ====
-
-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.
-{{{
->>> NOW+relativedelta(months=+1)
-datetime.datetime(2003, 10, 17, 20, 54, 47, 282310)
-}}}
-
-Next month, plus one week.
-{{{
->>> NOW+relativedelta(months=+1, weeks=+1)
-datetime.datetime(2003, 10, 24, 20, 54, 47, 282310)
-}}}
-
-Next month, plus one week, at 10am.
-{{{
->>> TODAY+relativedelta(months=+1, weeks=+1, hour=10)
-datetime.datetime(2003, 10, 24, 10, 0)
-}}}
-
-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.
-{{{
->>> relativedelta(datetime(2003, 10, 24, 10, 0), TODAY)
-relativedelta(months=+1, days=+7, hours=+10)
-}}}
-
-One month before one year.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> TODAY+relativedelta(weekday=FR)
-datetime.date(2003, 9, 19)
-
->>> TODAY+relativedelta(weekday=calendar.FRIDAY)
-datetime.date(2003, 9, 19)
-}}}
-
-Last friday in this month.
-{{{
->>> TODAY+relativedelta(day=31, weekday=FR(-1))
-datetime.date(2003, 9, 26)
-}}}
-
-Next wednesday (it's today!).
-{{{
->>> TODAY+relativedelta(weekday=WE(+1))
-datetime.date(2003, 9, 17)
-}}}
-
-Next wednesday, but not today.
-{{{
->>> TODAY+relativedelta(days=+1, weekday=WE(+1))
-datetime.date(2003, 9, 24)
-}}}
-
-Following
-[http://www.cl.cam.ac.uk/~mgk25/iso-time.html ISO year week number notation]
-find the first day of the 15th week of 1997.
-{{{
->>> 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?
-{{{
->>> 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?
-{{{
->>> 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.
-{{{
->>> relativedelta(TODAY, johnbirthday)
-relativedelta(years=+25, months=+5, days=+11, hours=+12)
-}}}
-
-Obtain today's date using the yearday:
-{{{
->>> 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:
-{{{
->>> TODAY+relativedelta(yearday=260)
-datetime.date(2003, 9, 17)
-}}}
-
-Last year it should be in the same day:
-{{{
->>> date(2002, 1, 1)+relativedelta(yearday=260)
-datetime.date(2002, 9, 17)
-}}}
-
-But not in a leap year:
-{{{
->>> date(2000, 1, 1)+relativedelta(yearday=260)
-datetime.date(2000, 9, 16)
-}}}
-
-We can use the non-leap year day to ignore this:
-{{{
->>> date(2000, 1, 1)+relativedelta(nlyearday=260)
-datetime.date(2000, 9, 17)
-}}}
-
-=== rrule ===
-The rrule module offers a small, complete, and very fast, implementation
-of the recurrence rules documented in the
-[ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar RFC], including
-support for caching of results.
-
-==== rrule type ====
-That's the base of the rrule operation. It accepts all the keywords
-defined in the RFC as its constructor parameters (except {{{byday}}},
-which was renamed to {{{byweekday}}}) and more. The constructor
-prototype is:
-{{{
-rrule(freq)
-}}}
-
-Where {{{freq}}} must be one of {{{YEARLY}}}, {{{MONTHLY}}},
-{{{WEEKLY}}}, {{{DAILY}}}, {{{HOURLY}}}, {{{MINUTELY}}},
-or {{{SECONDLY}}}.
-
-Additionally, it supports the following keyword arguments:
-
- cache::
- If given, it must be a boolean value specifying to enable
- or disable caching of results. If you will use the same
- {{{rrule}}} instance multiple times, enabling caching will
- improve the performance considerably.
-
- dtstart::
- The recurrence start. Besides being the base for the
- recurrence, missing parameters in the final recurrence
- instances will also be extracted from this date. If not
- given, {{{datetime.now()}}} will be used instead.
-
- interval::
- The interval between each {{{freq}}} iteration. For example,
- when using {{{YEARLY}}}, an interval of {{{2}}} means
- once every two years, but with {{{HOURLY}}}, it means
- once every two hours. The default interval is {{{1}}}.
-
- wkst::
- The week start day. Must be one of the {{{MO}}}, {{{TU}}},
- {{{WE}}} constants, or an integer, specifying the first day
- of the week. This will affect recurrences based on weekly
- periods. The default week start is got from
- {{{calendar.firstweekday()}}}, and may be modified by
- {{{calendar.setfirstweekday()}}}.
-
- count::
- How many occurrences will be generated.
-
- until::
- If given, this must be a {{{datetime}}} instance, that will
- specify the limit of the recurrence. If a recurrence instance
- happens to be the same as the {{{datetime}}} instance given
- in the {{{until}}} keyword, this will be the last occurrence.
-
- bysetpos::
- If given, it must be either an integer, or a sequence of
- integers, positive or negative. Each given integer will
- specify an occurrence number, corresponding to the nth
- occurrence of the rule inside the frequency period. For
- example, a {{{bysetpos}}} of {{{-1}}} if combined with a
- {{{MONTHLY}}} frequency, and a {{{byweekday}}} of
- {{{(MO, TU, WE, TH, FR)}}}, will result in the last work
- day of every month.
-
- bymonth::
- If given, it must be either an integer, or a sequence of
- integers, meaning the months to apply the recurrence to.
-
- bymonthday::
- If given, it must be either an integer, or a sequence of
- integers, meaning the month days to apply the recurrence to.
-
- byyearday::
- If given, it must be either an integer, or a sequence of
- integers, meaning the year days to apply the recurrence to.
-
- byweekno::
- If given, it must be either an integer, or a sequence of
- integers, meaning the week numbers to apply the recurrence
- to. Week numbers have the meaning described in ISO8601,
- that is, the first week of the year is that containing at
- least four days of the new year.
-
- byweekday::
- If given, it must be either an integer ({{{0 == MO}}}), a
- sequence of integers, one of the weekday constants
- ({{{MO}}}, {{{TU}}}, etc), or a sequence of these constants.
- When given, these variables will define the weekdays where
- the recurrence will be applied. It's also possible to use
- an argument {{{n}}} for the weekday instances, which will
- mean the {{{n}}}''th'' occurrence of this weekday in the
- period. For example, with {{{MONTHLY}}}, or with
- {{{YEARLY}}} and {{{BYMONTH}}}, using {{{FR(+1)}}}
- in {{{byweekday}}} will specify the first friday of the
- month where the recurrence happens. Notice that in the RFC
- documentation, this is specified as {{{BYDAY}}}, but was
- renamed to avoid the ambiguity of that keyword.
-
- byhour::
- If given, it must be either an integer, or a sequence of
- integers, meaning the hours to apply the recurrence to.
-
- byminute::
- If given, it must be either an integer, or a sequence of
- integers, meaning the minutes to apply the recurrence to.
-
- bysecond::
- If given, it must be either an integer, or a sequence of
- integers, meaning the seconds to apply the recurrence to.
-
- byeaster::
- If given, it must be either an integer, or a sequence of
- integers, positive or negative. Each integer will define
- an offset from the Easter Sunday. Passing the offset
- {{{0}}} to {{{byeaster}}} will yield the Easter Sunday
- itself. This is an extension to the RFC specification.
-
-==== rrule methods ====
-The following methods are available in {{{rrule}}} instances:
-
- rrule.before(dt, inc=False)::
- Returns the last recurrence before the given {{{datetime}}}
- instance. The {{{inc}}} keyword defines what happens if
- {{{dt}}} '''is''' an occurrence. With {{{inc == True}}},
- if {{{dt}}} itself is an occurrence, it will be returned.
-
- rrule.after(dt, inc=False)::
- Returns the first recurrence after the given {{{datetime}}}
- instance. The {{{inc}}} keyword defines what happens if
- {{{dt}}} '''is''' an occurrence. With {{{inc == True}}},
- if {{{dt}}} itself is an occurrence, it will be returned.
-
- rrule.between(after, before, inc=False)::
- Returns all the occurrences of the rrule between {{{after}}}
- and {{{before}}}. The {{{inc}}} keyword defines what happens
- if {{{after}}} and/or {{{before}}} are themselves occurrences.
- With {{{inc == True}}}, they will be included in the list,
- if they are found in the recurrence set.
-
- rrule.count()::
- Returns the number of recurrences in this set. It will have
- go trough the whole recurrence, if this hasn't been done
- before.
-
-Besides these methods, {{{rrule}}} instances also support
-the {{{__getitem__()}}} and {{{__contains__()}}} special methods,
-meaning that these are valid expressions:
-{{{
-rr = rrule(...)
-if datetime(...) in rr:
- ...
-print rr[0]
-print rr[-1]
-print rr[1:2]
-print rr[::-2]
-}}}
-
-The getitem/slicing mechanism is smart enough to avoid getting the whole
-recurrence set, if possible.
-
-==== Notes ====
-
- * The rrule type has no {{{byday}}} keyword. The equivalent keyword
- has been replaced by the {{{byweekday}}} keyword, to remove the
- ambiguity present in the original keyword.
-
- * Unlike documented in the RFC, the starting datetime ({{{dtstart}}})
- is not the first recurrence instance, unless it does fit in the
- specified rules. In a python module context, this behavior makes more
- sense than otherwise. Notice that you can easily get the original
- behavior by using a rruleset and adding the {{{dtstart}}} as an
- {{{rdate}}} recurrence.
-
- * Unlike documented in the RFC, every keyword is valid on every
- frequency (the RFC documents that {{{byweekno}}} is only valid
- on yearly frequencies, for example).
-
- * In addition to the documented keywords, a {{{byeaster}}} keyword
- was introduced, making it easy to compute recurrent events relative
- to the Easter Sunday.
-
-==== rrule examples ====
-These examples were converted from the RFC.
-
-Prepare the environment.
-{{{
->>> from dateutil.rrule import *
->>> from dateutil.parser import *
->>> from datetime import *
-
->>> import pprint
->>> import sys
->>> sys.displayhook = pprint.pprint
-}}}
-
-Daily, for 10 occurrences.
-{{{
->>> 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
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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, 29, 9, 0),
- datetime.datetime(2000, 1, 31, 9, 0)]
-}}}
-
-Same thing, in another way.
-{{{
->>> list(rrule(DAILY, bymonth=1,
- dtstart=parse("19980101T090000"),
- until=parse("20000131T090000")))
-(...)
-}}}
-
-Weekly for 10 occurrences.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> list(rrule(MONTHLY, count=5, bymonthday=(-1,1,),
- dtstart=parse("1997090
-2T090000")))
-[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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> list(rrule(YEARLY, count=4, bymonth=(6,7),
- dtstart=parse("19970610T0900
-00")))
-[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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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:
-{{{
->>> 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.
-{{{
->>> 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):
-{{{
->>> 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:
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> 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}}}.
-{{{
->>> 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 type ====
-The {{{rruleset}}} type allows more complex recurrence setups, mixing
-multiple rules, dates, exclusion rules, and exclusion dates.
-The type constructor takes the following keyword arguments:
-
- cache::
- If True, caching of results will be enabled, improving performance
- of multiple queries considerably.
-
-==== rruleset methods ====
-The following methods are available:
-
- rruleset.rrule(rrule)::
- Include the given {{{rrule}}} instance in the recurrence set
- generation.
-
- rruleset.rdate(dt)::
- Include the given {{{datetime}}} instance in the recurrence
- set generation.
-
- rruleset.exrule(rrule)::
- Include the given {{{rrule}}} instance in the recurrence set
- exclusion list. Dates which are part of the given recurrence
- rules will not be generated, even if some inclusive {{{rrule}}}
- or {{{rdate}}} matches them.
-
- rruleset.exdate(dt)::
- Include the given {{{datetime}}} instance in the recurrence set
- exclusion list. Dates included that way will not be generated,
- even if some inclusive {{{rrule}}} or {{{rdate}}} matches them.
-
- rruleset.before(dt, inc=False)::
- Returns the last recurrence before the given {{{datetime}}}
- instance. The {{{inc}}} keyword defines what happens if
- {{{dt}}} '''is''' an occurrence. With {{{inc == True}}},
- if {{{dt}}} itself is an occurrence, it will be returned.
-
- rruleset.after(dt, inc=False)::
- Returns the first recurrence after the given {{{datetime}}}
- instance. The {{{inc}}} keyword defines what happens if
- {{{dt}}} '''is''' an occurrence. With {{{inc == True}}},
- if {{{dt}}} itself is an occurrence, it will be returned.
-
- rruleset.between(after, before, inc=False)::
- Returns all the occurrences of the rrule between {{{after}}}
- and {{{before}}}. The {{{inc}}} keyword defines what happens
- if {{{after}}} and/or {{{before}}} are themselves occurrences.
- With {{{inc == True}}}, they will be included in the list,
- if they are found in the recurrence set.
-
- rruleset.count()::
- Returns the number of recurrences in this set. It will have
- go trough the whole recurrence, if this hasn't been done
- before.
-
-Besides these methods, {{{rruleset}}} instances also support
-the {{{__getitem__()}}} and {{{__contains__()}}} special methods,
-meaning that these are valid expressions:
-{{{
-set = rruleset(...)
-if datetime(...) in set:
- ...
-print set[0]
-print set[-1]
-print set[1:2]
-print set[::-2]
-}}}
-
-The getitem/slicing mechanism is smart enough to avoid getting the whole
-recurrence set, if possible.
-
-==== rruleset examples ====
-Daily, for 7 days, jumping Saturday and Sunday occurrences.
-{{{
->>> 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.
-{{{
->>> 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() function ====
-The {{{rrulestr()}}} function is a parser for ''RFC-like'' syntaxes.
-The function prototype is:
-{{{
-rrulestr(str)
-}}}
-
-The string passed as parameter may be a multiple line string, a
-single line string, or just the {{{RRULE}}} property value.
-
-Additionally, it accepts the following keyword arguments:
-
- cache::
- If {{{True}}}, the {{{rruleset}}} or {{{rrule}}} created instance
- will cache its results. Default is not to cache.
-
- dtstart::
- If given, it must be a {{{datetime}}} instance that will be used
- when no {{{DTSTART}}} property is found in the parsed string. If
- it is not given, and the property is not found, {{{datetime.now()}}}
- will be used instead.
-
- unfold::
- If set to {{{True}}}, lines will be unfolded following the RFC
- specification. It defaults to {{{False}}}, meaning that spaces
- before every line will be stripped.
-
- forceset::
- If set to {{{True}}} a {{{rruleset}}} instance will be returned,
- even if only a single rule is found. The default is to return an
- {{{rrule}}} if possible, and an {{{rruleset}}} if necessary.
-
- compatible::
- If set to {{{True}}}, the parser will operate in RFC-compatible
- mode. Right now it means that {{{unfold}}} will be turned on,
- and if a {{{DTSTART}}} is found, it will be considered the first
- recurrence instance, as documented in the RFC.
-
- ignoretz::
- If set to {{{True}}}, the date parser will ignore timezone
- information available in the {{{DTSTART}}} property, or the
- {{{UNTIL}}} attribute.
-
- tzinfos::
- If set, it will be passed to the datetime string parser to
- resolve unknown timezone settings. For more information about
- what could be used here, check the parser documentation.
-
-==== rrulestr() examples ====
-
-Every 10 days, 5 occurrences.
-{{{
->>> 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.
-{{{
->>> 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.
-{{{
->>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5")
-<dateutil.rrule.rrule instance at 0x30269f08>
-
->>> rrulestr("""
-... DTSTART:19970902T090000
-... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
-... """)
-<dateutil.rrule.rrule instance at 0x302699e0>
-
->>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", forceset=True)
-<dateutil.rrule.rruleset instance at 0x30269f08>
-}}}
-
-But when an {{{rruleset}}} is needed, it is automatically used.
-{{{
->>> rrulestr("""
-... DTSTART:19970902T090000
-... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
-... RRULE:FREQ=DAILY;INTERVAL=5;COUNT=3
-... """)
-<dateutil.rrule.rruleset instance at 0x302699e0>
-}}}
-
-=== parser ===
-This module offers a generic date/time string parser which is
-able to parse most known formats to represent a date and/or
-time.
-
-==== parse() function ====
-That's probably the only function you'll need from this module.
-It offers you an interface to access the parser functionality and
-extract a {{{datetime}}} type out of a string.
-
-The prototype of this function is:
-{{{
-parse(timestr)
-}}}
-
-Additionally, the following keyword arguments are available:
-
- default::
- If given, this must be a {{{datetime}}} instance. Any fields
- missing in the parsed date will be copied from this instance.
- The default value is the current date, at 00:00:00am.
-
- ignoretz::
- If this is true, even if a timezone is found in the string,
- the parser will not use it.
-
- tzinfos::
- Using this keyword argument you may provide custom timezones
- to the parser. If given, it must be either a dictionary with
- the timezone abbreviation as key, or a function accepting a
- timezone abbreviation and offset as argument. The dictionary
- values and the function return must be a timezone offset
- in seconds, a tzinfo subclass, or a string defining the
- timezone (in the TZ environment variable format).
-
- dayfirst::
- This option allow one to change the precedence in which
- days are parsed in date strings. The default is given in the
- parserinfo instance (the default parserinfo has it set to
- False). If {{{dayfirst}}} is False, the {{{MM-DD-YYYY}}}
- format will have precedence over {{{DD-MM-YYYY}}} in an
- ambiguous date.
-
- yearfirst::
- This option allow one to change the precedence in which
- years are parsed in date strings. The default is given in
- the parserinfo instance (the default parserinfo has it set
- to False). If {{{yearfirst}}} is false, the {{{MM-DD-YY}}}
- format will have precedence over {{{YY-MM-DD}}} in an
- ambiguous date.
-
- fuzzy::
- If {{{fuzzy}}} is set to True, unknown tokens in the string
- will be ignored.
-
- fuzzy_with_tokens::
- Similar to {{{fuzzy}}}, but will result a tuple of the normal
- results and the skipped tokens.
-
- parserinfo::
- This parameter allows one to change how the string is parsed,
- by using a different parserinfo class instance. Using it you
- may, for example, intenationalize the parser strings, or make
- it ignore additional words.
-
-==== Format precedence ====
-Whenever an ambiguous date is found, the {{{dayfirst}}} and
-{{{yearfirst}}} parameters will control how the information
-is processed. Here is the precedence in each case:
-
-If {{{dayfirst}}} is {{{False}}} and {{{yearfirst}}} is {{{False}}},
-(default, if no parameter is given):
-
- * {{{MM-DD-YY}}}
- * {{{DD-MM-YY}}}
- * {{{YY-MM-DD}}}
-
-If {{{dayfirst}}} is {{{True}}} and {{{yearfirst}}} is {{{False}}}:
-
- * {{{DD-MM-YY}}}
- * {{{MM-DD-YY}}}
- * {{{YY-MM-DD}}}
-
-If {{{dayfirst}}} is {{{False}}} and {{{yearfirst}}} is {{{True}}}:
-
- * {{{YY-MM-DD}}}
- * {{{MM-DD-YY}}}
- * {{{DD-MM-YY}}}
-
-If {{{dayfirst}}} is {{{True}}} and {{{yearfirst}}} is {{{True}}}:
-
- * {{{YY-MM-DD}}}
- * {{{DD-MM-YY}}}
- * {{{MM-DD-YY}}}
-
-==== Converting two digit years ====
-When a two digit year is found, it is processed considering
-the current year, so that the computed year is never more
-than 49 years after the current year, nor 50 years before the
-current year. In other words, if we are in year 2003, and the
-year 30 is found, it will be considered as 2030, but if the
-year 60 is found, it will be considered 1960.
-
-==== Examples ====
-The following code will prepare the environment:
-{{{
->>> from dateutil.parser import *
->>> from dateutil.tz import *
->>> from datetime import *
->>> TZOFFSETS = {"BRST": -10800}
->>> BRSTTZ = tzoffset(-10800, "BRST")
->>> DEFAULT = datetime(2003, 9, 25)
-}}}
-
-Some simple examples based on the {{{date}}} command, using the
-{{{TZOFFSET}}} dictionary to provide the BRST timezone offset.
-{{{
->>> 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.
-{{{
->>> 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:
-{{{
->>> 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:
-{{{
->>> 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:
-{{{
->>> parse("Thu Sep 25 10:36:28", default=DEFAULT)
-datetime.datetime(2003, 9, 25, 10, 36, 28)
-}}}
-
-Strip it further:
-{{{
->>> 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:
-{{{
->>> 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):
-{{{
->>> parse("Thu, 25 Sep 2003 10:49:41 -0300")
-datetime.datetime(2003, 9, 25, 10, 49, 41,
- tzinfo=tzoffset(None, -10800))
-}}}
-
-ISO format:
-{{{
->>> parse("2003-09-25T10:49:41.5-03:00")
-datetime.datetime(2003, 9, 25, 10, 49, 41, 500000,
- tzinfo=tzoffset(None, -10800))
-}}}
-
-Some variations:
-{{{
->>> 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:
-{{{
->>> parse("20030925T104941.5-0300")
-datetime.datetime(2003, 9, 25, 10, 49, 41, 500000,
- tzinfo=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.
-{{{
->>> parse("199709020900")
-datetime.datetime(1997, 9, 2, 9, 0)
->>> parse("19970902090059")
-datetime.datetime(1997, 9, 2, 9, 0, 59)
-}}}
-
-Different date orderings:
-{{{
->>> 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:
-{{{
->>> 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:
-{{{
->>> 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:
-{{{
->>> 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:
-{{{
->>> 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, 3, 1, 2)
-
->>> parse("01h02", default=DEFAULT)
-datetime.datetime(2003, 9, 2, 1, 0)
-
->>> parse("01h02s", default=DEFAULT)
-datetime.datetime(2003, 9, 25, 1, 0, 2)
-}}}
-
-With AM/PM:
-{{{
->>> 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:
-{{{
->>> 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:
-{{{
->>> 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:
-{{{
->>> 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)
-}}}
-
-=== easter ===
-This module offers a generic easter computing method for
-any given year, using Western, Orthodox or Julian algorithms.
-
-==== easter() function ====
-This method was ported from the work done by
-[http://users.chariot.net.au/~gmarts/eastalg.htm GM Arts],
-on top of the algorithm by
-[http://www.tondering.dk/claus/calendar.html Claus Tondering],
-which was based in part on the algorithm of Ouding (1940),
-as quoted in "Explanatory Supplement to the Astronomical
-Almanac", P. Kenneth Seidelmann, editor.
-
-This algorithm implements three different easter
-calculation methods:
-
- 1. Original calculation in Julian calendar, valid in
- dates after 326 AD
- 1. Original method, with date converted to Gregorian
- calendar, valid in years 1583 to 4099
- 1. Revised method, in Gregorian calendar, valid in
- years 1583 to 4099 as well
-
-These methods are represented by the constants:
-{{{
-EASTER_JULIAN = 1
-EASTER_ORTHODOX = 2
-EASTER_WESTERN = 3
-}}}
-
-The default method is method 3.
-
-=== tz ===
-This module offers timezone implementations subclassing
-the abstract {{{datetime.tzinfo}}} type. There are
-classes to handle [http://www.twinsun.com/tz/tz-link.htm tzfile]
-format files (usually are in /etc/localtime,
-/usr/share/zoneinfo, etc), TZ environment string (in all
-known formats), given ranges (with help from relative
-deltas), local machine timezone, fixed offset timezone,
-and UTC timezone.
-
-==== tzutc type ====
-This type implements a basic UTC timezone. The constructor of this
-type accepts no parameters.
-
-==== tzutc examples ====
-{{{
->>> 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 type ====
-This type implements a fixed offset timezone, with no
-support to daylight saving times. Here is the prototype of the
-type constructor:
-{{{
-tzoffset(name, offset)
-}}}
-
-The {{{name}}} parameter may be optionally set to {{{None}}}, and
-{{{offset}}} must be given in seconds.
-
-==== tzoffset examples ====
-{{{
->>> 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 type ====
-This type implements timezone settings as known by the
-operating system. The constructor of this type accepts no
-parameters.
-
-==== tzlocal examples ====
-{{{
->>> 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 type ====
-This type implements timezone settings extracted from a
-string in known TZ environment variable formats. Here is the prototype
-of the constructor:
-{{{
-tzstr(str)
-}}}
-
-==== tzstr examples ====
-Here are examples of the recognized formats:
-
- * {{{EST5EDT}}}
- * {{{EST5EDT,4,0,6,7200,10,0,26,7200,3600}}}
- * {{{EST5EDT,4,1,0,7200,10,-1,0,7200,3600}}}
- * {{{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
-[http://www.python.org/doc/current/lib/module-time.html time module documentation].
-{{{
->>> 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.
-{{{
->>> 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?
-{{{
->>> tzstr('EST5EDT') == tzstr('EST5EDT,4,1,0,7200,10,-1,0,7200,3600')
-True
-}}}
-
-Check the daylight limit.
-{{{
->>> 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'
-}}}
-
-==== tzrange type ====
-This type offers the same functionality as the {{{tzstr}}} type, but
-instead of timezone strings, information is passed using
-{{{relativedelta}}}s which are applied to a datetime set to the first
-day of the year. Here is the prototype of this type's constructor:
-{{{
-tzrange(stdabbr, stdoffset=None, dstabbr=None, dstoffset=None,
- start=None, end=None):
-}}}
-
-Offsets must be given in seconds. Information not provided will be
-set to the defaults, as explained in the {{{tzstr}}} section above.
-
-==== tzrange examples ====
-{{{
->>> 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
-[http://www.python.org/doc/current/lib/datetime-tzinfo.html tzinfo documentation]
-for more information.
-
-==== tzfile type ====
-This type allows one to use tzfile(5) format timezone files to extract
-current and historical zone information. Here is the type constructor
-prototype:
-{{{
-tzfile(fileobj)
-}}}
-
-Where {{{fileobj}}} is either a filename or a file-like object with
-a {{{read()}}} method.
-
-==== tzfile examples ====
-{{{
->>> 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.
-{{{
->>> 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 type ====
-This type is able to parse
-[ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar]
-style {{{VTIMEZONE}}} sessions into a Python timezone object.
-The constuctor prototype is:
-{{{
-tzical(fileobj)
-}}}
-
-Where {{{fileobj}}} is either a filename or a file-like object with
-a {{{read()}}} method.
-
-==== tzical methods ====
-
- tzical.get(tzid=None)::
- Since a single iCalendar file may contain more than one timezone,
- you must ask for the timezone you want with this method. If there's
- more than one timezone in the parsed file, you'll need to pass the
- {{{tzid}}} parameter. Otherwise, leaving it empty will yield the only
- available timezone.
-
-==== 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.
-{{{
-BEGIN:VTIMEZONE
-TZID:US-Eastern
-LAST-MODIFIED:19870101T000000Z
-TZURL:http://zones.stds_r_us.net/tz/US-Eastern
-BEGIN:STANDARD
-DTSTART:19671029T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-TZNAME:EST
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:19870405T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-TZNAME:EDT
-END:DAYLIGHT
-END:VTIMEZONE
-}}}
-
-And here is an example exploring a {{{tzical}}} type:
-{{{
->>> from dateutil.tz import *; from datetime import *
-
->>> tz = tzical('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:
-{{{
->>> 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 type ====
-This type offers access to internal registry-based Windows timezones.
-The constuctor prototype is:
-{{{
-tzwin(name)
-}}}
-
-Where {{{name}}} is the timezone name. There's a static {{{tzwin.list()}}}
-method to check the available names,
-
-==== tzwin methods ====
-
- tzwin.display()::
- This method returns the timezone extended name.
-
- tzwin.list()::
- This static method lists all available timezone names.
-
-==== tzwin examples ====
-{{{
->>> tz = tzwin("E. South America Standard Time")
-}}}
-
-==== tzwinlocal type ====
-This type offers access to internal registry-based Windows timezones.
-The constructor accepts no parameters, so the prototype is:
-{{{
-tzwinlocal()
-}}}
-
-==== tzwinlocal methods ====
-
- tzwinlocal.display()::
- This method returns the timezone extended name, and returns
- {{{None}}} if one is not available.
-
-==== tzwinlocal examples ====
-{{{
->>> tz = tzwinlocal()
-}}}
-
-==== gettz() function ====
-This function is a helper that will try its best to get the right
-timezone for your environment, or for the given string. The prototype
-is as follows:
-{{{
-gettz(name=None)
-}}}
-
-If given, the parameter may be a filename, a path relative to the base
-of the timezone information path (the base could be
-{{{/usr/share/zoneinfo}}}, for example), a string timezone
-specification, or a timezone abbreviation. If {{{name}}} is not given,
-and the {{{TZ}}} environment variable is set, it's used instead. If the
-parameter is not given, and {{{TZ}}} is not set, the default tzfile
-paths will be tried. Then, if no timezone information is found,
-an internal compiled database of timezones is used. When running
-on Windows, the internal registry-based Windows timezones are also
-considered.
-
-Example:
-{{{
->>> from dateutil.tz import *
->>> gettz()
-tzfile('/etc/localtime')
-
->>> gettz("America/Sao Paulo")
-tzfile('/usr/share/zoneinfo/America/Sao_Paulo')
-
->>> gettz("EST5EDT")
-tzfile('/usr/share/zoneinfo/EST5EDT')
-
->>> gettz("EST5")
-tzstr('EST5')
-
->>> gettz('BRST')
-tzlocal()
-
->>> os.environ["TZ"] = "America/Sao Paulo"
->>> gettz()
-tzfile('/usr/share/zoneinfo/America/Sao_Paulo')
-
->>> os.environ["TZ"] = "BRST"
->>> gettz()
-tzlocal()
-
->>> gettz("Unavailable")
->>>
-}}}
-
-=== zoneinfo ===
-This module provides direct access to the internal compiled
-database of timezones. The timezone data and the compiling tools
-are obtained from the following project:
-
- http://www.twinsun.com/tz/tz-link.htm
-
-==== gettz() function ====
-This function will try to retrieve the given timezone information
-from the internal compiled database, and will cache its results.
-
-Example:
-{{{
->>> from dateutil import zoneinfo
->>> zoneinfo.gettz("Brazil/East")
-tzfile('Brazil/East')
-}}}
-
-
-== Building and releasing ==
-When you get the source, it does not contain the internal zoneinfo
-database. To get (and update) the database, run the updatezinfo.py script. Make sure
-that the zic command is in your path, and that you have network connectivity
-to get the latest timezone information from IANA. If you have downloaded
-the timezone data earlier, you can give the tarball as a parameter to
-updatezinfo.py.
-
-After testing any changes, changing the version information in dateutil/__init__.py
-and updating NEWS, a new release can be uploaded to PyPI with
-{{{
-python setup.py sdist upload
-}}}
-
-
-== Testing ==
-dateutil has a comprehensive test suite, which can be run simply by running the
-test.py script in the project root. Note that if you don't have the internal
-zoneinfo database, some tests will fail. Apart from that, all tests should pass.
-
-To easily test dateutil against all supported Python versions, you can use
-[[[http://tox.readthedocs.org/en/latest/ tox]]].
-
-## vim:ft=moin
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..3d48ebf
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,106 @@
+dateutil - powerfull extensions to datetime
+===========================================
+The `dateutil` module provides powerful extensions to
+the standard `datetime` module, available in Python.
+
+
+Download
+========
+dateutil is available on PyPI
+https://pypi.python.org/pypi/python-dateutil/
+
+The documentation is hosted at:
+https://dateutil.readthedocs.org/
+
+Code
+====
+https://github.com/dateutil/dateutil/
+
+Features
+========
+
+* Computing of relative deltas (next month, next year,
+ next monday, last week of month, etc);
+* Computing of relative deltas between two given
+ date and/or datetime objects;
+* Computing of dates based on very flexible recurrence rules,
+ using a superset of the
+ [ftp://ftp.rfc-editor.org/in-notes/rfc2445.txt iCalendar]
+ specification. Parsing of RFC strings is supported as well.
+* Generic parsing of dates in almost any string format;
+* Timezone (tzinfo) implementations for tzfile(5) format
+ files (/etc/localtime, /usr/share/zoneinfo, etc), TZ
+ environment string (in all known formats), iCalendar
+ format files, given ranges (with help from relative deltas),
+ local machine timezone, fixed offset timezone, UTC timezone,
+ and Windows registry-based time zones.
+* Internal up-to-date world timezone information based on
+ Olson's database.
+* Computing of Easter Sunday dates for any given year,
+ using Western, Orthodox or Julian algorithms;
+* More than 400 test cases.
+
+Quick example
+=============
+Here's a snapshot, just to give an idea about the power of the
+package. For more examples, look at the documentation.
+
+Suppose you want to know how much time is left, in
+years/months/days/etc, before the next easter happening on a
+year with a Friday 13th in August, and you want to get today's
+date out of the "date" unix system command. Here is the code:
+
+.. doctest:: readmeexample
+
+ >>> from dateutil.relativedelta import *
+ >>> from dateutil.easter import *
+ >>> from dateutil.rrule import *
+ >>> from dateutil.parser import *
+ >>> from datetime import *
+ >>> now = parse("Sat Oct 11 17:13:46 UTC 2003")
+ >>> today = now.date()
+ >>> year = rrule(YEARLY,dtstart=now,bymonth=8,bymonthday=13,byweekday=FR)[0].year
+ >>> rdelta = relativedelta(easter(year), today)
+ >>> print("Today is: %s" % today)
+ Today is: 2003-10-11
+ >>> print("Year with next Aug 13th on a Friday is: %s" % year)
+ Year with next Aug 13th on a Friday is: 2004
+ >>> print("How far is the Easter of that year: %s" % rdelta)
+ How far is the Easter of that year: relativedelta(months=+6)
+ >>> print("And the Easter of that year is: %s" % (today+rdelta))
+ And the Easter of that year is: 2004-04-11
+
+Being exactly 6 months ahead was **really** a coincidence :)
+
+
+Author
+======
+The dateutil module was written by Gustavo Niemeyer <gustavo@niemeyer.net>
+in 2003
+
+It is maintained by:
+
+* Gustavo Niemeyer <gustavo@niemeyer.net> 2003-2013
+* Tomi Pieviläinen <tomi.pievilainen@iki.fi> 2013-2014
+* Yaron de Leeuw <me@jarond.net> 2014-
+
+Building and releasing
+======================
+When you get the source, it does not contain the internal zoneinfo
+database. To get (and update) the database, run the updatezinfo.py script. Make sure
+that the zic command is in your path, and that you have network connectivity
+to get the latest timezone information from IANA. If you have downloaded
+the timezone data earlier, you can give the tarball as a parameter to
+updatezinfo.py.
+
+
+Testing
+=======
+dateutil has a comprehensive test suite, which can be run simply by running
+`python setup.py test [-q]` in the project root. Note that if you don't have the internal
+zoneinfo database, some tests will fail. Apart from that, all tests should pass.
+
+To easily test dateutil against all supported Python versions, you can use
+`tox <https://tox.readthedocs.org/en/latest/>`_.
+
+All github pull requests are automatically tested using travis.
diff --git a/dateutil/rrule.py b/dateutil/rrule.py
index 91bdedf..6e886ec 100644
--- a/dateutil/rrule.py
+++ b/dateutil/rrule.py
@@ -925,11 +925,11 @@ class rruleset(rrulebase):
self._exdate = []
def rrule(self, rrule):
- """ Include the given :py:`rrule` instance in the recurrence set generation. """
+ """ Include the given :py:class:`rrule` instance in the recurrence set generation. """
self._rrule.append(rrule)
def rdate(self, rdate):
- """ Include the given :py:`datetime` instance in the recurrence set generation. """
+ """ Include the given :py:class:`datetime` instance in the recurrence set generation. """
self._rdate.append(rdate)
def exrule(self, exrule):
diff --git a/docs/examples.rst b/docs/examples.rst
new file mode 100644
index 0000000..815e457
--- /dev/null
+++ b/docs/examples.rst
@@ -0,0 +1,1393 @@
+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)
+
+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
+[http://www.cl.cam.ac.uk/~mgk25/iso-time.html ISO year week number notation]
+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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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, 29, 9, 0),
+ datetime.datetime(2000, 1, 31, 9, 0)]
+
+Same thing, in another way.
+
+.. doctest:: rrule
+
+ >>> list(rrule(DAILY, bymonth=1,
+ dtstart=parse("19980101T090000"),
+ until=parse("20000131T090000")))
+ (...)
+
+Weekly for 10 occurrences.
+
+.. doctest:: rrule
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> list(rrule(MONTHLY, count=5, bymonthday=(-1,1,),
+ dtstart=parse("1997090
+ 2T090000")))
+ [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
+
+ >>> 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
+
+ >>> 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
+
+ >>> list(rrule(YEARLY, count=4, bymonth=(6,7),
+ dtstart=parse("19970610T0900
+ 00")))
+ [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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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.
+
+.. doctest:: rruleset
+
+ >>> 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
+
+ >>> 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.
+
+.. doctest:: rrulestr
+
+ >>> 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
+
+ >>> 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
+
+ >>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5")
+ <dateutil.rrule.rrule instance at 0x30269f08>
+
+ >>> rrulestr("""
+ ... DTSTART:19970902T090000
+ ... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
+ ... """)
+ <dateutil.rrule.rrule instance at 0x302699e0>
+
+ >>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", forceset=True)
+ <dateutil.rrule.rruleset instance at 0x30269f08>
+
+
+But when an `rruleset` is needed, it is automatically used.
+
+.. doctest:: rrulestr
+
+ >>> rrulestr("""
+ ... DTSTART:19970902T090000
+ ... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
+ ... RRULE:FREQ=DAILY;INTERVAL=5;COUNT=3
+ ... """)
+ <dateutil.rrule.rruleset instance at 0x302699e0>
+
+
+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(-10800, "BRST")
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> 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
+
+ >>> parse("20030925T104941.5-0300")
+ datetime.datetime(2003, 9, 25, 10, 49, 41, 500000,
+ tzinfo=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, 3, 1, 2)
+
+ >>> parse("01h02", default=DEFAULT)
+ datetime.datetime(2003, 9, 2, 1, 0)
+
+ >>> 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
+
+ >>> 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)
+
+
+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
+
+ >>> 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`
+ * `EST5EDT,4,0,6,7200,10,0,26,7200,3600`
+ * `EST5EDT,4,1,0,7200,10,-1,0,7200,3600`
+ * `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
+
+[http://www.python.org/doc/current/lib/module-time.html time module documentation].
+
+
+.. 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,4,1,0,7200,10,-1,0,7200,3600')
+ True
+
+
+Check the daylight limit.
+
+.. doctest:: tzstr
+
+ >>> 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'
+
+
+tzrange examples
+----------------
+
+.. 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
+
+[http://www.python.org/doc/current/lib/datetime-tzinfo.html tzinfo documentation]
+
+for more information.
+
+tzfile examples
+---------------
+
+.. doctest:: tzfile
+
+ >>> 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.
+
+ BEGIN:VTIMEZONE
+ TZID:US-Eastern
+ LAST-MODIFIED:19870101T000000Z
+ TZURL:http://zones.stds_r_us.net/tz/US-Eastern
+ BEGIN:STANDARD
+ DTSTART:19671029T020000
+ RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+ TZOFFSETFROM:-0400
+ TZOFFSETTO:-0500
+ TZNAME:EST
+ END:STANDARD
+ BEGIN:DAYLIGHT
+ DTSTART:19870405T020000
+ RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+ TZOFFSETFROM:-0500
+ TZOFFSETTO:-0400
+ TZNAME:EDT
+ END:DAYLIGHT
+ END:VTIMEZONE
+
+And here is an example exploring a `tzical` type:
+
+.. doctest:: tzfile
+
+ >>> from dateutil.tz import *; from datetime import *
+
+ >>> tz = tzical('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
diff --git a/docs/index.rst b/docs/index.rst
index 4d8f560..5d252f6 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -3,9 +3,11 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
-Welcome to dateutil's documentation!
-====================================
+.. include:: ../README.rst
+
+Documentation
+=============
Contents:
.. toctree::
@@ -18,6 +20,7 @@ Contents:
rrule
tz
zoneinfo
+ examples
Indices and tables
==================