| ## 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 GustavoNiemeyer <gustavo@niemeyer.net>. |
| |
| == 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. |
| |
| 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') |
| }}} |
| |
| ## vim:ft=moin |