From 07d8416b99634da72124e17f08b02794670cf8d3 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 22 Aug 2012 10:03:10 -0400 Subject: [PATCH] Update pytz to 2012d and update dateutil to 1.5 for Python 2.x and 2.1 for Python 3.x Update setup.py so that it assume datetime is always there (as it should be on the versions of Python we support). Update setup.py to not 2to3 pytz. Update setup.py to install the correct version of dateutil that matches the version of Python. --- doc/users/whats_new.rst | 10 + lib/{dateutil => dateutil_py2}/LICENSE | 0 lib/{dateutil => dateutil_py2}/NEWS | 0 lib/{dateutil => dateutil_py2}/README | 0 lib/{dateutil => dateutil_py2}/__init__.py | 0 lib/{dateutil => dateutil_py2}/easter.py | 0 lib/{dateutil => dateutil_py2}/parser.py | 0 .../relativedelta.py | 0 lib/{dateutil => dateutil_py2}/rrule.py | 0 lib/{dateutil => dateutil_py2}/tz.py | 0 lib/{dateutil => dateutil_py2}/tzwin.py | 0 .../zoneinfo/__init__.py | 0 .../zoneinfo/zoneinfo-2010g.tar.gz | Bin lib/dateutil_py3/LICENSE | 30 + lib/dateutil_py3/NEWS | 164 ++ lib/dateutil_py3/README | 1970 +++++++++++++++++ lib/dateutil_py3/__init__.py | 10 + lib/dateutil_py3/easter.py | 91 + lib/dateutil_py3/parser.py | 909 ++++++++ lib/dateutil_py3/relativedelta.py | 436 ++++ lib/dateutil_py3/rrule.py | 1112 ++++++++++ lib/dateutil_py3/six.py | 353 +++ lib/dateutil_py3/tz.py | 960 ++++++++ lib/dateutil_py3/tzwin.py | 179 ++ lib/dateutil_py3/zoneinfo/__init__.py | 90 + .../zoneinfo/zoneinfo--latest.tar.gz | Bin 0 -> 86784 bytes .../zoneinfo/zoneinfo-2011d.tar.gz | Bin 0 -> 197294 bytes lib/pytz/README.txt | 5 +- lib/pytz/__init__.py | 21 +- lib/pytz/tests/test_tzinfo.py | 101 +- lib/pytz/tzfile.py | 4 +- lib/pytz/tzinfo.py | 5 + lib/pytz/zoneinfo/Africa/Casablanca | Bin 586 -> 1362 bytes lib/pytz/zoneinfo/America/Atikokan | Bin 319 -> 319 bytes lib/pytz/zoneinfo/America/Bahia | Bin 994 -> 1777 bytes lib/pytz/zoneinfo/America/Blanc-Sablon | Bin 281 -> 281 bytes lib/pytz/zoneinfo/America/Coral_Harbour | Bin 319 -> 319 bytes lib/pytz/zoneinfo/America/Creston | Bin 0 -> 207 bytes lib/pytz/zoneinfo/America/Dawson_Creek | Bin 1033 -> 1033 bytes lib/pytz/zoneinfo/America/Edmonton | Bin 2388 -> 2388 bytes lib/pytz/zoneinfo/America/Glace_Bay | Bin 2192 -> 2192 bytes lib/pytz/zoneinfo/America/Goose_Bay | Bin 3193 -> 3193 bytes lib/pytz/zoneinfo/America/Halifax | Bin 3424 -> 3424 bytes lib/pytz/zoneinfo/America/Havana | Bin 2411 -> 2411 bytes lib/pytz/zoneinfo/America/Moncton | Bin 3137 -> 3137 bytes lib/pytz/zoneinfo/America/Montreal | Bin 3477 -> 3477 bytes lib/pytz/zoneinfo/America/Nipigon | Bin 2105 -> 2105 bytes lib/pytz/zoneinfo/America/Port-au-Prince | Bin 711 -> 739 bytes lib/pytz/zoneinfo/America/Rainy_River | Bin 2105 -> 2105 bytes lib/pytz/zoneinfo/America/Regina | Bin 980 -> 980 bytes lib/pytz/zoneinfo/America/Santiago | Bin 9227 -> 9245 bytes lib/pytz/zoneinfo/America/Sitka | Bin 2324 -> 2324 bytes lib/pytz/zoneinfo/America/St_Johns | Bin 3638 -> 3638 bytes lib/pytz/zoneinfo/America/Swift_Current | Bin 560 -> 560 bytes lib/pytz/zoneinfo/America/Toronto | Bin 3477 -> 3477 bytes lib/pytz/zoneinfo/America/Vancouver | Bin 2875 -> 2875 bytes lib/pytz/zoneinfo/America/Winnipeg | Bin 2865 -> 2865 bytes lib/pytz/zoneinfo/Antarctica/Casey | Bin 227 -> 255 bytes lib/pytz/zoneinfo/Antarctica/Davis | Bin 248 -> 276 bytes lib/pytz/zoneinfo/Antarctica/Palmer | Bin 8546 -> 8780 bytes lib/pytz/zoneinfo/Asia/Damascus | Bin 2306 -> 2306 bytes lib/pytz/zoneinfo/Asia/Gaza | Bin 1534 -> 1562 bytes lib/pytz/zoneinfo/Asia/Hebron | Bin 1562 -> 1590 bytes lib/pytz/zoneinfo/Asia/Yerevan | Bin 2012 -> 1263 bytes lib/pytz/zoneinfo/Atlantic/Stanley | Bin 1965 -> 1220 bytes lib/pytz/zoneinfo/Canada/Atlantic | Bin 3424 -> 3424 bytes lib/pytz/zoneinfo/Canada/Central | Bin 2865 -> 2865 bytes lib/pytz/zoneinfo/Canada/East-Saskatchewan | Bin 980 -> 980 bytes lib/pytz/zoneinfo/Canada/Eastern | Bin 3477 -> 3477 bytes lib/pytz/zoneinfo/Canada/Mountain | Bin 2388 -> 2388 bytes lib/pytz/zoneinfo/Canada/Newfoundland | Bin 3638 -> 3638 bytes lib/pytz/zoneinfo/Canada/Pacific | Bin 2875 -> 2875 bytes lib/pytz/zoneinfo/Canada/Saskatchewan | Bin 980 -> 980 bytes lib/pytz/zoneinfo/Chile/Continental | Bin 9227 -> 9245 bytes lib/pytz/zoneinfo/Chile/EasterIsland | Bin 8989 -> 9007 bytes lib/pytz/zoneinfo/Cuba | Bin 2411 -> 2411 bytes lib/pytz/zoneinfo/Europe/Kiev | Bin 1316 -> 2057 bytes lib/pytz/zoneinfo/Europe/Simferopol | Bin 1372 -> 2113 bytes lib/pytz/zoneinfo/Europe/Uzhgorod | Bin 1336 -> 2077 bytes lib/pytz/zoneinfo/Europe/Zaporozhye | Bin 1344 -> 2085 bytes lib/pytz/zoneinfo/Pacific/Easter | Bin 8989 -> 9007 bytes lib/pytz/zoneinfo/Pacific/Fakaofo | Bin 140 -> 171 bytes lib/pytz/zoneinfo/Pacific/Fiji | Bin 296 -> 324 bytes lib/pytz/zoneinfo/iso3166.tab | 1 - lib/pytz/zoneinfo/zone.tab | 4 +- setup.py | 91 +- setupext.py | 22 +- 87 files changed, 6494 insertions(+), 74 deletions(-) rename lib/{dateutil => dateutil_py2}/LICENSE (100%) rename lib/{dateutil => dateutil_py2}/NEWS (100%) rename lib/{dateutil => dateutil_py2}/README (100%) rename lib/{dateutil => dateutil_py2}/__init__.py (100%) rename lib/{dateutil => dateutil_py2}/easter.py (100%) rename lib/{dateutil => dateutil_py2}/parser.py (100%) rename lib/{dateutil => dateutil_py2}/relativedelta.py (100%) rename lib/{dateutil => dateutil_py2}/rrule.py (100%) rename lib/{dateutil => dateutil_py2}/tz.py (100%) rename lib/{dateutil => dateutil_py2}/tzwin.py (100%) rename lib/{dateutil => dateutil_py2}/zoneinfo/__init__.py (100%) rename lib/{dateutil => dateutil_py2}/zoneinfo/zoneinfo-2010g.tar.gz (100%) create mode 100644 lib/dateutil_py3/LICENSE create mode 100644 lib/dateutil_py3/NEWS create mode 100644 lib/dateutil_py3/README create mode 100644 lib/dateutil_py3/__init__.py create mode 100644 lib/dateutil_py3/easter.py create mode 100644 lib/dateutil_py3/parser.py create mode 100644 lib/dateutil_py3/relativedelta.py create mode 100644 lib/dateutil_py3/rrule.py create mode 100644 lib/dateutil_py3/six.py create mode 100644 lib/dateutil_py3/tz.py create mode 100644 lib/dateutil_py3/tzwin.py create mode 100644 lib/dateutil_py3/zoneinfo/__init__.py create mode 100644 lib/dateutil_py3/zoneinfo/zoneinfo--latest.tar.gz create mode 100644 lib/dateutil_py3/zoneinfo/zoneinfo-2011d.tar.gz create mode 100644 lib/pytz/zoneinfo/America/Creston diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index addb2524cae4..759bf5029bac 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -127,6 +127,16 @@ local intensity of the vector field. .. plot:: mpl_examples/pylab_examples/streamplot_demo.py +Updated shipped dependencies +---------------------------- + +The following dependencies that ship with matplotlib and are +optionally installed alongside it have been updated: + + - `pytz ` 2012d + + - `dateutil ` 1.5 on Python 2.x, + and 2.1 on Python 3.x .. _whats-new-1-1: diff --git a/lib/dateutil/LICENSE b/lib/dateutil_py2/LICENSE similarity index 100% rename from lib/dateutil/LICENSE rename to lib/dateutil_py2/LICENSE diff --git a/lib/dateutil/NEWS b/lib/dateutil_py2/NEWS similarity index 100% rename from lib/dateutil/NEWS rename to lib/dateutil_py2/NEWS diff --git a/lib/dateutil/README b/lib/dateutil_py2/README similarity index 100% rename from lib/dateutil/README rename to lib/dateutil_py2/README diff --git a/lib/dateutil/__init__.py b/lib/dateutil_py2/__init__.py similarity index 100% rename from lib/dateutil/__init__.py rename to lib/dateutil_py2/__init__.py diff --git a/lib/dateutil/easter.py b/lib/dateutil_py2/easter.py similarity index 100% rename from lib/dateutil/easter.py rename to lib/dateutil_py2/easter.py diff --git a/lib/dateutil/parser.py b/lib/dateutil_py2/parser.py similarity index 100% rename from lib/dateutil/parser.py rename to lib/dateutil_py2/parser.py diff --git a/lib/dateutil/relativedelta.py b/lib/dateutil_py2/relativedelta.py similarity index 100% rename from lib/dateutil/relativedelta.py rename to lib/dateutil_py2/relativedelta.py diff --git a/lib/dateutil/rrule.py b/lib/dateutil_py2/rrule.py similarity index 100% rename from lib/dateutil/rrule.py rename to lib/dateutil_py2/rrule.py diff --git a/lib/dateutil/tz.py b/lib/dateutil_py2/tz.py similarity index 100% rename from lib/dateutil/tz.py rename to lib/dateutil_py2/tz.py diff --git a/lib/dateutil/tzwin.py b/lib/dateutil_py2/tzwin.py similarity index 100% rename from lib/dateutil/tzwin.py rename to lib/dateutil_py2/tzwin.py diff --git a/lib/dateutil/zoneinfo/__init__.py b/lib/dateutil_py2/zoneinfo/__init__.py similarity index 100% rename from lib/dateutil/zoneinfo/__init__.py rename to lib/dateutil_py2/zoneinfo/__init__.py diff --git a/lib/dateutil/zoneinfo/zoneinfo-2010g.tar.gz b/lib/dateutil_py2/zoneinfo/zoneinfo-2010g.tar.gz similarity index 100% rename from lib/dateutil/zoneinfo/zoneinfo-2010g.tar.gz rename to lib/dateutil_py2/zoneinfo/zoneinfo-2010g.tar.gz diff --git a/lib/dateutil_py3/LICENSE b/lib/dateutil_py3/LICENSE new file mode 100644 index 000000000000..5834335bd9da --- /dev/null +++ b/lib/dateutil_py3/LICENSE @@ -0,0 +1,30 @@ +dateutil - Extensions to the standard Python datetime module. + +Copyright (c) 2003-2011 - Gustavo Niemeyer +Copyright (c) 2012 - Tomi Pieviläinen + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/dateutil_py3/NEWS b/lib/dateutil_py3/NEWS new file mode 100644 index 000000000000..3a0a8ed12aae --- /dev/null +++ b/lib/dateutil_py3/NEWS @@ -0,0 +1,164 @@ +Version 2.1 +----------- + +- New maintainer + +- Dateutil now works on Python 2.6, 2.7 and 3.2 from same codebase (with six) + +- #704047: Ismael Carnales' patch for a new time format + +- Small bug fixes, thanks for reporters! + + +Version 2.0 +----------- + +- Ported to Python 3, by Brian Jones. If you need dateutil for Python 2.X, + please continue using the 1.X series. + +- There's no such thing as a "PSF License". This source code is now + made available under the Simplified BSD license. See LICENSE for + details. + +Version 1.5 +----------- + +- As reported by Mathieu Bridon, rrules were matching the bysecond rules + incorrectly against byminute in some circumstances when the SECONDLY + frequency was in use, due to a copy & paste bug. The problem has been + unittested and corrected. + +- Adam Ryan reported a problem in the relativedelta implementation which + affected the yearday parameter in the month of January specifically. + This has been unittested and fixed. + +- Updated timezone information. + + +Version 1.4.1 +------------- + +- Updated timezone information. + + +Version 1.4 +----------- + +- Fixed another parser precision problem on conversion of decimal seconds + to microseconds, as reported by Erik Brown. Now these issues are gone + for real since it's not using floating point arithmetic anymore. + +- Fixed case where tzrange.utcoffset and tzrange.dst() might fail due + to a date being used where a datetime was expected (reported and fixed + by Lennart Regebro). + +- Prevent tzstr from introducing daylight timings in strings that didn't + specify them (reported by Lennart Regebro). + +- Calls like gettz("GMT+3") and gettz("UTC-2") will now return the + expected values, instead of the TZ variable behavior. + +- Fixed DST signal handling in zoneinfo files. Reported by + Nicholas F. Fabry and John-Mark Gurney. + + +Version 1.3 +----------- + +- Fixed precision problem on conversion of decimal seconds to + microseconds, as reported by Skip Montanaro. + +- Fixed bug in constructor of parser, and converted parser classes to + new-style classes. Original report and patch by Michael Elsdörfer. + +- Initialize tzid and comps in tz.py, to prevent the code from ever + raising a NameError (even with broken files). Johan Dahlin suggested + the fix after a pyflakes run. + +- Version is now published in dateutil.__version__, as requested + by Darren Dale. + +- All code is compatible with new-style division. + + +Version 1.2 +----------- + +- Now tzfile will round timezones to full-minutes if necessary, + since Python's datetime doesn't support sub-minute offsets. + Thanks to Ilpo Nyyssönen for reporting the issue. + +- Removed bare string exceptions, as reported and fixed by + Wilfredo Sánchez Vega. + +- Fix bug in leap count parsing (reported and fixed by Eugene Oden). + + +Version 1.1 +----------- + +- Fixed rrule byyearday handling. Abramo Bagnara pointed out that + RFC2445 allows negative numbers. + +- Fixed --prefix handling in setup.py (by Sidnei da Silva). + +- Now tz.gettz() returns a tzlocal instance when not given any + arguments and no other timezone information is found. + +- Updating timezone information to version 2005q. + + +Version 1.0 +----------- + +- Fixed parsing of XXhXXm formatted time after day/month/year + has been parsed. + +- Added patch by Jeffrey Harris optimizing rrule.__contains__. + + +Version 0.9 +----------- + +- Fixed pickling of timezone types, as reported by + Andreas Köhler. + +- Implemented internal timezone information with binary + timezone files [1]. datautil.tz.gettz() function will now + try to use the system timezone files, and fallback to + the internal versions. It's also possible to ask for + the internal versions directly by using + dateutil.zoneinfo.gettz(). + +- New tzwin timezone type, allowing access to Windows + internal timezones (contributed by Jeffrey Harris). + +- Fixed parsing of unicode date strings. + +- Accept parserinfo instances as the parser constructor + parameter, besides parserinfo (sub)classes. + +- Changed weekday to spell the not-set n value as None + instead of 0. + +- Fixed other reported bugs. + +[1] http://www.twinsun.com/tz/tz-link.htm + + +Version 0.5 +----------- + +- Removed FREQ_ prefix from rrule frequency constants + WARNING: this breaks compatibility with previous versions. + +- Fixed rrule.between() for cases where "after" is achieved + before even starting, as reported by Andreas Köhler. + +- Fixed two digit zero-year parsing (such as 31-Dec-00), as + reported by Jim Abramson, and included test case for this. + +- Sort exdate and rdate before iterating over them, so that + it's not necessary to sort them before adding to the rruleset, + as reported by Nicholas Piper. + diff --git a/lib/dateutil_py3/README b/lib/dateutil_py3/README new file mode 100644 index 000000000000..9453699e7d54 --- /dev/null +++ b/lib/dateutil_py3/README @@ -0,0 +1,1970 @@ +## 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 . + +== 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") + + +>>> rrulestr(""" +... DTSTART:19970902T090000 +... RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 +... """) + + +>>> rrulestr("FREQ=DAILY;INTERVAL=10;COUNT=5", forceset=True) + +}}} + +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 +... """) + +}}} + +=== 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 + + +>>> datetime.now(est) +datetime.datetime(2003, 10, 6, 19, 44, 18, 667987, + tzinfo=) + +>>> 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 diff --git a/lib/dateutil_py3/__init__.py b/lib/dateutil_py3/__init__.py new file mode 100644 index 000000000000..0f91a31f6eb2 --- /dev/null +++ b/lib/dateutil_py3/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +""" +Copyright (c) 2003-2010 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__author__ = "Tomi Pieviläinen " +__license__ = "Simplified BSD" +__version__ = "2.1" diff --git a/lib/dateutil_py3/easter.py b/lib/dateutil_py3/easter.py new file mode 100644 index 000000000000..d8a38844f9e3 --- /dev/null +++ b/lib/dateutil_py3/easter.py @@ -0,0 +1,91 @@ +""" +Copyright (c) 2003-2007 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__license__ = "Simplified BSD" + +import datetime + +__all__ = ["easter", "EASTER_JULIAN", "EASTER_ORTHODOX", "EASTER_WESTERN"] + +EASTER_JULIAN = 1 +EASTER_ORTHODOX = 2 +EASTER_WESTERN = 3 + +def easter(year, method=EASTER_WESTERN): + """ + This method was ported from the work done by GM Arts, + on top of the algorithm by 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 + 2 - Original method, with date converted to Gregorian + calendar, valid in years 1583 to 4099 + 3 - 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. + + More about the algorithm may be found at: + + http://users.chariot.net.au/~gmarts/eastalg.htm + + and + + http://www.tondering.dk/claus/calendar.html + + """ + + if not (1 <= method <= 3): + raise ValueError("invalid method") + + # g - Golden year - 1 + # c - Century + # h - (23 - Epact) mod 30 + # i - Number of days from March 21 to Paschal Full Moon + # j - Weekday for PFM (0=Sunday, etc) + # p - Number of days from March 21 to Sunday on or before PFM + # (-6 to 28 methods 1 & 3, to 56 for method 2) + # e - Extra days to add for method 2 (converting Julian + # date to Gregorian date) + + y = year + g = y % 19 + e = 0 + if method < 3: + # Old method + i = (19*g+15)%30 + j = (y+y//4+i)%7 + if method == 2: + # Extra dates to convert Julian to Gregorian date + e = 10 + if y > 1600: + e = e+y//100-16-(y//100-16)//4 + else: + # New method + c = y//100 + h = (c-c//4-(8*c+13)//25+19*g+15)%30 + i = h-(h//28)*(1-(h//28)*(29//(h+1))*((21-g)//11)) + j = (y+y//4+i+2-c+c//4)%7 + + # p can be from -6 to 56 corresponding to dates 22 March to 23 May + # (later dates apply to method 2, although 23 May never actually occurs) + p = i-j+e + d = 1+(p+27+(p+6)//40)%31 + m = 3+(p+26)//30 + return datetime.date(int(y), int(m), int(d)) + diff --git a/lib/dateutil_py3/parser.py b/lib/dateutil_py3/parser.py new file mode 100644 index 000000000000..a2604a35ba06 --- /dev/null +++ b/lib/dateutil_py3/parser.py @@ -0,0 +1,909 @@ +# -*- coding:iso-8859-1 -*- +""" +Copyright (c) 2003-2007 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +from __future__ import unicode_literals +__license__ = "Simplified BSD" + + +import datetime +import string +import time +import sys +import os +import collections + +try: + from io import StringIO +except ImportError: + from io import StringIO + +from six import text_type, binary_type, integer_types + +from . import relativedelta +from . import tz + + +__all__ = ["parse", "parserinfo"] + + +# Some pointers: +# +# http://www.cl.cam.ac.uk/~mgk25/iso-time.html +# http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html +# http://www.w3.org/TR/NOTE-datetime +# http://ringmaster.arc.nasa.gov/tools/time_formats.html +# http://search.cpan.org/author/MUIR/Time-modules-2003.0211/lib/Time/ParseDate.pm +# http://stein.cshl.org/jade/distrib/docs/java.text.SimpleDateFormat.html + + +class _timelex(object): + + def __init__(self, instream): + if isinstance(instream, text_type): + instream = StringIO(instream) + self.instream = instream + self.wordchars = ('abcdfeghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_' + 'ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ' + 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ') + self.numchars = '0123456789' + self.whitespace = ' \t\r\n' + self.charstack = [] + self.tokenstack = [] + self.eof = False + + def get_token(self): + if self.tokenstack: + return self.tokenstack.pop(0) + seenletters = False + token = None + state = None + wordchars = self.wordchars + numchars = self.numchars + whitespace = self.whitespace + while not self.eof: + if self.charstack: + nextchar = self.charstack.pop(0) + else: + nextchar = self.instream.read(1) + while nextchar == '\x00': + nextchar = self.instream.read(1) + if not nextchar: + self.eof = True + break + elif not state: + token = nextchar + if nextchar in wordchars: + state = 'a' + elif nextchar in numchars: + state = '0' + elif nextchar in whitespace: + token = ' ' + break # emit token + else: + break # emit token + elif state == 'a': + seenletters = True + if nextchar in wordchars: + token += nextchar + elif nextchar == '.': + token += nextchar + state = 'a.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == '0': + if nextchar in numchars: + token += nextchar + elif nextchar == '.': + token += nextchar + state = '0.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == 'a.': + seenletters = True + if nextchar == '.' or nextchar in wordchars: + token += nextchar + elif nextchar in numchars and token[-1] == '.': + token += nextchar + state = '0.' + else: + self.charstack.append(nextchar) + break # emit token + elif state == '0.': + if nextchar == '.' or nextchar in numchars: + token += nextchar + elif nextchar in wordchars and token[-1] == '.': + token += nextchar + state = 'a.' + else: + self.charstack.append(nextchar) + break # emit token + if (state in ('a.', '0.') and + (seenletters or token.count('.') > 1 or token[-1] == '.')): + l = token.split('.') + token = l[0] + for tok in l[1:]: + self.tokenstack.append('.') + if tok: + self.tokenstack.append(tok) + return token + + def __iter__(self): + return self + + def __next__(self): + token = self.get_token() + if token is None: + raise StopIteration + return token + + def next(self): + return self.__next__() # Python 2.x support + + def split(cls, s): + return list(cls(s)) + split = classmethod(split) + + +class _resultbase(object): + + def __init__(self): + for attr in self.__slots__: + setattr(self, attr, None) + + def _repr(self, classname): + l = [] + for attr in self.__slots__: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, repr(value))) + return "%s(%s)" % (classname, ", ".join(l)) + + def __repr__(self): + return self._repr(self.__class__.__name__) + + +class parserinfo(object): + + # m from a.m/p.m, t from ISO T separator + JUMP = [" ", ".", ",", ";", "-", "/", "'", + "at", "on", "and", "ad", "m", "t", "of", + "st", "nd", "rd", "th"] + + WEEKDAYS = [("Mon", "Monday"), + ("Tue", "Tuesday"), + ("Wed", "Wednesday"), + ("Thu", "Thursday"), + ("Fri", "Friday"), + ("Sat", "Saturday"), + ("Sun", "Sunday")] + MONTHS = [("Jan", "January"), + ("Feb", "February"), + ("Mar", "March"), + ("Apr", "April"), + ("May", "May"), + ("Jun", "June"), + ("Jul", "July"), + ("Aug", "August"), + ("Sep", "Sept", "September"), + ("Oct", "October"), + ("Nov", "November"), + ("Dec", "December")] + HMS = [("h", "hour", "hours"), + ("m", "minute", "minutes"), + ("s", "second", "seconds")] + AMPM = [("am", "a"), + ("pm", "p")] + UTCZONE = ["UTC", "GMT", "Z"] + PERTAIN = ["of"] + TZOFFSET = {} + + def __init__(self, dayfirst=False, yearfirst=False): + self._jump = self._convert(self.JUMP) + self._weekdays = self._convert(self.WEEKDAYS) + self._months = self._convert(self.MONTHS) + self._hms = self._convert(self.HMS) + self._ampm = self._convert(self.AMPM) + self._utczone = self._convert(self.UTCZONE) + self._pertain = self._convert(self.PERTAIN) + + self.dayfirst = dayfirst + self.yearfirst = yearfirst + + self._year = time.localtime().tm_year + self._century = self._year//100*100 + + def _convert(self, lst): + dct = {} + for i in range(len(lst)): + v = lst[i] + if isinstance(v, tuple): + for v in v: + dct[v.lower()] = i + else: + dct[v.lower()] = i + return dct + + def jump(self, name): + return name.lower() in self._jump + + def weekday(self, name): + if len(name) >= 3: + try: + return self._weekdays[name.lower()] + except KeyError: + pass + return None + + def month(self, name): + if len(name) >= 3: + try: + return self._months[name.lower()]+1 + except KeyError: + pass + return None + + def hms(self, name): + try: + return self._hms[name.lower()] + except KeyError: + return None + + def ampm(self, name): + try: + return self._ampm[name.lower()] + except KeyError: + return None + + def pertain(self, name): + return name.lower() in self._pertain + + def utczone(self, name): + return name.lower() in self._utczone + + def tzoffset(self, name): + if name in self._utczone: + return 0 + return self.TZOFFSET.get(name) + + def convertyear(self, year): + if year < 100: + year += self._century + if abs(year-self._year) >= 50: + if year < self._year: + year += 100 + else: + year -= 100 + return year + + def validate(self, res): + # move to info + if res.year is not None: + res.year = self.convertyear(res.year) + if res.tzoffset == 0 and not res.tzname or res.tzname == 'Z': + res.tzname = "UTC" + res.tzoffset = 0 + elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname): + res.tzoffset = 0 + return True + + +class parser(object): + + def __init__(self, info=None): + self.info = info or parserinfo() + + def parse(self, timestr, default=None, + ignoretz=False, tzinfos=None, + **kwargs): + if not default: + default = datetime.datetime.now().replace(hour=0, minute=0, + second=0, microsecond=0) + res = self._parse(timestr, **kwargs) + if res is None: + raise ValueError("unknown string format") + repl = {} + for attr in ["year", "month", "day", "hour", + "minute", "second", "microsecond"]: + value = getattr(res, attr) + if value is not None: + repl[attr] = value + ret = default.replace(**repl) + if res.weekday is not None and not res.day: + ret = ret+relativedelta.relativedelta(weekday=res.weekday) + if not ignoretz: + if isinstance(tzinfos, collections.Callable) or tzinfos and res.tzname in tzinfos: + if isinstance(tzinfos, collections.Callable): + tzdata = tzinfos(res.tzname, res.tzoffset) + else: + tzdata = tzinfos.get(res.tzname) + if isinstance(tzdata, datetime.tzinfo): + tzinfo = tzdata + elif isinstance(tzdata, text_type): + tzinfo = tz.tzstr(tzdata) + elif isinstance(tzdata, integer_types): + tzinfo = tz.tzoffset(res.tzname, tzdata) + else: + raise ValueError("offset must be tzinfo subclass, " \ + "tz string, or int offset") + ret = ret.replace(tzinfo=tzinfo) + elif res.tzname and res.tzname in time.tzname: + ret = ret.replace(tzinfo=tz.tzlocal()) + elif res.tzoffset == 0: + ret = ret.replace(tzinfo=tz.tzutc()) + elif res.tzoffset: + ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) + return ret + + class _result(_resultbase): + __slots__ = ["year", "month", "day", "weekday", + "hour", "minute", "second", "microsecond", + "tzname", "tzoffset"] + + def _parse(self, timestr, dayfirst=None, yearfirst=None, fuzzy=False): + info = self.info + if dayfirst is None: + dayfirst = info.dayfirst + if yearfirst is None: + yearfirst = info.yearfirst + res = self._result() + l = _timelex.split(timestr) + try: + + # year/month/day list + ymd = [] + + # Index of the month string in ymd + mstridx = -1 + + len_l = len(l) + i = 0 + while i < len_l: + + # Check if it's a number + try: + value_repr = l[i] + value = float(value_repr) + except ValueError: + value = None + + if value is not None: + # Token is a number + len_li = len(l[i]) + i += 1 + if (len(ymd) == 3 and len_li in (2, 4) + and (i >= len_l or (l[i] != ':' and + info.hms(l[i]) is None))): + # 19990101T23[59] + s = l[i-1] + res.hour = int(s[:2]) + if len_li == 4: + res.minute = int(s[2:]) + elif len_li == 6 or (len_li > 6 and l[i-1].find('.') == 6): + # YYMMDD or HHMMSS[.ss] + s = l[i-1] + if not ymd and l[i-1].find('.') == -1: + ymd.append(info.convertyear(int(s[:2]))) + ymd.append(int(s[2:4])) + ymd.append(int(s[4:])) + else: + # 19990101T235959[.59] + res.hour = int(s[:2]) + res.minute = int(s[2:4]) + res.second, res.microsecond = _parsems(s[4:]) + elif len_li == 8: + # YYYYMMDD + s = l[i-1] + ymd.append(int(s[:4])) + ymd.append(int(s[4:6])) + ymd.append(int(s[6:])) + elif len_li in (12, 14): + # YYYYMMDDhhmm[ss] + s = l[i-1] + ymd.append(int(s[:4])) + ymd.append(int(s[4:6])) + ymd.append(int(s[6:8])) + res.hour = int(s[8:10]) + res.minute = int(s[10:12]) + if len_li == 14: + res.second = int(s[12:]) + elif ((i < len_l and info.hms(l[i]) is not None) or + (i+1 < len_l and l[i] == ' ' and + info.hms(l[i+1]) is not None)): + # HH[ ]h or MM[ ]m or SS[.ss][ ]s + if l[i] == ' ': + i += 1 + idx = info.hms(l[i]) + while True: + if idx == 0: + res.hour = int(value) + if value%1: + res.minute = int(60*(value%1)) + elif idx == 1: + res.minute = int(value) + if value%1: + res.second = int(60*(value%1)) + elif idx == 2: + res.second, res.microsecond = \ + _parsems(value_repr) + i += 1 + if i >= len_l or idx == 2: + break + # 12h00 + try: + value_repr = l[i] + value = float(value_repr) + except ValueError: + break + else: + i += 1 + idx += 1 + if i < len_l: + newidx = info.hms(l[i]) + if newidx is not None: + idx = newidx + elif i == len_l and l[i-2] == ' ' and info.hms(l[i-3]) is not None: + # X h MM or X m SS + idx = info.hms(l[i-3]) + 1 + if idx == 1: + res.minute = int(value) + if value%1: + res.second = int(60*(value%1)) + elif idx == 2: + res.second, res.microsecond = \ + _parsems(value_repr) + i += 1 + elif i+1 < len_l and l[i] == ':': + # HH:MM[:SS[.ss]] + res.hour = int(value) + i += 1 + value = float(l[i]) + res.minute = int(value) + if value%1: + res.second = int(60*(value%1)) + i += 1 + if i < len_l and l[i] == ':': + res.second, res.microsecond = _parsems(l[i+1]) + i += 2 + elif i < len_l and l[i] in ('-', '/', '.'): + sep = l[i] + ymd.append(int(value)) + i += 1 + if i < len_l and not info.jump(l[i]): + try: + # 01-01[-01] + ymd.append(int(l[i])) + except ValueError: + # 01-Jan[-01] + value = info.month(l[i]) + if value is not None: + ymd.append(value) + assert mstridx == -1 + mstridx = len(ymd)-1 + else: + return None + i += 1 + if i < len_l and l[i] == sep: + # We have three members + i += 1 + value = info.month(l[i]) + if value is not None: + ymd.append(value) + mstridx = len(ymd)-1 + assert mstridx == -1 + else: + ymd.append(int(l[i])) + i += 1 + elif i >= len_l or info.jump(l[i]): + if i+1 < len_l and info.ampm(l[i+1]) is not None: + # 12 am + res.hour = int(value) + if res.hour < 12 and info.ampm(l[i+1]) == 1: + res.hour += 12 + elif res.hour == 12 and info.ampm(l[i+1]) == 0: + res.hour = 0 + i += 1 + else: + # Year, month or day + ymd.append(int(value)) + i += 1 + elif info.ampm(l[i]) is not None: + # 12am + res.hour = int(value) + if res.hour < 12 and info.ampm(l[i]) == 1: + res.hour += 12 + elif res.hour == 12 and info.ampm(l[i]) == 0: + res.hour = 0 + i += 1 + elif not fuzzy: + return None + else: + i += 1 + continue + + # Check weekday + value = info.weekday(l[i]) + if value is not None: + res.weekday = value + i += 1 + continue + + # Check month name + value = info.month(l[i]) + if value is not None: + ymd.append(value) + assert mstridx == -1 + mstridx = len(ymd)-1 + i += 1 + if i < len_l: + if l[i] in ('-', '/'): + # Jan-01[-99] + sep = l[i] + i += 1 + ymd.append(int(l[i])) + i += 1 + if i < len_l and l[i] == sep: + # Jan-01-99 + i += 1 + ymd.append(int(l[i])) + i += 1 + elif (i+3 < len_l and l[i] == l[i+2] == ' ' + and info.pertain(l[i+1])): + # Jan of 01 + # In this case, 01 is clearly year + try: + value = int(l[i+3]) + except ValueError: + # Wrong guess + pass + else: + # Convert it here to become unambiguous + ymd.append(info.convertyear(value)) + i += 4 + continue + + # Check am/pm + value = info.ampm(l[i]) + if value is not None: + if value == 1 and res.hour < 12: + res.hour += 12 + elif value == 0 and res.hour == 12: + res.hour = 0 + i += 1 + continue + + # Check for a timezone name + if (res.hour is not None and len(l[i]) <= 5 and + res.tzname is None and res.tzoffset is None and + not [x for x in l[i] if x not in string.ascii_uppercase]): + res.tzname = l[i] + res.tzoffset = info.tzoffset(res.tzname) + i += 1 + + # Check for something like GMT+3, or BRST+3. Notice + # that it doesn't mean "I am 3 hours after GMT", but + # "my time +3 is GMT". If found, we reverse the + # logic so that timezone parsing code will get it + # right. + if i < len_l and l[i] in ('+', '-'): + l[i] = ('+', '-')[l[i] == '+'] + res.tzoffset = None + if info.utczone(res.tzname): + # With something like GMT+3, the timezone + # is *not* GMT. + res.tzname = None + + continue + + # Check for a numbered timezone + if res.hour is not None and l[i] in ('+', '-'): + signal = (-1, 1)[l[i] == '+'] + i += 1 + len_li = len(l[i]) + if len_li == 4: + # -0300 + res.tzoffset = int(l[i][:2])*3600+int(l[i][2:])*60 + elif i+1 < len_l and l[i+1] == ':': + # -03:00 + res.tzoffset = int(l[i])*3600+int(l[i+2])*60 + i += 2 + elif len_li <= 2: + # -[0]3 + res.tzoffset = int(l[i][:2])*3600 + else: + return None + i += 1 + res.tzoffset *= signal + + # Look for a timezone name between parenthesis + if (i+3 < len_l and + info.jump(l[i]) and l[i+1] == '(' and l[i+3] == ')' and + 3 <= len(l[i+2]) <= 5 and + not [x for x in l[i+2] + if x not in string.ascii_uppercase]): + # -0300 (BRST) + res.tzname = l[i+2] + i += 4 + continue + + # Check jumps + if not (info.jump(l[i]) or fuzzy): + return None + + i += 1 + + # Process year/month/day + len_ymd = len(ymd) + if len_ymd > 3: + # More than three members!? + return None + elif len_ymd == 1 or (mstridx != -1 and len_ymd == 2): + # One member, or two members with a month string + if mstridx != -1: + res.month = ymd[mstridx] + del ymd[mstridx] + if len_ymd > 1 or mstridx == -1: + if ymd[0] > 31: + res.year = ymd[0] + else: + res.day = ymd[0] + elif len_ymd == 2: + # Two members with numbers + if ymd[0] > 31: + # 99-01 + res.year, res.month = ymd + elif ymd[1] > 31: + # 01-99 + res.month, res.year = ymd + elif dayfirst and ymd[1] <= 12: + # 13-01 + res.day, res.month = ymd + else: + # 01-13 + res.month, res.day = ymd + if len_ymd == 3: + # Three members + if mstridx == 0: + res.month, res.day, res.year = ymd + elif mstridx == 1: + if ymd[0] > 31 or (yearfirst and ymd[2] <= 31): + # 99-Jan-01 + res.year, res.month, res.day = ymd + else: + # 01-Jan-01 + # Give precendence to day-first, since + # two-digit years is usually hand-written. + res.day, res.month, res.year = ymd + elif mstridx == 2: + # WTF!? + if ymd[1] > 31: + # 01-99-Jan + res.day, res.year, res.month = ymd + else: + # 99-01-Jan + res.year, res.day, res.month = ymd + else: + if ymd[0] > 31 or \ + (yearfirst and ymd[1] <= 12 and ymd[2] <= 31): + # 99-01-01 + res.year, res.month, res.day = ymd + elif ymd[0] > 12 or (dayfirst and ymd[1] <= 12): + # 13-01-01 + res.day, res.month, res.year = ymd + else: + # 01-13-01 + res.month, res.day, res.year = ymd + + except (IndexError, ValueError, AssertionError): + return None + + if not info.validate(res): + return None + return res + +DEFAULTPARSER = parser() +def parse(timestr, parserinfo=None, **kwargs): + # Python 2.x support: datetimes return their string presentation as + # bytes in 2.x and unicode in 3.x, so it's reasonable to expect that + # the parser will get both kinds. Internally we use unicode only. + if isinstance(timestr, binary_type): + timestr = timestr.decode() + if parserinfo: + return parser(parserinfo).parse(timestr, **kwargs) + else: + return DEFAULTPARSER.parse(timestr, **kwargs) + + +class _tzparser(object): + + class _result(_resultbase): + + __slots__ = ["stdabbr", "stdoffset", "dstabbr", "dstoffset", + "start", "end"] + + class _attr(_resultbase): + __slots__ = ["month", "week", "weekday", + "yday", "jyday", "day", "time"] + + def __repr__(self): + return self._repr("") + + def __init__(self): + _resultbase.__init__(self) + self.start = self._attr() + self.end = self._attr() + + def parse(self, tzstr): + res = self._result() + l = _timelex.split(tzstr) + try: + + len_l = len(l) + + i = 0 + while i < len_l: + # BRST+3[BRDT[+2]] + j = i + while j < len_l and not [x for x in l[j] + if x in "0123456789:,-+"]: + j += 1 + if j != i: + if not res.stdabbr: + offattr = "stdoffset" + res.stdabbr = "".join(l[i:j]) + else: + offattr = "dstoffset" + res.dstabbr = "".join(l[i:j]) + i = j + if (i < len_l and + (l[i] in ('+', '-') or l[i][0] in "0123456789")): + if l[i] in ('+', '-'): + # Yes, that's right. See the TZ variable + # documentation. + signal = (1, -1)[l[i] == '+'] + i += 1 + else: + signal = -1 + len_li = len(l[i]) + if len_li == 4: + # -0300 + setattr(res, offattr, + (int(l[i][:2])*3600+int(l[i][2:])*60)*signal) + elif i+1 < len_l and l[i+1] == ':': + # -03:00 + setattr(res, offattr, + (int(l[i])*3600+int(l[i+2])*60)*signal) + i += 2 + elif len_li <= 2: + # -[0]3 + setattr(res, offattr, + int(l[i][:2])*3600*signal) + else: + return None + i += 1 + if res.dstabbr: + break + else: + break + + if i < len_l: + for j in range(i, len_l): + if l[j] == ';': l[j] = ',' + + assert l[i] == ',' + + i += 1 + + if i >= len_l: + pass + elif (8 <= l.count(',') <= 9 and + not [y for x in l[i:] if x != ',' + for y in x if y not in "0123456789"]): + # GMT0BST,3,0,30,3600,10,0,26,7200[,3600] + for x in (res.start, res.end): + x.month = int(l[i]) + i += 2 + if l[i] == '-': + value = int(l[i+1])*-1 + i += 1 + else: + value = int(l[i]) + i += 2 + if value: + x.week = value + x.weekday = (int(l[i])-1)%7 + else: + x.day = int(l[i]) + i += 2 + x.time = int(l[i]) + i += 2 + if i < len_l: + if l[i] in ('-', '+'): + signal = (-1, 1)[l[i] == "+"] + i += 1 + else: + signal = 1 + res.dstoffset = (res.stdoffset+int(l[i]))*signal + elif (l.count(',') == 2 and l[i:].count('/') <= 2 and + not [y for x in l[i:] if x not in (',', '/', 'J', 'M', + '.', '-', ':') + for y in x if y not in "0123456789"]): + for x in (res.start, res.end): + if l[i] == 'J': + # non-leap year day (1 based) + i += 1 + x.jyday = int(l[i]) + elif l[i] == 'M': + # month[-.]week[-.]weekday + i += 1 + x.month = int(l[i]) + i += 1 + assert l[i] in ('-', '.') + i += 1 + x.week = int(l[i]) + if x.week == 5: + x.week = -1 + i += 1 + assert l[i] in ('-', '.') + i += 1 + x.weekday = (int(l[i])-1)%7 + else: + # year day (zero based) + x.yday = int(l[i])+1 + + i += 1 + + if i < len_l and l[i] == '/': + i += 1 + # start time + len_li = len(l[i]) + if len_li == 4: + # -0300 + x.time = (int(l[i][:2])*3600+int(l[i][2:])*60) + elif i+1 < len_l and l[i+1] == ':': + # -03:00 + x.time = int(l[i])*3600+int(l[i+2])*60 + i += 2 + if i+1 < len_l and l[i+1] == ':': + i += 2 + x.time += int(l[i]) + elif len_li <= 2: + # -[0]3 + x.time = (int(l[i][:2])*3600) + else: + return None + i += 1 + + assert i == len_l or l[i] == ',' + + i += 1 + + assert i >= len_l + + except (IndexError, ValueError, AssertionError): + return None + + return res + + +DEFAULTTZPARSER = _tzparser() +def _parsetz(tzstr): + return DEFAULTTZPARSER.parse(tzstr) + + +def _parsems(value): + """Parse a I[.F] seconds value into (seconds, microseconds).""" + if "." not in value: + return int(value), 0 + else: + i, f = value.split(".") + return int(i), int(f.ljust(6, "0")[:6]) + + +# vim:ts=4:sw=4:et diff --git a/lib/dateutil_py3/relativedelta.py b/lib/dateutil_py3/relativedelta.py new file mode 100644 index 000000000000..4393bcbcde22 --- /dev/null +++ b/lib/dateutil_py3/relativedelta.py @@ -0,0 +1,436 @@ +""" +Copyright (c) 2003-2010 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__license__ = "Simplified BSD" + +import datetime +import calendar + +from six import integer_types + +__all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"] + +class weekday(object): + __slots__ = ["weekday", "n"] + + def __init__(self, weekday, n=None): + self.weekday = weekday + self.n = n + + def __call__(self, n): + if n == self.n: + return self + else: + return self.__class__(self.weekday, n) + + def __eq__(self, other): + try: + if self.weekday != other.weekday or self.n != other.n: + return False + except AttributeError: + return False + return True + + def __repr__(self): + s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] + if not self.n: + return s + else: + return "%s(%+d)" % (s, self.n) + +MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) + +class relativedelta(object): + """ +The relativedelta type is based on the specification of the excelent +work done by M.-A. Lemburg in his mx.DateTime extension. However, +notice that this type does *NOT* implement the same algorithm as +his work. Do *NOT* expect it to behave like mx.DateTime's counterpart. + +There's two different ways to build a relativedelta instance. The +first one is passing it two date/datetime classes: + + relativedelta(datetime1, datetime2) + +And the other way is to use 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 Nth weekday, which could + be positive or negative (like MO(+1) or MO(-2). Not specifying + it is the same as specifying +1. You can also use an integer, + where 0=MO. + + leapdays: + Will add given days to the date found, if year is a leap + year, and the date found 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. + +Here is the behavior of operations with relativedelta: + +1) Calculate the absolute year, using the 'year' argument, or the + original datetime year, if the argument is not present. + +2) Add the relative 'years' argument to the absolute year. + +3) Do steps 1 and 2 for month/months. + +4) 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. + +5) Add the relative 'days' argument to the absolute day. Notice + that the 'weeks' argument is multiplied by 7 and added to + 'days'. + +6) Do steps 1 and 2 for hour/hours, minute/minutes, second/seconds, + microsecond/microseconds. + +7) If the 'weekday' argument is present, calculate the weekday, + with the given (wday, nth) tuple. wday is the index of the + weekday (0-6, 0=Mon), and nth is the number of weeks to add + forward or backward, depending on its signal. Notice that if + the calculated date is already Monday, for example, using + (0, 1) or (0, -1) won't change the day. + """ + + def __init__(self, dt1=None, dt2=None, + years=0, months=0, days=0, leapdays=0, weeks=0, + hours=0, minutes=0, seconds=0, microseconds=0, + year=None, month=None, day=None, weekday=None, + yearday=None, nlyearday=None, + hour=None, minute=None, second=None, microsecond=None): + if dt1 and dt2: + if (not isinstance(dt1, datetime.date)) or (not isinstance(dt2, datetime.date)): + raise TypeError("relativedelta only diffs datetime/date") + if not type(dt1) == type(dt2): #isinstance(dt1, type(dt2)): + if not isinstance(dt1, datetime.datetime): + dt1 = datetime.datetime.fromordinal(dt1.toordinal()) + elif not isinstance(dt2, datetime.datetime): + dt2 = datetime.datetime.fromordinal(dt2.toordinal()) + self.years = 0 + self.months = 0 + self.days = 0 + self.leapdays = 0 + self.hours = 0 + self.minutes = 0 + self.seconds = 0 + self.microseconds = 0 + self.year = None + self.month = None + self.day = None + self.weekday = None + self.hour = None + self.minute = None + self.second = None + self.microsecond = None + self._has_time = 0 + + months = (dt1.year*12+dt1.month)-(dt2.year*12+dt2.month) + self._set_months(months) + dtm = self.__radd__(dt2) + if dt1 < dt2: + while dt1 > dtm: + months += 1 + self._set_months(months) + dtm = self.__radd__(dt2) + else: + while dt1 < dtm: + months -= 1 + self._set_months(months) + dtm = self.__radd__(dt2) + delta = dt1 - dtm + self.seconds = delta.seconds+delta.days*86400 + self.microseconds = delta.microseconds + else: + self.years = years + self.months = months + self.days = days+weeks*7 + self.leapdays = leapdays + self.hours = hours + self.minutes = minutes + self.seconds = seconds + self.microseconds = microseconds + self.year = year + self.month = month + self.day = day + self.hour = hour + self.minute = minute + self.second = second + self.microsecond = microsecond + + if isinstance(weekday, integer_types): + self.weekday = weekdays[weekday] + else: + self.weekday = weekday + + yday = 0 + if nlyearday: + yday = nlyearday + elif yearday: + yday = yearday + if yearday > 59: + self.leapdays = -1 + if yday: + ydayidx = [31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 366] + for idx, ydays in enumerate(ydayidx): + if yday <= ydays: + self.month = idx+1 + if idx == 0: + self.day = yday + else: + self.day = yday-ydayidx[idx-1] + break + else: + raise ValueError("invalid year day (%d)" % yday) + + self._fix() + + def _fix(self): + if abs(self.microseconds) > 999999: + s = self.microseconds//abs(self.microseconds) + div, mod = divmod(self.microseconds*s, 1000000) + self.microseconds = mod*s + self.seconds += div*s + if abs(self.seconds) > 59: + s = self.seconds//abs(self.seconds) + div, mod = divmod(self.seconds*s, 60) + self.seconds = mod*s + self.minutes += div*s + if abs(self.minutes) > 59: + s = self.minutes//abs(self.minutes) + div, mod = divmod(self.minutes*s, 60) + self.minutes = mod*s + self.hours += div*s + if abs(self.hours) > 23: + s = self.hours//abs(self.hours) + div, mod = divmod(self.hours*s, 24) + self.hours = mod*s + self.days += div*s + if abs(self.months) > 11: + s = self.months//abs(self.months) + div, mod = divmod(self.months*s, 12) + self.months = mod*s + self.years += div*s + if (self.hours or self.minutes or self.seconds or self.microseconds or + self.hour is not None or self.minute is not None or + self.second is not None or self.microsecond is not None): + self._has_time = 1 + else: + self._has_time = 0 + + def _set_months(self, months): + self.months = months + if abs(self.months) > 11: + s = self.months//abs(self.months) + div, mod = divmod(self.months*s, 12) + self.months = mod*s + self.years = div*s + else: + self.years = 0 + + def __add__(self, other): + if isinstance(other, relativedelta): + return relativedelta(years=other.years+self.years, + months=other.months+self.months, + days=other.days+self.days, + hours=other.hours+self.hours, + minutes=other.minutes+self.minutes, + seconds=other.seconds+self.seconds, + microseconds=other.microseconds+self.microseconds, + leapdays=other.leapdays or self.leapdays, + year=other.year or self.year, + month=other.month or self.month, + day=other.day or self.day, + weekday=other.weekday or self.weekday, + hour=other.hour or self.hour, + minute=other.minute or self.minute, + second=other.second or self.second, + microsecond=other.microsecond or self.microsecond) + if not isinstance(other, datetime.date): + raise TypeError("unsupported type for add operation") + elif self._has_time and not isinstance(other, datetime.datetime): + other = datetime.datetime.fromordinal(other.toordinal()) + year = (self.year or other.year)+self.years + month = self.month or other.month + if self.months: + assert 1 <= abs(self.months) <= 12 + month += self.months + if month > 12: + year += 1 + month -= 12 + elif month < 1: + year -= 1 + month += 12 + day = min(calendar.monthrange(year, month)[1], + self.day or other.day) + repl = {"year": year, "month": month, "day": day} + for attr in ["hour", "minute", "second", "microsecond"]: + value = getattr(self, attr) + if value is not None: + repl[attr] = value + days = self.days + if self.leapdays and month > 2 and calendar.isleap(year): + days += self.leapdays + ret = (other.replace(**repl) + + datetime.timedelta(days=days, + hours=self.hours, + minutes=self.minutes, + seconds=self.seconds, + microseconds=self.microseconds)) + if self.weekday: + weekday, nth = self.weekday.weekday, self.weekday.n or 1 + jumpdays = (abs(nth)-1)*7 + if nth > 0: + jumpdays += (7-ret.weekday()+weekday)%7 + else: + jumpdays += (ret.weekday()-weekday)%7 + jumpdays *= -1 + ret += datetime.timedelta(days=jumpdays) + return ret + + def __radd__(self, other): + return self.__add__(other) + + def __rsub__(self, other): + return self.__neg__().__radd__(other) + + def __sub__(self, other): + if not isinstance(other, relativedelta): + raise TypeError("unsupported type for sub operation") + return relativedelta(years=self.years-other.years, + months=self.months-other.months, + days=self.days-other.days, + hours=self.hours-other.hours, + minutes=self.minutes-other.minutes, + seconds=self.seconds-other.seconds, + microseconds=self.microseconds-other.microseconds, + leapdays=self.leapdays or other.leapdays, + year=self.year or other.year, + month=self.month or other.month, + day=self.day or other.day, + weekday=self.weekday or other.weekday, + hour=self.hour or other.hour, + minute=self.minute or other.minute, + second=self.second or other.second, + microsecond=self.microsecond or other.microsecond) + + def __neg__(self): + return relativedelta(years=-self.years, + months=-self.months, + days=-self.days, + hours=-self.hours, + minutes=-self.minutes, + seconds=-self.seconds, + microseconds=-self.microseconds, + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + + def __bool__(self): + return not (not self.years and + not self.months and + not self.days and + not self.hours and + not self.minutes and + not self.seconds and + not self.microseconds and + not self.leapdays and + self.year is None and + self.month is None and + self.day is None and + self.weekday is None and + self.hour is None and + self.minute is None and + self.second is None and + self.microsecond is None) + + def __mul__(self, other): + f = float(other) + return relativedelta(years=int(self.years*f), + months=int(self.months*f), + days=int(self.days*f), + hours=int(self.hours*f), + minutes=int(self.minutes*f), + seconds=int(self.seconds*f), + microseconds=int(self.microseconds*f), + leapdays=self.leapdays, + year=self.year, + month=self.month, + day=self.day, + weekday=self.weekday, + hour=self.hour, + minute=self.minute, + second=self.second, + microsecond=self.microsecond) + + __rmul__ = __mul__ + + def __eq__(self, other): + if not isinstance(other, relativedelta): + return False + if self.weekday or other.weekday: + if not self.weekday or not other.weekday: + return False + if self.weekday.weekday != other.weekday.weekday: + return False + n1, n2 = self.weekday.n, other.weekday.n + if n1 != n2 and not ((not n1 or n1 == 1) and (not n2 or n2 == 1)): + return False + return (self.years == other.years and + self.months == other.months and + self.days == other.days and + self.hours == other.hours and + self.minutes == other.minutes and + self.seconds == other.seconds and + self.leapdays == other.leapdays and + self.year == other.year and + self.month == other.month and + self.day == other.day and + self.hour == other.hour and + self.minute == other.minute and + self.second == other.second and + self.microsecond == other.microsecond) + + def __ne__(self, other): + return not self.__eq__(other) + + def __div__(self, other): + return self.__mul__(1/float(other)) + + __truediv__ = __div__ + + def __repr__(self): + l = [] + for attr in ["years", "months", "days", "leapdays", + "hours", "minutes", "seconds", "microseconds"]: + value = getattr(self, attr) + if value: + l.append("%s=%+d" % (attr, value)) + for attr in ["year", "month", "day", "weekday", + "hour", "minute", "second", "microsecond"]: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, repr(value))) + return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) + +# vim:ts=4:sw=4:et diff --git a/lib/dateutil_py3/rrule.py b/lib/dateutil_py3/rrule.py new file mode 100644 index 000000000000..ad4d3ba70c4e --- /dev/null +++ b/lib/dateutil_py3/rrule.py @@ -0,0 +1,1112 @@ +""" +Copyright (c) 2003-2010 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__license__ = "Simplified BSD" + +import itertools +import datetime +import calendar +try: + import _thread +except ImportError: + import thread as _thread +import sys + +from six import advance_iterator, integer_types + +__all__ = ["rrule", "rruleset", "rrulestr", + "YEARLY", "MONTHLY", "WEEKLY", "DAILY", + "HOURLY", "MINUTELY", "SECONDLY", + "MO", "TU", "WE", "TH", "FR", "SA", "SU"] + +# Every mask is 7 days longer to handle cross-year weekly periods. +M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30+ + [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7) +M365MASK = list(M366MASK) +M29, M30, M31 = list(range(1, 30)), list(range(1, 31)), list(range(1, 32)) +MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) +MDAY365MASK = list(MDAY366MASK) +M29, M30, M31 = list(range(-29, 0)), list(range(-30, 0)), list(range(-31, 0)) +NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7]) +NMDAY365MASK = list(NMDAY366MASK) +M366RANGE = (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366) +M365RANGE = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365) +WDAYMASK = [0, 1, 2, 3, 4, 5, 6]*55 +del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31] +MDAY365MASK = tuple(MDAY365MASK) +M365MASK = tuple(M365MASK) + +(YEARLY, + MONTHLY, + WEEKLY, + DAILY, + HOURLY, + MINUTELY, + SECONDLY) = list(range(7)) + +# Imported on demand. +easter = None +parser = None + +class weekday(object): + __slots__ = ["weekday", "n"] + + def __init__(self, weekday, n=None): + if n == 0: + raise ValueError("Can't create weekday with n == 0") + self.weekday = weekday + self.n = n + + def __call__(self, n): + if n == self.n: + return self + else: + return self.__class__(self.weekday, n) + + def __eq__(self, other): + try: + if self.weekday != other.weekday or self.n != other.n: + return False + except AttributeError: + return False + return True + + def __repr__(self): + s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday] + if not self.n: + return s + else: + return "%s(%+d)" % (s, self.n) + +MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)]) + +class rrulebase(object): + def __init__(self, cache=False): + if cache: + self._cache = [] + self._cache_lock = _thread.allocate_lock() + self._cache_gen = self._iter() + self._cache_complete = False + else: + self._cache = None + self._cache_complete = False + self._len = None + + def __iter__(self): + if self._cache_complete: + return iter(self._cache) + elif self._cache is None: + return self._iter() + else: + return self._iter_cached() + + def _iter_cached(self): + i = 0 + gen = self._cache_gen + cache = self._cache + acquire = self._cache_lock.acquire + release = self._cache_lock.release + while gen: + if i == len(cache): + acquire() + if self._cache_complete: + break + try: + for j in range(10): + cache.append(advance_iterator(gen)) + except StopIteration: + self._cache_gen = gen = None + self._cache_complete = True + break + release() + yield cache[i] + i += 1 + while i < self._len: + yield cache[i] + i += 1 + + def __getitem__(self, item): + if self._cache_complete: + return self._cache[item] + elif isinstance(item, slice): + if item.step and item.step < 0: + return list(iter(self))[item] + else: + return list(itertools.islice(self, + item.start or 0, + item.stop or sys.maxsize, + item.step or 1)) + elif item >= 0: + gen = iter(self) + try: + for i in range(item+1): + res = advance_iterator(gen) + except StopIteration: + raise IndexError + return res + else: + return list(iter(self))[item] + + def __contains__(self, item): + if self._cache_complete: + return item in self._cache + else: + for i in self: + if i == item: + return True + elif i > item: + return False + return False + + # __len__() introduces a large performance penality. + def count(self): + if self._len is None: + for x in self: pass + return self._len + + def before(self, dt, inc=False): + if self._cache_complete: + gen = self._cache + else: + gen = self + last = None + if inc: + for i in gen: + if i > dt: + break + last = i + else: + for i in gen: + if i >= dt: + break + last = i + return last + + def after(self, dt, inc=False): + if self._cache_complete: + gen = self._cache + else: + gen = self + if inc: + for i in gen: + if i >= dt: + return i + else: + for i in gen: + if i > dt: + return i + return None + + def between(self, after, before, inc=False): + if self._cache_complete: + gen = self._cache + else: + gen = self + started = False + l = [] + if inc: + for i in gen: + if i > before: + break + elif not started: + if i >= after: + started = True + l.append(i) + else: + l.append(i) + else: + for i in gen: + if i >= before: + break + elif not started: + if i > after: + started = True + l.append(i) + else: + l.append(i) + return l + +class rrule(rrulebase): + def __init__(self, freq, dtstart=None, + interval=1, wkst=None, count=None, until=None, bysetpos=None, + bymonth=None, bymonthday=None, byyearday=None, byeaster=None, + byweekno=None, byweekday=None, + byhour=None, byminute=None, bysecond=None, + cache=False): + super(rrule, self).__init__(cache) + global easter + if not dtstart: + dtstart = datetime.datetime.now().replace(microsecond=0) + elif not isinstance(dtstart, datetime.datetime): + dtstart = datetime.datetime.fromordinal(dtstart.toordinal()) + else: + dtstart = dtstart.replace(microsecond=0) + self._dtstart = dtstart + self._tzinfo = dtstart.tzinfo + self._freq = freq + self._interval = interval + self._count = count + if until and not isinstance(until, datetime.datetime): + until = datetime.datetime.fromordinal(until.toordinal()) + self._until = until + if wkst is None: + self._wkst = calendar.firstweekday() + elif isinstance(wkst, integer_types): + self._wkst = wkst + else: + self._wkst = wkst.weekday + if bysetpos is None: + self._bysetpos = None + elif isinstance(bysetpos, integer_types): + if bysetpos == 0 or not (-366 <= bysetpos <= 366): + raise ValueError("bysetpos must be between 1 and 366, " + "or between -366 and -1") + self._bysetpos = (bysetpos,) + else: + self._bysetpos = tuple(bysetpos) + for pos in self._bysetpos: + if pos == 0 or not (-366 <= pos <= 366): + raise ValueError("bysetpos must be between 1 and 366, " + "or between -366 and -1") + if not (byweekno or byyearday or bymonthday or + byweekday is not None or byeaster is not None): + if freq == YEARLY: + if not bymonth: + bymonth = dtstart.month + bymonthday = dtstart.day + elif freq == MONTHLY: + bymonthday = dtstart.day + elif freq == WEEKLY: + byweekday = dtstart.weekday() + # bymonth + if not bymonth: + self._bymonth = None + elif isinstance(bymonth, integer_types): + self._bymonth = (bymonth,) + else: + self._bymonth = tuple(bymonth) + # byyearday + if not byyearday: + self._byyearday = None + elif isinstance(byyearday, integer_types): + self._byyearday = (byyearday,) + else: + self._byyearday = tuple(byyearday) + # byeaster + if byeaster is not None: + if not easter: + from dateutil import easter + if isinstance(byeaster, integer_types): + self._byeaster = (byeaster,) + else: + self._byeaster = tuple(byeaster) + else: + self._byeaster = None + # bymonthay + if not bymonthday: + self._bymonthday = () + self._bynmonthday = () + elif isinstance(bymonthday, integer_types): + if bymonthday < 0: + self._bynmonthday = (bymonthday,) + self._bymonthday = () + else: + self._bymonthday = (bymonthday,) + self._bynmonthday = () + else: + self._bymonthday = tuple([x for x in bymonthday if x > 0]) + self._bynmonthday = tuple([x for x in bymonthday if x < 0]) + # byweekno + if byweekno is None: + self._byweekno = None + elif isinstance(byweekno, integer_types): + self._byweekno = (byweekno,) + else: + self._byweekno = tuple(byweekno) + # byweekday / bynweekday + if byweekday is None: + self._byweekday = None + self._bynweekday = None + elif isinstance(byweekday, integer_types): + self._byweekday = (byweekday,) + self._bynweekday = None + elif hasattr(byweekday, "n"): + if not byweekday.n or freq > MONTHLY: + self._byweekday = (byweekday.weekday,) + self._bynweekday = None + else: + self._bynweekday = ((byweekday.weekday, byweekday.n),) + self._byweekday = None + else: + self._byweekday = [] + self._bynweekday = [] + for wday in byweekday: + if isinstance(wday, integer_types): + self._byweekday.append(wday) + elif not wday.n or freq > MONTHLY: + self._byweekday.append(wday.weekday) + else: + self._bynweekday.append((wday.weekday, wday.n)) + self._byweekday = tuple(self._byweekday) + self._bynweekday = tuple(self._bynweekday) + if not self._byweekday: + self._byweekday = None + elif not self._bynweekday: + self._bynweekday = None + # byhour + if byhour is None: + if freq < HOURLY: + self._byhour = (dtstart.hour,) + else: + self._byhour = None + elif isinstance(byhour, integer_types): + self._byhour = (byhour,) + else: + self._byhour = tuple(byhour) + # byminute + if byminute is None: + if freq < MINUTELY: + self._byminute = (dtstart.minute,) + else: + self._byminute = None + elif isinstance(byminute, integer_types): + self._byminute = (byminute,) + else: + self._byminute = tuple(byminute) + # bysecond + if bysecond is None: + if freq < SECONDLY: + self._bysecond = (dtstart.second,) + else: + self._bysecond = None + elif isinstance(bysecond, integer_types): + self._bysecond = (bysecond,) + else: + self._bysecond = tuple(bysecond) + + if self._freq >= HOURLY: + self._timeset = None + else: + self._timeset = [] + for hour in self._byhour: + for minute in self._byminute: + for second in self._bysecond: + self._timeset.append( + datetime.time(hour, minute, second, + tzinfo=self._tzinfo)) + self._timeset.sort() + self._timeset = tuple(self._timeset) + + def _iter(self): + year, month, day, hour, minute, second, weekday, yearday, _ = \ + self._dtstart.timetuple() + + # Some local variables to speed things up a bit + freq = self._freq + interval = self._interval + wkst = self._wkst + until = self._until + bymonth = self._bymonth + byweekno = self._byweekno + byyearday = self._byyearday + byweekday = self._byweekday + byeaster = self._byeaster + bymonthday = self._bymonthday + bynmonthday = self._bynmonthday + bysetpos = self._bysetpos + byhour = self._byhour + byminute = self._byminute + bysecond = self._bysecond + + ii = _iterinfo(self) + ii.rebuild(year, month) + + getdayset = {YEARLY:ii.ydayset, + MONTHLY:ii.mdayset, + WEEKLY:ii.wdayset, + DAILY:ii.ddayset, + HOURLY:ii.ddayset, + MINUTELY:ii.ddayset, + SECONDLY:ii.ddayset}[freq] + + if freq < HOURLY: + timeset = self._timeset + else: + gettimeset = {HOURLY:ii.htimeset, + MINUTELY:ii.mtimeset, + SECONDLY:ii.stimeset}[freq] + if ((freq >= HOURLY and + self._byhour and hour not in self._byhour) or + (freq >= MINUTELY and + self._byminute and minute not in self._byminute) or + (freq >= SECONDLY and + self._bysecond and second not in self._bysecond)): + timeset = () + else: + timeset = gettimeset(hour, minute, second) + + total = 0 + count = self._count + while True: + # Get dayset with the right frequency + dayset, start, end = getdayset(year, month, day) + + # Do the "hard" work ;-) + filtered = False + for i in dayset[start:end]: + if ((bymonth and ii.mmask[i] not in bymonth) or + (byweekno and not ii.wnomask[i]) or + (byweekday and ii.wdaymask[i] not in byweekday) or + (ii.nwdaymask and not ii.nwdaymask[i]) or + (byeaster and not ii.eastermask[i]) or + ((bymonthday or bynmonthday) and + ii.mdaymask[i] not in bymonthday and + ii.nmdaymask[i] not in bynmonthday) or + (byyearday and + ((i < ii.yearlen and i+1 not in byyearday + and -ii.yearlen+i not in byyearday) or + (i >= ii.yearlen and i+1-ii.yearlen not in byyearday + and -ii.nextyearlen+i-ii.yearlen + not in byyearday)))): + dayset[i] = None + filtered = True + + # Output results + if bysetpos and timeset: + poslist = [] + for pos in bysetpos: + if pos < 0: + daypos, timepos = divmod(pos, len(timeset)) + else: + daypos, timepos = divmod(pos-1, len(timeset)) + try: + i = [x for x in dayset[start:end] + if x is not None][daypos] + time = timeset[timepos] + except IndexError: + pass + else: + date = datetime.date.fromordinal(ii.yearordinal+i) + res = datetime.datetime.combine(date, time) + if res not in poslist: + poslist.append(res) + poslist.sort() + for res in poslist: + if until and res > until: + self._len = total + return + elif res >= self._dtstart: + total += 1 + yield res + if count: + count -= 1 + if not count: + self._len = total + return + else: + for i in dayset[start:end]: + if i is not None: + date = datetime.date.fromordinal(ii.yearordinal+i) + for time in timeset: + res = datetime.datetime.combine(date, time) + if until and res > until: + self._len = total + return + elif res >= self._dtstart: + total += 1 + yield res + if count: + count -= 1 + if not count: + self._len = total + return + + # Handle frequency and interval + fixday = False + if freq == YEARLY: + year += interval + if year > datetime.MAXYEAR: + self._len = total + return + ii.rebuild(year, month) + elif freq == MONTHLY: + month += interval + if month > 12: + div, mod = divmod(month, 12) + month = mod + year += div + if month == 0: + month = 12 + year -= 1 + if year > datetime.MAXYEAR: + self._len = total + return + ii.rebuild(year, month) + elif freq == WEEKLY: + if wkst > weekday: + day += -(weekday+1+(6-wkst))+self._interval*7 + else: + day += -(weekday-wkst)+self._interval*7 + weekday = wkst + fixday = True + elif freq == DAILY: + day += interval + fixday = True + elif freq == HOURLY: + if filtered: + # Jump to one iteration before next day + hour += ((23-hour)//interval)*interval + while True: + hour += interval + div, mod = divmod(hour, 24) + if div: + hour = mod + day += div + fixday = True + if not byhour or hour in byhour: + break + timeset = gettimeset(hour, minute, second) + elif freq == MINUTELY: + if filtered: + # Jump to one iteration before next day + minute += ((1439-(hour*60+minute))//interval)*interval + while True: + minute += interval + div, mod = divmod(minute, 60) + if div: + minute = mod + hour += div + div, mod = divmod(hour, 24) + if div: + hour = mod + day += div + fixday = True + filtered = False + if ((not byhour or hour in byhour) and + (not byminute or minute in byminute)): + break + timeset = gettimeset(hour, minute, second) + elif freq == SECONDLY: + if filtered: + # Jump to one iteration before next day + second += (((86399-(hour*3600+minute*60+second)) + //interval)*interval) + while True: + second += self._interval + div, mod = divmod(second, 60) + if div: + second = mod + minute += div + div, mod = divmod(minute, 60) + if div: + minute = mod + hour += div + div, mod = divmod(hour, 24) + if div: + hour = mod + day += div + fixday = True + if ((not byhour or hour in byhour) and + (not byminute or minute in byminute) and + (not bysecond or second in bysecond)): + break + timeset = gettimeset(hour, minute, second) + + if fixday and day > 28: + daysinmonth = calendar.monthrange(year, month)[1] + if day > daysinmonth: + while day > daysinmonth: + day -= daysinmonth + month += 1 + if month == 13: + month = 1 + year += 1 + if year > datetime.MAXYEAR: + self._len = total + return + daysinmonth = calendar.monthrange(year, month)[1] + ii.rebuild(year, month) + +class _iterinfo(object): + __slots__ = ["rrule", "lastyear", "lastmonth", + "yearlen", "nextyearlen", "yearordinal", "yearweekday", + "mmask", "mrange", "mdaymask", "nmdaymask", + "wdaymask", "wnomask", "nwdaymask", "eastermask"] + + def __init__(self, rrule): + for attr in self.__slots__: + setattr(self, attr, None) + self.rrule = rrule + + def rebuild(self, year, month): + # Every mask is 7 days longer to handle cross-year weekly periods. + rr = self.rrule + if year != self.lastyear: + self.yearlen = 365+calendar.isleap(year) + self.nextyearlen = 365+calendar.isleap(year+1) + firstyday = datetime.date(year, 1, 1) + self.yearordinal = firstyday.toordinal() + self.yearweekday = firstyday.weekday() + + wday = datetime.date(year, 1, 1).weekday() + if self.yearlen == 365: + self.mmask = M365MASK + self.mdaymask = MDAY365MASK + self.nmdaymask = NMDAY365MASK + self.wdaymask = WDAYMASK[wday:] + self.mrange = M365RANGE + else: + self.mmask = M366MASK + self.mdaymask = MDAY366MASK + self.nmdaymask = NMDAY366MASK + self.wdaymask = WDAYMASK[wday:] + self.mrange = M366RANGE + + if not rr._byweekno: + self.wnomask = None + else: + self.wnomask = [0]*(self.yearlen+7) + #no1wkst = firstwkst = self.wdaymask.index(rr._wkst) + no1wkst = firstwkst = (7-self.yearweekday+rr._wkst)%7 + if no1wkst >= 4: + no1wkst = 0 + # Number of days in the year, plus the days we got + # from last year. + wyearlen = self.yearlen+(self.yearweekday-rr._wkst)%7 + else: + # Number of days in the year, minus the days we + # left in last year. + wyearlen = self.yearlen-no1wkst + div, mod = divmod(wyearlen, 7) + numweeks = div+mod//4 + for n in rr._byweekno: + if n < 0: + n += numweeks+1 + if not (0 < n <= numweeks): + continue + if n > 1: + i = no1wkst+(n-1)*7 + if no1wkst != firstwkst: + i -= 7-firstwkst + else: + i = no1wkst + for j in range(7): + self.wnomask[i] = 1 + i += 1 + if self.wdaymask[i] == rr._wkst: + break + if 1 in rr._byweekno: + # Check week number 1 of next year as well + # TODO: Check -numweeks for next year. + i = no1wkst+numweeks*7 + if no1wkst != firstwkst: + i -= 7-firstwkst + if i < self.yearlen: + # If week starts in next year, we + # don't care about it. + for j in range(7): + self.wnomask[i] = 1 + i += 1 + if self.wdaymask[i] == rr._wkst: + break + if no1wkst: + # Check last week number of last year as + # well. If no1wkst is 0, either the year + # started on week start, or week number 1 + # got days from last year, so there are no + # days from last year's last week number in + # this year. + if -1 not in rr._byweekno: + lyearweekday = datetime.date(year-1, 1, 1).weekday() + lno1wkst = (7-lyearweekday+rr._wkst)%7 + lyearlen = 365+calendar.isleap(year-1) + if lno1wkst >= 4: + lno1wkst = 0 + lnumweeks = 52+(lyearlen+ + (lyearweekday-rr._wkst)%7)%7//4 + else: + lnumweeks = 52+(self.yearlen-no1wkst)%7//4 + else: + lnumweeks = -1 + if lnumweeks in rr._byweekno: + for i in range(no1wkst): + self.wnomask[i] = 1 + + if (rr._bynweekday and + (month != self.lastmonth or year != self.lastyear)): + ranges = [] + if rr._freq == YEARLY: + if rr._bymonth: + for month in rr._bymonth: + ranges.append(self.mrange[month-1:month+1]) + else: + ranges = [(0, self.yearlen)] + elif rr._freq == MONTHLY: + ranges = [self.mrange[month-1:month+1]] + if ranges: + # Weekly frequency won't get here, so we may not + # care about cross-year weekly periods. + self.nwdaymask = [0]*self.yearlen + for first, last in ranges: + last -= 1 + for wday, n in rr._bynweekday: + if n < 0: + i = last+(n+1)*7 + i -= (self.wdaymask[i]-wday)%7 + else: + i = first+(n-1)*7 + i += (7-self.wdaymask[i]+wday)%7 + if first <= i <= last: + self.nwdaymask[i] = 1 + + if rr._byeaster: + self.eastermask = [0]*(self.yearlen+7) + eyday = easter.easter(year).toordinal()-self.yearordinal + for offset in rr._byeaster: + self.eastermask[eyday+offset] = 1 + + self.lastyear = year + self.lastmonth = month + + def ydayset(self, year, month, day): + return list(range(self.yearlen)), 0, self.yearlen + + def mdayset(self, year, month, day): + set = [None]*self.yearlen + start, end = self.mrange[month-1:month+1] + for i in range(start, end): + set[i] = i + return set, start, end + + def wdayset(self, year, month, day): + # We need to handle cross-year weeks here. + set = [None]*(self.yearlen+7) + i = datetime.date(year, month, day).toordinal()-self.yearordinal + start = i + for j in range(7): + set[i] = i + i += 1 + #if (not (0 <= i < self.yearlen) or + # self.wdaymask[i] == self.rrule._wkst): + # This will cross the year boundary, if necessary. + if self.wdaymask[i] == self.rrule._wkst: + break + return set, start, i + + def ddayset(self, year, month, day): + set = [None]*self.yearlen + i = datetime.date(year, month, day).toordinal()-self.yearordinal + set[i] = i + return set, i, i+1 + + def htimeset(self, hour, minute, second): + set = [] + rr = self.rrule + for minute in rr._byminute: + for second in rr._bysecond: + set.append(datetime.time(hour, minute, second, + tzinfo=rr._tzinfo)) + set.sort() + return set + + def mtimeset(self, hour, minute, second): + set = [] + rr = self.rrule + for second in rr._bysecond: + set.append(datetime.time(hour, minute, second, tzinfo=rr._tzinfo)) + set.sort() + return set + + def stimeset(self, hour, minute, second): + return (datetime.time(hour, minute, second, + tzinfo=self.rrule._tzinfo),) + + +class rruleset(rrulebase): + + class _genitem(object): + def __init__(self, genlist, gen): + try: + self.dt = advance_iterator(gen) + genlist.append(self) + except StopIteration: + pass + self.genlist = genlist + self.gen = gen + + def __next__(self): + try: + self.dt = advance_iterator(self.gen) + except StopIteration: + self.genlist.remove(self) + + next = __next__ + + def __lt__(self, other): + return self.dt < other.dt + + def __gt__(self, other): + return self.dt > other.dt + + def __eq__(self, other): + return self.dt == other.dt + + def __ne__(self, other): + return self.dt != other.dt + + def __init__(self, cache=False): + super(rruleset, self).__init__(cache) + self._rrule = [] + self._rdate = [] + self._exrule = [] + self._exdate = [] + + def rrule(self, rrule): + self._rrule.append(rrule) + + def rdate(self, rdate): + self._rdate.append(rdate) + + def exrule(self, exrule): + self._exrule.append(exrule) + + def exdate(self, exdate): + self._exdate.append(exdate) + + def _iter(self): + rlist = [] + self._rdate.sort() + self._genitem(rlist, iter(self._rdate)) + for gen in [iter(x) for x in self._rrule]: + self._genitem(rlist, gen) + rlist.sort() + exlist = [] + self._exdate.sort() + self._genitem(exlist, iter(self._exdate)) + for gen in [iter(x) for x in self._exrule]: + self._genitem(exlist, gen) + exlist.sort() + lastdt = None + total = 0 + while rlist: + ritem = rlist[0] + if not lastdt or lastdt != ritem.dt: + while exlist and exlist[0] < ritem: + advance_iterator(exlist[0]) + exlist.sort() + if not exlist or ritem != exlist[0]: + total += 1 + yield ritem.dt + lastdt = ritem.dt + advance_iterator(ritem) + rlist.sort() + self._len = total + +class _rrulestr(object): + + _freq_map = {"YEARLY": YEARLY, + "MONTHLY": MONTHLY, + "WEEKLY": WEEKLY, + "DAILY": DAILY, + "HOURLY": HOURLY, + "MINUTELY": MINUTELY, + "SECONDLY": SECONDLY} + + _weekday_map = {"MO":0,"TU":1,"WE":2,"TH":3,"FR":4,"SA":5,"SU":6} + + def _handle_int(self, rrkwargs, name, value, **kwargs): + rrkwargs[name.lower()] = int(value) + + def _handle_int_list(self, rrkwargs, name, value, **kwargs): + rrkwargs[name.lower()] = [int(x) for x in value.split(',')] + + _handle_INTERVAL = _handle_int + _handle_COUNT = _handle_int + _handle_BYSETPOS = _handle_int_list + _handle_BYMONTH = _handle_int_list + _handle_BYMONTHDAY = _handle_int_list + _handle_BYYEARDAY = _handle_int_list + _handle_BYEASTER = _handle_int_list + _handle_BYWEEKNO = _handle_int_list + _handle_BYHOUR = _handle_int_list + _handle_BYMINUTE = _handle_int_list + _handle_BYSECOND = _handle_int_list + + def _handle_FREQ(self, rrkwargs, name, value, **kwargs): + rrkwargs["freq"] = self._freq_map[value] + + def _handle_UNTIL(self, rrkwargs, name, value, **kwargs): + global parser + if not parser: + from dateutil import parser + try: + rrkwargs["until"] = parser.parse(value, + ignoretz=kwargs.get("ignoretz"), + tzinfos=kwargs.get("tzinfos")) + except ValueError: + raise ValueError("invalid until date") + + def _handle_WKST(self, rrkwargs, name, value, **kwargs): + rrkwargs["wkst"] = self._weekday_map[value] + + def _handle_BYWEEKDAY(self, rrkwargs, name, value, **kwarsg): + l = [] + for wday in value.split(','): + for i in range(len(wday)): + if wday[i] not in '+-0123456789': + break + n = wday[:i] or None + w = wday[i:] + if n: n = int(n) + l.append(weekdays[self._weekday_map[w]](n)) + rrkwargs["byweekday"] = l + + _handle_BYDAY = _handle_BYWEEKDAY + + def _parse_rfc_rrule(self, line, + dtstart=None, + cache=False, + ignoretz=False, + tzinfos=None): + if line.find(':') != -1: + name, value = line.split(':') + if name != "RRULE": + raise ValueError("unknown parameter name") + else: + value = line + rrkwargs = {} + for pair in value.split(';'): + name, value = pair.split('=') + name = name.upper() + value = value.upper() + try: + getattr(self, "_handle_"+name)(rrkwargs, name, value, + ignoretz=ignoretz, + tzinfos=tzinfos) + except AttributeError: + raise ValueError("unknown parameter '%s'" % name) + except (KeyError, ValueError): + raise ValueError("invalid '%s': %s" % (name, value)) + return rrule(dtstart=dtstart, cache=cache, **rrkwargs) + + def _parse_rfc(self, s, + dtstart=None, + cache=False, + unfold=False, + forceset=False, + compatible=False, + ignoretz=False, + tzinfos=None): + global parser + if compatible: + forceset = True + unfold = True + s = s.upper() + if not s.strip(): + raise ValueError("empty string") + if unfold: + lines = s.splitlines() + i = 0 + while i < len(lines): + line = lines[i].rstrip() + if not line: + del lines[i] + elif i > 0 and line[0] == " ": + lines[i-1] += line[1:] + del lines[i] + else: + i += 1 + else: + lines = s.split() + if (not forceset and len(lines) == 1 and + (s.find(':') == -1 or s.startswith('RRULE:'))): + return self._parse_rfc_rrule(lines[0], cache=cache, + dtstart=dtstart, ignoretz=ignoretz, + tzinfos=tzinfos) + else: + rrulevals = [] + rdatevals = [] + exrulevals = [] + exdatevals = [] + for line in lines: + if not line: + continue + if line.find(':') == -1: + name = "RRULE" + value = line + else: + name, value = line.split(':', 1) + parms = name.split(';') + if not parms: + raise ValueError("empty property name") + name = parms[0] + parms = parms[1:] + if name == "RRULE": + for parm in parms: + raise ValueError("unsupported RRULE parm: "+parm) + rrulevals.append(value) + elif name == "RDATE": + for parm in parms: + if parm != "VALUE=DATE-TIME": + raise ValueError("unsupported RDATE parm: "+parm) + rdatevals.append(value) + elif name == "EXRULE": + for parm in parms: + raise ValueError("unsupported EXRULE parm: "+parm) + exrulevals.append(value) + elif name == "EXDATE": + for parm in parms: + if parm != "VALUE=DATE-TIME": + raise ValueError("unsupported RDATE parm: "+parm) + exdatevals.append(value) + elif name == "DTSTART": + for parm in parms: + raise ValueError("unsupported DTSTART parm: "+parm) + if not parser: + from dateutil import parser + dtstart = parser.parse(value, ignoretz=ignoretz, + tzinfos=tzinfos) + else: + raise ValueError("unsupported property: "+name) + if (forceset or len(rrulevals) > 1 or + rdatevals or exrulevals or exdatevals): + if not parser and (rdatevals or exdatevals): + from dateutil import parser + set = rruleset(cache=cache) + for value in rrulevals: + set.rrule(self._parse_rfc_rrule(value, dtstart=dtstart, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in rdatevals: + for datestr in value.split(','): + set.rdate(parser.parse(datestr, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in exrulevals: + set.exrule(self._parse_rfc_rrule(value, dtstart=dtstart, + ignoretz=ignoretz, + tzinfos=tzinfos)) + for value in exdatevals: + for datestr in value.split(','): + set.exdate(parser.parse(datestr, + ignoretz=ignoretz, + tzinfos=tzinfos)) + if compatible and dtstart: + set.rdate(dtstart) + return set + else: + return self._parse_rfc_rrule(rrulevals[0], + dtstart=dtstart, + cache=cache, + ignoretz=ignoretz, + tzinfos=tzinfos) + + def __call__(self, s, **kwargs): + return self._parse_rfc(s, **kwargs) + +rrulestr = _rrulestr() + +# vim:ts=4:sw=4:et diff --git a/lib/dateutil_py3/six.py b/lib/dateutil_py3/six.py new file mode 100644 index 000000000000..6526d76cb148 --- /dev/null +++ b/lib/dateutil_py3/six.py @@ -0,0 +1,353 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +import operator +import sys +import types + +__author__ = "Benjamin Peterson " +__version__ = "1.1.0" + + +# True if we are running on Python 3. +PY3 = sys.version_info[0] == 3 + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) + # This is a bit ugly, but it avoids running this again. + delattr(tp, self.name) + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + + +class _MovedItems(types.ModuleType): + """Lazy loading of moved objects""" + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("reload_module", "__builtin__", "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("winreg", "_winreg"), +] +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) +del attr + +moves = sys.modules["six.moves"] = _MovedItems("moves") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_code = "__code__" + _func_defaults = "__defaults__" + + _iterkeys = "keys" + _itervalues = "values" + _iteritems = "items" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_code = "func_code" + _func_defaults = "func_defaults" + + _iterkeys = "iterkeys" + _itervalues = "itervalues" + _iteritems = "iteritems" + + +if PY3: + def get_unbound_function(unbound): + return unbound + + + advance_iterator = next + + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) +else: + def get_unbound_function(unbound): + return unbound.im_func + + + def advance_iterator(it): + return it.next() + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) + + +def iterkeys(d): + """Return an iterator over the keys of a dictionary.""" + return getattr(d, _iterkeys)() + +def itervalues(d): + """Return an iterator over the values of a dictionary.""" + return getattr(d, _itervalues)() + +def iteritems(d): + """Return an iterator over the (key, value) pairs of a dictionary.""" + return getattr(d, _iteritems)() + + +if PY3: + def b(s): + return s.encode("latin-1") + def u(s): + return s + if sys.version_info[1] <= 1: + def int2byte(i): + return bytes((i,)) + else: + # This is about 2x faster than the implementation above on 3.2+ + int2byte = operator.methodcaller("to_bytes", 1, "big") + import io + StringIO = io.StringIO + BytesIO = io.BytesIO +else: + def b(s): + return s + def u(s): + return unicode(s, "unicode_escape") + int2byte = chr + import StringIO + StringIO = BytesIO = StringIO.StringIO +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +if PY3: + import builtins + exec_ = getattr(builtins, "exec") + + + def reraise(tp, value, tb=None): + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + + + print_ = getattr(builtins, "print") + del builtins + +else: + def exec_(code, globs=None, locs=None): + """Execute code in a namespace.""" + if globs is None: + frame = sys._getframe(1) + globs = frame.f_globals + if locs is None: + locs = frame.f_locals + del frame + elif locs is None: + locs = globs + exec("""exec code in globs, locs""") + + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + + def print_(*args, **kwargs): + """The new-style print function.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + def write(data): + if not isinstance(data, basestring): + data = str(data) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) + +_add_doc(reraise, """Reraise an exception.""") + + +def with_metaclass(meta, base=object): + """Create a base class with a metaclass.""" + return meta("NewBase", (base,), {}) diff --git a/lib/dateutil_py3/tz.py b/lib/dateutil_py3/tz.py new file mode 100644 index 000000000000..e849fc24b5e2 --- /dev/null +++ b/lib/dateutil_py3/tz.py @@ -0,0 +1,960 @@ +""" +Copyright (c) 2003-2007 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +__license__ = "Simplified BSD" + +from six import string_types, PY3 + +import datetime +import struct +import time +import sys +import os + +relativedelta = None +parser = None +rrule = None + +__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", + "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"] + +try: + from dateutil.tzwin import tzwin, tzwinlocal +except (ImportError, OSError): + tzwin, tzwinlocal = None, None + +def tzname_in_python2(myfunc): + """Change unicode output into bytestrings in Python 2 + + tzname() API changed in Python 3. It used to return bytes, but was changed + to unicode strings + """ + def inner_func(*args, **kwargs): + if PY3: + return myfunc(*args, **kwargs) + else: + return myfunc(*args, **kwargs).encode() + return inner_func + +ZERO = datetime.timedelta(0) +EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal() + +class tzutc(datetime.tzinfo): + + def utcoffset(self, dt): + return ZERO + + def dst(self, dt): + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return "UTC" + + def __eq__(self, other): + return (isinstance(other, tzutc) or + (isinstance(other, tzoffset) and other._offset == ZERO)) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s()" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + +class tzoffset(datetime.tzinfo): + + def __init__(self, name, offset): + self._name = name + self._offset = datetime.timedelta(seconds=offset) + + def utcoffset(self, dt): + return self._offset + + def dst(self, dt): + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return self._name + + def __eq__(self, other): + return (isinstance(other, tzoffset) and + self._offset == other._offset) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s(%s, %s)" % (self.__class__.__name__, + repr(self._name), + self._offset.days*86400+self._offset.seconds) + + __reduce__ = object.__reduce__ + +class tzlocal(datetime.tzinfo): + + _std_offset = datetime.timedelta(seconds=-time.timezone) + if time.daylight: + _dst_offset = datetime.timedelta(seconds=-time.altzone) + else: + _dst_offset = _std_offset + + def utcoffset(self, dt): + if self._isdst(dt): + return self._dst_offset + else: + return self._std_offset + + def dst(self, dt): + if self._isdst(dt): + return self._dst_offset-self._std_offset + else: + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return time.tzname[self._isdst(dt)] + + def _isdst(self, dt): + # We can't use mktime here. It is unstable when deciding if + # the hour near to a change is DST or not. + # + # timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour, + # dt.minute, dt.second, dt.weekday(), 0, -1)) + # return time.localtime(timestamp).tm_isdst + # + # The code above yields the following result: + # + #>>> import tz, datetime + #>>> t = tz.tzlocal() + #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + #'BRDT' + #>>> datetime.datetime(2003,2,16,0,tzinfo=t).tzname() + #'BRST' + #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + #'BRST' + #>>> datetime.datetime(2003,2,15,22,tzinfo=t).tzname() + #'BRDT' + #>>> datetime.datetime(2003,2,15,23,tzinfo=t).tzname() + #'BRDT' + # + # Here is a more stable implementation: + # + timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 + + dt.hour * 3600 + + dt.minute * 60 + + dt.second) + return time.localtime(timestamp+time.timezone).tm_isdst + + def __eq__(self, other): + if not isinstance(other, tzlocal): + return False + return (self._std_offset == other._std_offset and + self._dst_offset == other._dst_offset) + return True + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s()" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + +class _ttinfo(object): + __slots__ = ["offset", "delta", "isdst", "abbr", "isstd", "isgmt"] + + def __init__(self): + for attr in self.__slots__: + setattr(self, attr, None) + + def __repr__(self): + l = [] + for attr in self.__slots__: + value = getattr(self, attr) + if value is not None: + l.append("%s=%s" % (attr, repr(value))) + return "%s(%s)" % (self.__class__.__name__, ", ".join(l)) + + def __eq__(self, other): + if not isinstance(other, _ttinfo): + return False + return (self.offset == other.offset and + self.delta == other.delta and + self.isdst == other.isdst and + self.abbr == other.abbr and + self.isstd == other.isstd and + self.isgmt == other.isgmt) + + def __ne__(self, other): + return not self.__eq__(other) + + def __getstate__(self): + state = {} + for name in self.__slots__: + state[name] = getattr(self, name, None) + return state + + def __setstate__(self, state): + for name in self.__slots__: + if name in state: + setattr(self, name, state[name]) + +class tzfile(datetime.tzinfo): + + # http://www.twinsun.com/tz/tz-link.htm + # ftp://ftp.iana.org/tz/tz*.tar.gz + + def __init__(self, fileobj): + if isinstance(fileobj, string_types): + self._filename = fileobj + fileobj = open(fileobj, 'rb') + elif hasattr(fileobj, "name"): + self._filename = fileobj.name + else: + self._filename = repr(fileobj) + + # From tzfile(5): + # + # The time zone information files used by tzset(3) + # begin with the magic characters "TZif" to identify + # them as time zone information files, followed by + # sixteen bytes reserved for future use, followed by + # six four-byte values of type long, written in a + # ``standard'' byte order (the high-order byte + # of the value is written first). + + if fileobj.read(4).decode() != "TZif": + raise ValueError("magic not found") + + fileobj.read(16) + + ( + # The number of UTC/local indicators stored in the file. + ttisgmtcnt, + + # The number of standard/wall indicators stored in the file. + ttisstdcnt, + + # The number of leap seconds for which data is + # stored in the file. + leapcnt, + + # The number of "transition times" for which data + # is stored in the file. + timecnt, + + # The number of "local time types" for which data + # is stored in the file (must not be zero). + typecnt, + + # The number of characters of "time zone + # abbreviation strings" stored in the file. + charcnt, + + ) = struct.unpack(">6l", fileobj.read(24)) + + # The above header is followed by tzh_timecnt four-byte + # values of type long, sorted in ascending order. + # These values are written in ``standard'' byte order. + # Each is used as a transition time (as returned by + # time(2)) at which the rules for computing local time + # change. + + if timecnt: + self._trans_list = struct.unpack(">%dl" % timecnt, + fileobj.read(timecnt*4)) + else: + self._trans_list = [] + + # Next come tzh_timecnt one-byte values of type unsigned + # char; each one tells which of the different types of + # ``local time'' types described in the file is associated + # with the same-indexed transition time. These values + # serve as indices into an array of ttinfo structures that + # appears next in the file. + + if timecnt: + self._trans_idx = struct.unpack(">%dB" % timecnt, + fileobj.read(timecnt)) + else: + self._trans_idx = [] + + # Each ttinfo structure is written as a four-byte value + # for tt_gmtoff of type long, in a standard byte + # order, followed by a one-byte value for tt_isdst + # and a one-byte value for tt_abbrind. In each + # structure, tt_gmtoff gives the number of + # seconds to be added to UTC, tt_isdst tells whether + # tm_isdst should be set by localtime(3), and + # tt_abbrind serves as an index into the array of + # time zone abbreviation characters that follow the + # ttinfo structure(s) in the file. + + ttinfo = [] + + for i in range(typecnt): + ttinfo.append(struct.unpack(">lbb", fileobj.read(6))) + + abbr = fileobj.read(charcnt).decode() + + # Then there are tzh_leapcnt pairs of four-byte + # values, written in standard byte order; the + # first value of each pair gives the time (as + # returned by time(2)) at which a leap second + # occurs; the second gives the total number of + # leap seconds to be applied after the given time. + # The pairs of values are sorted in ascending order + # by time. + + # Not used, for now + if leapcnt: + leap = struct.unpack(">%dl" % (leapcnt*2), + fileobj.read(leapcnt*8)) + + # Then there are tzh_ttisstdcnt standard/wall + # indicators, each stored as a one-byte value; + # they tell whether the transition times associated + # with local time types were specified as standard + # time or wall clock time, and are used when + # a time zone file is used in handling POSIX-style + # time zone environment variables. + + if ttisstdcnt: + isstd = struct.unpack(">%db" % ttisstdcnt, + fileobj.read(ttisstdcnt)) + + # Finally, there are tzh_ttisgmtcnt UTC/local + # indicators, each stored as a one-byte value; + # they tell whether the transition times associated + # with local time types were specified as UTC or + # local time, and are used when a time zone file + # is used in handling POSIX-style time zone envi- + # ronment variables. + + if ttisgmtcnt: + isgmt = struct.unpack(">%db" % ttisgmtcnt, + fileobj.read(ttisgmtcnt)) + + # ** Everything has been read ** + + # Build ttinfo list + self._ttinfo_list = [] + for i in range(typecnt): + gmtoff, isdst, abbrind = ttinfo[i] + # Round to full-minutes if that's not the case. Python's + # datetime doesn't accept sub-minute timezones. Check + # http://python.org/sf/1447945 for some information. + gmtoff = (gmtoff+30)//60*60 + tti = _ttinfo() + tti.offset = gmtoff + tti.delta = datetime.timedelta(seconds=gmtoff) + tti.isdst = isdst + tti.abbr = abbr[abbrind:abbr.find('\x00', abbrind)] + tti.isstd = (ttisstdcnt > i and isstd[i] != 0) + tti.isgmt = (ttisgmtcnt > i and isgmt[i] != 0) + self._ttinfo_list.append(tti) + + # Replace ttinfo indexes for ttinfo objects. + trans_idx = [] + for idx in self._trans_idx: + trans_idx.append(self._ttinfo_list[idx]) + self._trans_idx = tuple(trans_idx) + + # Set standard, dst, and before ttinfos. before will be + # used when a given time is before any transitions, + # and will be set to the first non-dst ttinfo, or to + # the first dst, if all of them are dst. + self._ttinfo_std = None + self._ttinfo_dst = None + self._ttinfo_before = None + if self._ttinfo_list: + if not self._trans_list: + self._ttinfo_std = self._ttinfo_first = self._ttinfo_list[0] + else: + for i in range(timecnt-1, -1, -1): + tti = self._trans_idx[i] + if not self._ttinfo_std and not tti.isdst: + self._ttinfo_std = tti + elif not self._ttinfo_dst and tti.isdst: + self._ttinfo_dst = tti + if self._ttinfo_std and self._ttinfo_dst: + break + else: + if self._ttinfo_dst and not self._ttinfo_std: + self._ttinfo_std = self._ttinfo_dst + + for tti in self._ttinfo_list: + if not tti.isdst: + self._ttinfo_before = tti + break + else: + self._ttinfo_before = self._ttinfo_list[0] + + # Now fix transition times to become relative to wall time. + # + # I'm not sure about this. In my tests, the tz source file + # is setup to wall time, and in the binary file isstd and + # isgmt are off, so it should be in wall time. OTOH, it's + # always in gmt time. Let me know if you have comments + # about this. + laststdoffset = 0 + self._trans_list = list(self._trans_list) + for i in range(len(self._trans_list)): + tti = self._trans_idx[i] + if not tti.isdst: + # This is std time. + self._trans_list[i] += tti.offset + laststdoffset = tti.offset + else: + # This is dst time. Convert to std. + self._trans_list[i] += laststdoffset + self._trans_list = tuple(self._trans_list) + + def _find_ttinfo(self, dt, laststd=0): + timestamp = ((dt.toordinal() - EPOCHORDINAL) * 86400 + + dt.hour * 3600 + + dt.minute * 60 + + dt.second) + idx = 0 + for trans in self._trans_list: + if timestamp < trans: + break + idx += 1 + else: + return self._ttinfo_std + if idx == 0: + return self._ttinfo_before + if laststd: + while idx > 0: + tti = self._trans_idx[idx-1] + if not tti.isdst: + return tti + idx -= 1 + else: + return self._ttinfo_std + else: + return self._trans_idx[idx-1] + + def utcoffset(self, dt): + if not self._ttinfo_std: + return ZERO + return self._find_ttinfo(dt).delta + + def dst(self, dt): + if not self._ttinfo_dst: + return ZERO + tti = self._find_ttinfo(dt) + if not tti.isdst: + return ZERO + + # The documentation says that utcoffset()-dst() must + # be constant for every dt. + return tti.delta-self._find_ttinfo(dt, laststd=1).delta + + # An alternative for that would be: + # + # return self._ttinfo_dst.offset-self._ttinfo_std.offset + # + # However, this class stores historical changes in the + # dst offset, so I belive that this wouldn't be the right + # way to implement this. + + @tzname_in_python2 + def tzname(self, dt): + if not self._ttinfo_std: + return None + return self._find_ttinfo(dt).abbr + + def __eq__(self, other): + if not isinstance(other, tzfile): + return False + return (self._trans_list == other._trans_list and + self._trans_idx == other._trans_idx and + self._ttinfo_list == other._ttinfo_list) + + def __ne__(self, other): + return not self.__eq__(other) + + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self._filename)) + + def __reduce__(self): + if not os.path.isfile(self._filename): + raise ValueError("Unpickable %s class" % self.__class__.__name__) + return (self.__class__, (self._filename,)) + +class tzrange(datetime.tzinfo): + + def __init__(self, stdabbr, stdoffset=None, + dstabbr=None, dstoffset=None, + start=None, end=None): + global relativedelta + if not relativedelta: + from dateutil import relativedelta + self._std_abbr = stdabbr + self._dst_abbr = dstabbr + if stdoffset is not None: + self._std_offset = datetime.timedelta(seconds=stdoffset) + else: + self._std_offset = ZERO + if dstoffset is not None: + self._dst_offset = datetime.timedelta(seconds=dstoffset) + elif dstabbr and stdoffset is not None: + self._dst_offset = self._std_offset+datetime.timedelta(hours=+1) + else: + self._dst_offset = ZERO + if dstabbr and start is None: + self._start_delta = relativedelta.relativedelta( + hours=+2, month=4, day=1, weekday=relativedelta.SU(+1)) + else: + self._start_delta = start + if dstabbr and end is None: + self._end_delta = relativedelta.relativedelta( + hours=+1, month=10, day=31, weekday=relativedelta.SU(-1)) + else: + self._end_delta = end + + def utcoffset(self, dt): + if self._isdst(dt): + return self._dst_offset + else: + return self._std_offset + + def dst(self, dt): + if self._isdst(dt): + return self._dst_offset-self._std_offset + else: + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + if self._isdst(dt): + return self._dst_abbr + else: + return self._std_abbr + + def _isdst(self, dt): + if not self._start_delta: + return False + year = datetime.datetime(dt.year, 1, 1) + start = year+self._start_delta + end = year+self._end_delta + dt = dt.replace(tzinfo=None) + if start < end: + return dt >= start and dt < end + else: + return dt >= start or dt < end + + def __eq__(self, other): + if not isinstance(other, tzrange): + return False + return (self._std_abbr == other._std_abbr and + self._dst_abbr == other._dst_abbr and + self._std_offset == other._std_offset and + self._dst_offset == other._dst_offset and + self._start_delta == other._start_delta and + self._end_delta == other._end_delta) + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "%s(...)" % self.__class__.__name__ + + __reduce__ = object.__reduce__ + +class tzstr(tzrange): + + def __init__(self, s): + global parser + if not parser: + from dateutil import parser + self._s = s + + res = parser._parsetz(s) + if res is None: + raise ValueError("unknown string format") + + # Here we break the compatibility with the TZ variable handling. + # GMT-3 actually *means* the timezone -3. + if res.stdabbr in ("GMT", "UTC"): + res.stdoffset *= -1 + + # We must initialize it first, since _delta() needs + # _std_offset and _dst_offset set. Use False in start/end + # to avoid building it two times. + tzrange.__init__(self, res.stdabbr, res.stdoffset, + res.dstabbr, res.dstoffset, + start=False, end=False) + + if not res.dstabbr: + self._start_delta = None + self._end_delta = None + else: + self._start_delta = self._delta(res.start) + if self._start_delta: + self._end_delta = self._delta(res.end, isend=1) + + def _delta(self, x, isend=0): + kwargs = {} + if x.month is not None: + kwargs["month"] = x.month + if x.weekday is not None: + kwargs["weekday"] = relativedelta.weekday(x.weekday, x.week) + if x.week > 0: + kwargs["day"] = 1 + else: + kwargs["day"] = 31 + elif x.day: + kwargs["day"] = x.day + elif x.yday is not None: + kwargs["yearday"] = x.yday + elif x.jyday is not None: + kwargs["nlyearday"] = x.jyday + if not kwargs: + # Default is to start on first sunday of april, and end + # on last sunday of october. + if not isend: + kwargs["month"] = 4 + kwargs["day"] = 1 + kwargs["weekday"] = relativedelta.SU(+1) + else: + kwargs["month"] = 10 + kwargs["day"] = 31 + kwargs["weekday"] = relativedelta.SU(-1) + if x.time is not None: + kwargs["seconds"] = x.time + else: + # Default is 2AM. + kwargs["seconds"] = 7200 + if isend: + # Convert to standard time, to follow the documented way + # of working with the extra hour. See the documentation + # of the tzinfo class. + delta = self._dst_offset-self._std_offset + kwargs["seconds"] -= delta.seconds+delta.days*86400 + return relativedelta.relativedelta(**kwargs) + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self._s)) + +class _tzicalvtzcomp(object): + def __init__(self, tzoffsetfrom, tzoffsetto, isdst, + tzname=None, rrule=None): + self.tzoffsetfrom = datetime.timedelta(seconds=tzoffsetfrom) + self.tzoffsetto = datetime.timedelta(seconds=tzoffsetto) + self.tzoffsetdiff = self.tzoffsetto-self.tzoffsetfrom + self.isdst = isdst + self.tzname = tzname + self.rrule = rrule + +class _tzicalvtz(datetime.tzinfo): + def __init__(self, tzid, comps=[]): + self._tzid = tzid + self._comps = comps + self._cachedate = [] + self._cachecomp = [] + + def _find_comp(self, dt): + if len(self._comps) == 1: + return self._comps[0] + dt = dt.replace(tzinfo=None) + try: + return self._cachecomp[self._cachedate.index(dt)] + except ValueError: + pass + lastcomp = None + lastcompdt = None + for comp in self._comps: + if not comp.isdst: + # Handle the extra hour in DST -> STD + compdt = comp.rrule.before(dt-comp.tzoffsetdiff, inc=True) + else: + compdt = comp.rrule.before(dt, inc=True) + if compdt and (not lastcompdt or lastcompdt < compdt): + lastcompdt = compdt + lastcomp = comp + if not lastcomp: + # RFC says nothing about what to do when a given + # time is before the first onset date. We'll look for the + # first standard component, or the first component, if + # none is found. + for comp in self._comps: + if not comp.isdst: + lastcomp = comp + break + else: + lastcomp = comp[0] + self._cachedate.insert(0, dt) + self._cachecomp.insert(0, lastcomp) + if len(self._cachedate) > 10: + self._cachedate.pop() + self._cachecomp.pop() + return lastcomp + + def utcoffset(self, dt): + return self._find_comp(dt).tzoffsetto + + def dst(self, dt): + comp = self._find_comp(dt) + if comp.isdst: + return comp.tzoffsetdiff + else: + return ZERO + + @tzname_in_python2 + def tzname(self, dt): + return self._find_comp(dt).tzname + + def __repr__(self): + return "" % repr(self._tzid) + + __reduce__ = object.__reduce__ + +class tzical(object): + def __init__(self, fileobj): + global rrule + if not rrule: + from dateutil import rrule + + if isinstance(fileobj, string_types): + self._s = fileobj + fileobj = open(fileobj, 'r') # ical should be encoded in UTF-8 with CRLF + elif hasattr(fileobj, "name"): + self._s = fileobj.name + else: + self._s = repr(fileobj) + + self._vtz = {} + + self._parse_rfc(fileobj.read()) + + def keys(self): + return list(self._vtz.keys()) + + def get(self, tzid=None): + if tzid is None: + keys = list(self._vtz.keys()) + if len(keys) == 0: + raise ValueError("no timezones defined") + elif len(keys) > 1: + raise ValueError("more than one timezone available") + tzid = keys[0] + return self._vtz.get(tzid) + + def _parse_offset(self, s): + s = s.strip() + if not s: + raise ValueError("empty offset") + if s[0] in ('+', '-'): + signal = (-1, +1)[s[0]=='+'] + s = s[1:] + else: + signal = +1 + if len(s) == 4: + return (int(s[:2])*3600+int(s[2:])*60)*signal + elif len(s) == 6: + return (int(s[:2])*3600+int(s[2:4])*60+int(s[4:]))*signal + else: + raise ValueError("invalid offset: "+s) + + def _parse_rfc(self, s): + lines = s.splitlines() + if not lines: + raise ValueError("empty string") + + # Unfold + i = 0 + while i < len(lines): + line = lines[i].rstrip() + if not line: + del lines[i] + elif i > 0 and line[0] == " ": + lines[i-1] += line[1:] + del lines[i] + else: + i += 1 + + tzid = None + comps = [] + invtz = False + comptype = None + for line in lines: + if not line: + continue + name, value = line.split(':', 1) + parms = name.split(';') + if not parms: + raise ValueError("empty property name") + name = parms[0].upper() + parms = parms[1:] + if invtz: + if name == "BEGIN": + if value in ("STANDARD", "DAYLIGHT"): + # Process component + pass + else: + raise ValueError("unknown component: "+value) + comptype = value + founddtstart = False + tzoffsetfrom = None + tzoffsetto = None + rrulelines = [] + tzname = None + elif name == "END": + if value == "VTIMEZONE": + if comptype: + raise ValueError("component not closed: "+comptype) + if not tzid: + raise ValueError("mandatory TZID not found") + if not comps: + raise ValueError("at least one component is needed") + # Process vtimezone + self._vtz[tzid] = _tzicalvtz(tzid, comps) + invtz = False + elif value == comptype: + if not founddtstart: + raise ValueError("mandatory DTSTART not found") + if tzoffsetfrom is None: + raise ValueError("mandatory TZOFFSETFROM not found") + if tzoffsetto is None: + raise ValueError("mandatory TZOFFSETFROM not found") + # Process component + rr = None + if rrulelines: + rr = rrule.rrulestr("\n".join(rrulelines), + compatible=True, + ignoretz=True, + cache=True) + comp = _tzicalvtzcomp(tzoffsetfrom, tzoffsetto, + (comptype == "DAYLIGHT"), + tzname, rr) + comps.append(comp) + comptype = None + else: + raise ValueError("invalid component end: "+value) + elif comptype: + if name == "DTSTART": + rrulelines.append(line) + founddtstart = True + elif name in ("RRULE", "RDATE", "EXRULE", "EXDATE"): + rrulelines.append(line) + elif name == "TZOFFSETFROM": + if parms: + raise ValueError("unsupported %s parm: %s "%(name, parms[0])) + tzoffsetfrom = self._parse_offset(value) + elif name == "TZOFFSETTO": + if parms: + raise ValueError("unsupported TZOFFSETTO parm: "+parms[0]) + tzoffsetto = self._parse_offset(value) + elif name == "TZNAME": + if parms: + raise ValueError("unsupported TZNAME parm: "+parms[0]) + tzname = value + elif name == "COMMENT": + pass + else: + raise ValueError("unsupported property: "+name) + else: + if name == "TZID": + if parms: + raise ValueError("unsupported TZID parm: "+parms[0]) + tzid = value + elif name in ("TZURL", "LAST-MODIFIED", "COMMENT"): + pass + else: + raise ValueError("unsupported property: "+name) + elif name == "BEGIN" and value == "VTIMEZONE": + tzid = None + comps = [] + invtz = True + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self._s)) + +if sys.platform != "win32": + TZFILES = ["/etc/localtime", "localtime"] + TZPATHS = ["/usr/share/zoneinfo", "/usr/lib/zoneinfo", "/etc/zoneinfo"] +else: + TZFILES = [] + TZPATHS = [] + +def gettz(name=None): + tz = None + if not name: + try: + name = os.environ["TZ"] + except KeyError: + pass + if name is None or name == ":": + for filepath in TZFILES: + if not os.path.isabs(filepath): + filename = filepath + for path in TZPATHS: + filepath = os.path.join(path, filename) + if os.path.isfile(filepath): + break + else: + continue + if os.path.isfile(filepath): + try: + tz = tzfile(filepath) + break + except (IOError, OSError, ValueError): + pass + else: + tz = tzlocal() + else: + if name.startswith(":"): + name = name[:-1] + if os.path.isabs(name): + if os.path.isfile(name): + tz = tzfile(name) + else: + tz = None + else: + for path in TZPATHS: + filepath = os.path.join(path, name) + if not os.path.isfile(filepath): + filepath = filepath.replace(' ', '_') + if not os.path.isfile(filepath): + continue + try: + tz = tzfile(filepath) + break + except (IOError, OSError, ValueError): + pass + else: + tz = None + if tzwin: + try: + tz = tzwin(name) + except OSError: + pass + if not tz: + from dateutil.zoneinfo import gettz + tz = gettz(name) + if not tz: + for c in name: + # name must have at least one offset to be a tzstr + if c in "0123456789": + try: + tz = tzstr(name) + except ValueError: + pass + break + else: + if name in ("GMT", "UTC"): + tz = tzutc() + elif name in time.tzname: + tz = tzlocal() + return tz + +# vim:ts=4:sw=4:et diff --git a/lib/dateutil_py3/tzwin.py b/lib/dateutil_py3/tzwin.py new file mode 100644 index 000000000000..041c6cc3d645 --- /dev/null +++ b/lib/dateutil_py3/tzwin.py @@ -0,0 +1,179 @@ +# This code was originally contributed by Jeffrey Harris. +import datetime +import struct +import winreg + + +__all__ = ["tzwin", "tzwinlocal"] + +ONEWEEK = datetime.timedelta(7) + +TZKEYNAMENT = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones" +TZKEYNAME9X = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones" +TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation" + +def _settzkeyname(): + global TZKEYNAME + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + try: + winreg.OpenKey(handle, TZKEYNAMENT).Close() + TZKEYNAME = TZKEYNAMENT + except WindowsError: + TZKEYNAME = TZKEYNAME9X + handle.Close() + +_settzkeyname() + +class tzwinbase(datetime.tzinfo): + """tzinfo class based on win32's timezones available in the registry.""" + + def utcoffset(self, dt): + if self._isdst(dt): + return datetime.timedelta(minutes=self._dstoffset) + else: + return datetime.timedelta(minutes=self._stdoffset) + + def dst(self, dt): + if self._isdst(dt): + minutes = self._dstoffset - self._stdoffset + return datetime.timedelta(minutes=minutes) + else: + return datetime.timedelta(0) + + def tzname(self, dt): + if self._isdst(dt): + return self._dstname + else: + return self._stdname + + def list(): + """Return a list of all time zones known to the system.""" + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + tzkey = winreg.OpenKey(handle, TZKEYNAME) + result = [winreg.EnumKey(tzkey, i) + for i in range(winreg.QueryInfoKey(tzkey)[0])] + tzkey.Close() + handle.Close() + return result + list = staticmethod(list) + + def display(self): + return self._display + + def _isdst(self, dt): + dston = picknthweekday(dt.year, self._dstmonth, self._dstdayofweek, + self._dsthour, self._dstminute, + self._dstweeknumber) + dstoff = picknthweekday(dt.year, self._stdmonth, self._stddayofweek, + self._stdhour, self._stdminute, + self._stdweeknumber) + if dston < dstoff: + return dston <= dt.replace(tzinfo=None) < dstoff + else: + return not dstoff <= dt.replace(tzinfo=None) < dston + + +class tzwin(tzwinbase): + + def __init__(self, name): + self._name = name + + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + tzkey = winreg.OpenKey(handle, "%s\%s" % (TZKEYNAME, name)) + keydict = valuestodict(tzkey) + tzkey.Close() + handle.Close() + + self._stdname = keydict["Std"].encode("iso-8859-1") + self._dstname = keydict["Dlt"].encode("iso-8859-1") + + self._display = keydict["Display"] + + # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm + tup = struct.unpack("=3l16h", keydict["TZI"]) + self._stdoffset = -tup[0]-tup[1] # Bias + StandardBias * -1 + self._dstoffset = self._stdoffset-tup[2] # + DaylightBias * -1 + + (self._stdmonth, + self._stddayofweek, # Sunday = 0 + self._stdweeknumber, # Last = 5 + self._stdhour, + self._stdminute) = tup[4:9] + + (self._dstmonth, + self._dstdayofweek, # Sunday = 0 + self._dstweeknumber, # Last = 5 + self._dsthour, + self._dstminute) = tup[12:17] + + def __repr__(self): + return "tzwin(%s)" % repr(self._name) + + def __reduce__(self): + return (self.__class__, (self._name,)) + + +class tzwinlocal(tzwinbase): + + def __init__(self): + + handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) + + tzlocalkey = winreg.OpenKey(handle, TZLOCALKEYNAME) + keydict = valuestodict(tzlocalkey) + tzlocalkey.Close() + + self._stdname = keydict["StandardName"].encode("iso-8859-1") + self._dstname = keydict["DaylightName"].encode("iso-8859-1") + + try: + tzkey = winreg.OpenKey(handle, "%s\%s"%(TZKEYNAME, self._stdname)) + _keydict = valuestodict(tzkey) + self._display = _keydict["Display"] + tzkey.Close() + except OSError: + self._display = None + + handle.Close() + + self._stdoffset = -keydict["Bias"]-keydict["StandardBias"] + self._dstoffset = self._stdoffset-keydict["DaylightBias"] + + + # See http://ww_winreg.jsiinc.com/SUBA/tip0300/rh0398.htm + tup = struct.unpack("=8h", keydict["StandardStart"]) + + (self._stdmonth, + self._stddayofweek, # Sunday = 0 + self._stdweeknumber, # Last = 5 + self._stdhour, + self._stdminute) = tup[1:6] + + tup = struct.unpack("=8h", keydict["DaylightStart"]) + + (self._dstmonth, + self._dstdayofweek, # Sunday = 0 + self._dstweeknumber, # Last = 5 + self._dsthour, + self._dstminute) = tup[1:6] + + def __reduce__(self): + return (self.__class__, ()) + +def picknthweekday(year, month, dayofweek, hour, minute, whichweek): + """dayofweek == 0 means Sunday, whichweek 5 means last instance""" + first = datetime.datetime(year, month, 1, hour, minute) + weekdayone = first.replace(day=((dayofweek-first.isoweekday())%7+1)) + for n in range(whichweek): + dt = weekdayone+(whichweek-n)*ONEWEEK + if dt.month == month: + return dt + +def valuestodict(key): + """Convert a registry key's values to a dictionary.""" + dict = {} + size = winreg.QueryInfoKey(key)[1] + for i in range(size): + data = winreg.EnumValue(key, i) + dict[data[0]] = data[1] + return dict diff --git a/lib/dateutil_py3/zoneinfo/__init__.py b/lib/dateutil_py3/zoneinfo/__init__.py new file mode 100644 index 000000000000..a1b34874baa3 --- /dev/null +++ b/lib/dateutil_py3/zoneinfo/__init__.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +""" +Copyright (c) 2003-2005 Gustavo Niemeyer + +This module offers extensions to the standard Python +datetime module. +""" +from dateutil.tz import tzfile +from tarfile import TarFile +import os + +__author__ = "Tomi Pieviläinen " +__license__ = "Simplified BSD" + +__all__ = ["setcachesize", "gettz", "rebuild"] + +CACHE = [] +CACHESIZE = 10 + +class tzfile(tzfile): + def __reduce__(self): + return (gettz, (self._filename,)) + +def getzoneinfofile(): + filenames = sorted(os.listdir(os.path.join(os.path.dirname(__file__)))) + filenames.reverse() + for entry in filenames: + if entry.startswith("zoneinfo") and ".tar." in entry: + return os.path.join(os.path.dirname(__file__), entry) + return None + +ZONEINFOFILE = getzoneinfofile() + +del getzoneinfofile + +def setcachesize(size): + global CACHESIZE, CACHE + CACHESIZE = size + del CACHE[size:] + +def gettz(name): + tzinfo = None + if ZONEINFOFILE: + for cachedname, tzinfo in CACHE: + if cachedname == name: + break + else: + tf = TarFile.open(ZONEINFOFILE) + try: + zonefile = tf.extractfile(name) + except KeyError: + tzinfo = None + else: + tzinfo = tzfile(zonefile) + tf.close() + CACHE.insert(0, (name, tzinfo)) + del CACHE[CACHESIZE:] + return tzinfo + +def rebuild(filename, tag=None, format="gz"): + import tempfile, shutil + tmpdir = tempfile.mkdtemp() + zonedir = os.path.join(tmpdir, "zoneinfo") + moduledir = os.path.dirname(__file__) + if tag: tag = "-"+tag + targetname = "zoneinfo%s.tar.%s" % (tag, format) + try: + tf = TarFile.open(filename) + # The "backwards" zone file contains links to other files, so must be + # processed as last + for name in sorted(tf.getnames(), + key=lambda k: k != "backward" and k or "z"): + if not (name.endswith(".sh") or + name.endswith(".tab") or + name == "leapseconds"): + tf.extract(name, tmpdir) + filepath = os.path.join(tmpdir, name) + os.system("zic -d %s %s" % (zonedir, filepath)) + tf.close() + target = os.path.join(moduledir, targetname) + for entry in os.listdir(moduledir): + if entry.startswith("zoneinfo") and ".tar." in entry: + os.unlink(os.path.join(moduledir, entry)) + tf = TarFile.open(target, "w:%s" % format) + for entry in os.listdir(zonedir): + entrypath = os.path.join(zonedir, entry) + tf.add(entrypath, entry) + tf.close() + finally: + shutil.rmtree(tmpdir) diff --git a/lib/dateutil_py3/zoneinfo/zoneinfo--latest.tar.gz b/lib/dateutil_py3/zoneinfo/zoneinfo--latest.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..12eadffb098afd7cc74615e72f7480c4d043c4c3 GIT binary patch literal 86784 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 literal 0 HcmV?d00001 diff --git a/lib/dateutil_py3/zoneinfo/zoneinfo-2011d.tar.gz b/lib/dateutil_py3/zoneinfo/zoneinfo-2011d.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a8c96074d8a27427eb8b0d282a1de220e8278bbc GIT binary patch literal 197294 zcmb@thf|Z=7cLAaMe0wHj$k>8fPnN4Dk{f9QIIMiVCY49sG*36w1XOuE+S2uAVqpp zkWd0jk)DVl2tq;+HQ&me`R4uucZSKVckQ)T*?Yf){X7fNI2INHDo&4qD&yqoj*#(i zMz|va5#BOB-u5z&ZG91bzRqs{R|xX-Ksb9ic*^|$f|T54S=qwK;4^P{JKb}V&7vdv)Il_1sD z+iQ?4+A?!UPfye@GEADyX3~G;HtgVF%KA5ZD%RK8Ucj4PscQL>3nSpT5mzh9BCrl7-aJibkzF2Ivx{-%Kdk<7CUgKR}?7lUjsN3K) zCZb+qRo9g5-<+RxKJ2}Iqit1xmF$N^gwe*$JCV872%jfx%e+}#RU_)7RZ<78y<72T zQkG?~mi`(h)#@^>-&Yz&?=}WcsxD`9%w7t1^cb}u{{FramytU?t85;8`hC*Yqp0&K zIuTMeF}*84M2^)vsd_8c5Rjv1=jY_pGYm3&T=oB24TN|{*=ZrzhccCBWhWbIWOHH% zKB%sLwe(T?m9h13?^nutyZ>@@(~cD1hkr6;rm9?}M=kT3DS9;zr8Tbx@BC0$9`U_5 zQDTteTrrJxs1N(~daJA5ASL6N!KJ!U#K=V91q%<|vFfSV_@Nnhvkvcy%5m>m^)kZM z=$eU``WLRE2oJZwjq?dxUfx{GuS&2r2A&GvwI;nR_CkI*_Qs71Rm(8PSiael!^D zy4>Q+xtGz>trzED;(X^BlgXVfEx|h%DsH6oovDyAXVp@4rx@6srntj<)1}(#o#GDj*vQGEA7)0EhmDMi-nSM! zDVvx->-@>}Mao5l^zOje!zroedP;QZ{D~x+G|dxQ>32lb9i)utQ@8n z1RSP2ue~r`k`yE@98EBY&Jvt`_Cql&aNc>pc~0T5CrTlrz99XG=TjF(@TYrAv%t^*>Pm{oPn{e^A(1(cEZy=S}_1 zcFS}@84;(*k%O94v-vhhML9)oW2^|q;( zee%Mk=ezt|-ef#3arCgL`dt5qIZO4QJAQiK^5f^{NiUo&+yY%a0^9X|U|wGRp@vT@ z=zpu6UTb9F9PcjUbd6auWmDtsPrqHbm?LK}8dnVfRww z;tM$}XIibgbMEY@-}|#W7geXMo$W}GuFEVl%6UZi`4qG8m_T_&_|%p3?# z4g{nF;kg6hjRT>`f$-UZ@Xdkn^BHErfk1H}us9O<9SIj52`Y|+e;o;Cjsz!10@9K2 z+>!9ckx=AF`0Pmd7K8ceNLYx$P#g)oZ5a1(v?aY{-4PRyW2IBPX7!3!5W$ZKyzLnG zNVFxRWF1?Pn}FfCl3Bgq6~rD4FreL^qAiaZ*K(V9h?h>8nAO*O^bWQq@OEO{pP?-| zBu(8QWS>w8^--VwB;GeIvo>_*yk+cyyo?aRo=mm3A{ZR_m^nP^OALUOgz#`r`0828s`OL56MBNLBesKva#24)}#yuBFr6ttz3WSymnM?KVHUcU)5qA|RE z7HleeWKVRQhqoQ1a3kgN+d@z^Y#S~0IDzzi6`VwQ8z$HURG;plsG5?~qtKO6=%Fa|Y83kTQ?%?;^u4EOuczqbqr2Z$XH$os zqF0}yk4K|rqtW-G(O!&_7h*4!#!HpPOP9vWl*V5!jh8KrmorPgm1&E3A91_X7Ev8> zyU7;u#TL=OxYrS+amtjA~w#f>WVJfh;VLWsoGf&54Yk5q+7TD-P}X%S7?6L zp`JcfXcKHuPu@^|aorDmQR${jO$E@zSr^cfU{X z*7#we`&E4CJG;Z*_WOsMqMn|fqB*nH)Kxa}?fS!Y?h2~P0piB{i>un%g<5Lo+ru_| zv?nVoWR|;=G^(;xDhJ*mOFl3EPM_Q|ikY3zH~8yRSN7LlUB1srTiu}ypNtBg%d5+0 zH~8+RtX2Q0S~GM@_0RZxIcEJw)Jy9=WLZ=E>`C-+;m1EC@0o8^SSpy#Z1f3i)=sJX zXuQDoZid+ZXcvc4`qR06nqcIgT4Yd{B$=a)zO`GWJ-)Fyk^TO6zRulQ|K`M9ExWjP zeKMK^a!Nl{IY01C z=4<~>tyg=p6-BCbYsSXej4iikq~cz!rFG~{2&BGSiy64by5Y|A z;A6Up_;9(CF}@?=?hTCSbBRT{`{F6Y(EF7!>UYn-4!d!_LWX4mGAJJrpPx20@9?L3(9*bbOMfE2T^-d^J3DLfJ=)H?#AYR?C_!j`zLI86LB)e_&vV7AgDtpjWx_fve$=$ZOeg z!|6M&6&@tFqO^#=iggYj8O5eQjS03+8}5C$JbG-}y+mH^i?w5qqt5hlK*HuTE9K!F zzi&GR^FviA7E=r4Wu z;NF@Mx3aC&syY#yFQX3kf`TW@%a!JSzU&$-h~`*6`$J%IuTajn2>qD7ckSn3?6S<i9Wo9(=cB$qEy#ULk>@!;n zFF4#Zh0rzKzc(v4C1(5hGcb=9vKr$nw{<*qrp6w2Y3a%d?ONYa+Opi58AK7K=E9Gs zavUN4mFHai+)0k92;P6ibsx2T<|O(sKjymEsXD8AH?PCZ^|zJzK8GIm5! z(WaZ}>vQ$$6`4$b%QMCOqjt$gJ!~jJ`>54&wiqaof{0_f}sv07+wOyC$=}*$X#bT zGuQ>M{Kqb2!YRDJgc-c*g2A0`sVY z)%Y2=$y>R%;U04DKQf@NM)MT0OTvUlwu}-wY?6io55bHKW=#BG_JwA`gtmQ#E@W3I zVpjyik6_rz0ftY&@V`!0-?%xF&reVu;gTF2RHgWEYL#9ov2Bm1`vS2}gANOp?aWB*D=musst8wiaOf6Ks$0fo+3XAO`mpWAsc0Ou}g<@nB+i zC6(PC%ueedE`IX9tbxk#} z=Ov|&Y6b#4RKAu2xFiYMW_XQz=CWO#5 zEFe6kX+ZF}=`GLE7%|6Djym2g^xalw-w^9g?))J2R5UwGY5(~(9lUPSUoLHoID6Re zA0=`gX(U|qlQoz2)?;R2&#Asql^IIS2wv>VgUB3}7XBvHf3)}CmwS+39eF?z_secK z==T>5OK+9j(zasxi@KR2Mwb5@fOl-U^E3ycc~pC^Lye-ELLmDnXW)rxH#@O8yd14< z{Kq^6RE~FB@@uemTMid6@BjLhxNCO5^7#JuVLx0dVKd5R>$AfCn&&vqRQN|*MaV+b zLB)jGi9MUpf7tfZd;Z|Yr1$7r%XLre?;bbB%?V{j&klNt?cc08O3@o3wu?P}!`V9S z!<<;RvwlI?({;C=Y+0cnHM`|~dVlLwGd>_wse_a`EgUwsD?x7DONpA5ul(Qs3~wN= z%qvLP(`H0YW#;fd1~N12e55x2!co-omv}D6U^*0KK#FosG_gZ;x|Qqj&4JbyDr8gd zFZJmrOUN%X$^Bcsw<$)+aX5pFu8v6;t|)E$zpSXyymR}ip`ny@XO|9}iz2aeR>(>E z?#9;*();=ABX}9@t*5Oo4cQMDE7{3o1r6;sHmgjBH?fXnWii)}RLe3Wd+L@*1>Q3i z#fmCy52Q5K8+6RBPcWcJOF&B)s1QH3#O=p_t_zd?B&tvx zJA>P_bEX*%Z=iKXtVc*D7tnnlt66wO@DU9KLl-v6AohZ#(tVgD7cH1H)xJ z*=00>tS^Em>yr}5($0~1D`}GmgU#V1Gk$l@P=>{(@Y4m2ZH2ckws&(oGxK~|ohmGd zHW(Wf&Vi|Z-Yw3E$RX!K}zZ$(MW91ja?xJ=PdJD)`6 zkru=IHz{ZJZE$g!VQe-VGaMAVC7BLB?VV$LGP3K6TcpY@!H}NM>*V|{(leP;Rg5#A zmKcy$xVy-ThA4dVr|sx%@ez?3qP--twe*58mgFxgjHQOEQ^G@~@JD1!qGUdOWC$6T zx`FHE7+|&uYmf|yHl(+y9OI_k-fblB)=H~b6MoHlHA(P@wwvmO3bk0w%#lY#M8mmu zYnfVhEAz>U9{S-G_1^!4kdsG#qRM*ie56kFc6W}&iqP8xJPx1)aj3VCae2~tlFJ!q z-#+6C>5M;*7vkw>m|gHwqg)V_5w7T|IiX_x;~#RCQ!RIh*fsqq()IOmocfTRCPlyc zFIx+D*@Z~b^(9_VUEmB6n=oOVJ!a2B(SOQ&bT-yM0@T)wv$34x?E&vPt;ks{dn_&7 zr?|pN*C`0ikixGB+_|j?(siO2PW^cO|3btXe2;~b)c8Rd>7k$1JQ*VPPNSu5dl16< zrVEiZYhv)hTGMQ^l8Q+E4K=Q8?#iTgpLYQaNc}ITj$mW8jNplMo1D48cO;wpKsSo` zCA5%$ni{ZpC z9d0<)%5O(B#CV&Tv9af!VXWr{In!+Sq=s0EJ3Tg*AjaES@kWa;3;|`A3LeeoE-8e- z>9sIViAh6j^Z^4lb~B;f=d6|}Qs0dXxp2%vo<{S($Qd3y;RgRQVPpGsLDS1Y&ivT` zb<{3{YB>)=bw31^0B1IL<8DsmtkoRLezwUfIXJHTX&qAp@rxD*Qva_E)VlYo&F9x! zd8EE@HK=p7C4|(^lz@FHT#6t* zm12e`@y%n0ecfYZ;#5U@PGgA3;eIeV^Yce84KZnJSo%9`?LNQOctIt{uOU{h59{HY z3!XIn|F@rj@ggfvLfvI2aH_TyunKk4kdnR@Sg#+|5L*cY>)>v1a41F2M1Ew|5EEJP zi$E#ts_)P7;8a)Niy`$jPBCV4V+Fy>`V%n1b7XVNxP}w2-@ge@4}5v{OUB~xv+o6& zsq=rIQ0i{MG!K~8R0lQ3sKS#h)U34$ClBjD&ZK-lp&{0CGq7DORg#`sri#=LkvW=u zE}tEl_>>!&c##>IxFCW|98SWidaKc8pCk72;jDObA`NQXC7YH8k(6Pm_xC8HhORSH z6!D__DY9^VOeFE5)h)7ceg%8>IXw%qFyh-Rt5)Zy3*@w^HlNpj7?6o_+Vt3aDg8KA zOpvgK?s!22@#3BYS(vcEn4Ont4@M=j$V6}5sR-;`Fo%|>4h;1k$v#)6j7+TV!Kq68 zcU(i4(IcE#gmWbe^GtAL=XE%?`xrllR9|?+hs!9vJr%MF#Yzl;p~yj-k8zb6GVylJ zQS7}xXK|`)mzcB9Ww9X>o4g~4-ZOd=%u`y5_!6w1hl!~Z??C^q@<2r}`*d$2*@!Kr@OW!KOh zsfDGu2q}y>Latp7WZ@A7C>1G)Omq=>Y&_3!V&DfP#dtJa%Sf-rEPa8 zf3D$Zv6Vw63Z4S5b3!;(mnsGgUA=%PV$t|TvT$@C%vje4wJe>6u9RyevFO3lY0BtV ziH^Er@KGz!=JWUxL-x5jNwRQ_59Hb?55`n5KBW{+y!iKj$V9dDcAt|iP;b^QXzXBb z)RdXA_Z};gh5f{jWapJ{w)qUh!B1>RWy0RuHo&PaCQGxnbfZ})3w#{-V2=t8QJ-TP zy3M>$n7<@4F^CJ|OtF)NH=UWY^IDqQeTFMok%_y?2Xxw}Q787VXd)At^69b3;-bjJ zy9RAO3KVr@;xl1p?9iYkPF1j$RYSLPdmuto)YISFS7bUP#fvP2t!yv z%1v@`2n-Y90G6h~el{P=&I|Pf4T=ky$e9TRwC~_l)v8y8_VM(hxTHQt?9k8?vhb-T z$Y*Y(-N*Occ?cL6PF#4bN*2!Yh7f-q!i)nr2DLJsc&xAp3u+6>9Vml6*nx5zF2j-K zONANt1IWTwB2a=p zz()p4c3!Z2n~yJw1DPnY!Gs;^bjGO$JwA#ZnzIJs9R&Mv0fYib*hiZz+-%t9vmpmB zrS(L+&+Cl=(L?kI_u-}~sb-^&~p@2-B!NSZK7P4@tFkN<@fnvMQM!h03vE?L0 z9$Unz-W~w8=MAu4=0WN|c-ZFi!JA2=@C7qY6%D7}c=Iw+-!J`Wwoz7UbVuWc6Mc@$ zS}3IA6q&ZRDeL1Y2Cs8crOZ3W7l~_&(|{ zVZ;^(=0p;W%fO&Utj)(IOdY8&^-)lxkheOLIDE|>9NONwKslT2jE_r%I9~-JhhN8W zsx?n#koucNkk%as25fQu3y6Oo4#bB-NziLBXB+v!`TsB`4atW>;k$4mid%$0WrG5h z_A!k@rfQfNp$Spb*1(}#)C)4fo4GAjhArDjQboDyV6~?lwU(=Pu%gpZk-qkC;Cqe3 z6`gx)!|fG*ehd}xXC!r36)SY;@(!PROQ-I&a|f#1q{ira>Se4p>QJT)OCmKNa?g3U zh8`5|zZ{i89Fk@?X089n~jVz@_ zg>%wo^23=QdVhMAC>m9oSdpn1&55fYq)`Fi`7W;CFum-QUt^dk)X)*}qJ|~(h0NM+ zUd;kJy1`DA(;|*Ed&=h5ce#@8cZ{p&>k_L{1m#p(HsS|Nu>Q+)eg(-v6%tohXS!IL z4WjR;*@U_`+oZdwp|;(3=~CHNBW?$U;*ObGrFDypR+VHgU{3kerHH;ND*5;;zs8Q} z*Kj*;z-%)ivD`0i1HkCA% zkEZ=EblLrONEQcT)6a1#wnACFt|hGGlA6x!71tGk$f8(|&^8p?UmY34FXT7P`p(VCQep$*`6nXyet1VytFE_}3`mkZp z-*(qOe_~<6v^bZ9D<6vvtgd^eDf5=ifcr6r_Mi7l8`VXMc5zBA>#@V5-~ODOMT{7^ zj#+R2YSi-^3Gnn*(fUB-4&`d)Ssh9^v8nkfJ~nC9yfA5}_90(JPia!Ks>RrzUbU8o z!TWOT=CRS1^`*t#88ww$n01m^SPTQJ&CDTFsvO{ z@=MPamHyM@YiPpF#D%zFOa8Bf6?N5w_rmM)?x=*v(Y9nm6M@9Dk{nSnRTGzy7bOSo zwXBdI1{#`&@@u^2d7j$RBXRU`&+RX`+|rxuBA6F6;Wh{unxGE?>sJu&gK(QBn9yu! zf(6Yc8ngKI&dg&*9R!a(1d@Xk6lsD22oGq25(s`YK?MXfO;7`&h9+o$FhUcwK-knl zFg&8WS3n2y30%IX9LJR+x#N(p5q(sQoB#+vXu=tqh9Otx6$3m-!2@^a>dU%2Kefe} zVPeoDvf%|5CQif)T)v0gt+#S|Gz&&BeE`BMnqWoKFoA%eX=s8wO~VX=-{3T24LlTZ zfh&fq2v$5eiG3@VKr=W7258z85GKhIbkW?bQP1S^FFRd)MH9+E;AR7%hNhtj&4ccb zBW(u_3;3Bh5HGJH(m}o;XuWp9hyzB)!R!Z3z=L4K3Bn(mh9<1iG+ZF;&@?oGUKTX} z1L0V%9LMT?<+SI9X)pK{UiUn|s*{!o!m(HoUV?CoCZvQPO?v|m#k7Y^5dOr}YX z-n`sL;Mpg4m_KR4a}Bg7`R>wbuaO-n_qNO1lB`j@-9kQ3#P)y29wX1C^hJrzhN|s9 zU7f6?#%|8x`mKm<25WBg+Vv}R6!CHUN@{WbM2EovKZEvkv)ukhF9PqVA;Y5WW9dOL z=i5}7`71DsBf5#xY1h@A3Y+m2qwI7&7WTYa!A#~okfKEEC3eVsUx~7LxGJ*MdflA8 zRe@wn$=|}0dt1uFZ9F()Y`lEf_c3T4ucimV4Q&-7rhu$}Efmhjo}x28hvTx^ zjM3h&WZX|alJJq5m)hGYYWbHL6=G>k;nw-oE;e9{GpOA=igJ14Ax!c`yONdWlqvFz z{+&4^lXz@?edJu$*h-8x)mLo)2IAQMSMGJ3jOI+tfsM5$%OR%nE7`RBS%;0Ks_yiUBQlF~0^-PuU|a?1mpCv$MyY|lfM!}0(QVbY2vA7xJ5NrB82 zpl(Y|8qkPAX>8N)zv3vw=WJ=SQr*5YQHW(G?X3&Jtlh!pVZtHzdt zJU8WV$l1xzTD!rI!x_kj>BZisvZsbxpISWPYT6BvZ1PEW4O-|iCrcXybQW4na?Nah zVW15Ea9q6X^f~BqNcztfvU7KBOn~PEtCm&Y>A%{|s2fPVIYSD&d8NupfzXl;$9-#& zJ#1$E<&b&HK>VjBJ;oeAncdWH{wuN}TRRIjXS+T4gk^|rQRMo0tw`*&gFs03VK;t# zR3&_l;9A3EZRsl>a=6BgV|y=n%;qCm;%_UilZDbTFo$CkE#|QK9i~iq*L$a(PaST} zU*Y0-&rTevkGvj1yxxOP!{33M&O2Xa8DZ=XZVfSCxU+OfYQlIb1NImR?ymSHfCpMq z+kHAnaK)u~!tFQwl@IQSV66?GhDhyTB3;8|KrgR`!EaGgDDNKFwu9>MQ)Kd9ua!9y!yA0w|AQAvoxQ`|G zPfHETy{_#VKKB)hcz$amg5)QpA!auQI0I=8rYrMmi0zg_+AYaA)gey>K(;&qVL5UZ z;F!1Y=P5fY6989$FYrGMIlhmp1AIy09H=z`{_3;_7>oS0mV9miK#XsJFy;bd@gj8D z-1Zk>?B^(`%3+=3D?r5!m$ffnGypJ>X3plGui(Oo5g~977lgt%0xlKAq9Imb^>z2o zT^rVHZh20?qx$gR!BrNi-^U3%t*QgKk%uOjjzQJ)aF2~;d;mw`CG0sbuN!+SnGvaf zNuMp7JI(+=l9!GEO8HtbQ4p~pgur%{ngIeN84Rg?s0395oV?OMfWo*QfMY9r0J?Hu z6@P^Se06xhPDw}u^&B8LKQ~~RPHaK`^XpN#x=XM-Wyf;KlQdLn3+k@Sa}T6s9f3kj z^P9+xmJlG@4%Br3l9^e76B`jnN+=iLLE&tGTB$H(b2E!VdAWo=JeMde!Z}!Bl?FJY zi8sLID!v3~zz+vU)=hZ-7F?UNd1RtaBxg@vO8^-VA|LbgU(qeSXt$D$WIEc5Fgn9ugdb1++UuA z8AQ0ZOie?eZ4YpA5G_mQqE*}}3s932J>XR%LpG42F_ zM~zKGw^%)#_^m8SJtW-)E{&6%8oDctaPce$a-`6)XY30#j?{!@V6srMX zrao5yrx3FzDW!8Dxbq+rs{#P;NQ7!J=G}BTC2+a--UBGaKngIceunJ4kn>o@@SsCovdB4g45;_ZDln4(Exq|Ea zZ2|=O;|t(q!R3B9Q$O4Z`AzB7P$Rq7;$}SeB>b|C*?9H)gy96CUZ3h0y|V zd#@Vt(u~CTK_P(#WZ?%zpn3tfS>xi<$V7=|P$S@;|3C{a^AcEy=m*(;I1kX3Q^!Th zB2;Xg2f&+4B4qnS9`LEf6O1)X$#1g9ysbofFlxpcAow@FdTyMEcN-AqzxEKh3os`2Ur4S zsMqgK!!c1bKwS5fBtwz_>wYl<8D<04eNrCILGx%?c+xV&n*p@qa zg!My)t#klb9R-xT!nqy0pL}3G~nt62o8W_klPLLx@Ler$(_*9 z&4c&c$rsK+f^#runA^J!Sa#%Fcq-QxBEE>A6lwktq9w1p+ zP_?sUdZz&iCI|p-t?=nMGSOj^4m;$QQ%d#`gmgSS$in^WfKWA607CV4hp80@r{K~p ze@e7^yHE83oMT?>__5Z<0I#KNWiYq8@q!QlE?#KC1al4z-I8>!C>tw??D_#5mI2^9 z$^+vK!D##(AZx2);0Mo%OjIg|+6oT7;<>wMxYauavSkB6XiH`QV3okiEhpntC+@9X z+#j$20S#bT;~j9gtxgtR_Os+_-G;+n>Is;YC%hh8IRMl|I9uVkJRtd8>rEV&0bo+e zN`OgCaBJvxO8~-zJcpui2g2)U2KyE}3ow!d96|kQ^fQ)XspqYnq2c*GSeU>R6 zn*@nRt2W|f`~hLgw*>_1;VBJWQ#C-bT#~iOV;>>_w+bQ)PhUKmohKv%a8@srSf>wf z&mru2-B=WHVE|C;=`0#>xI^ada0I7|X?OviNz+XZx76yPbZ2|hFmns5Q>OW3u9ozvAb(p0HSjIi&kOL;r&M}uvFbJOGY|=brl&!#2ZDhTSP?nlX%Bxoqy-ND z16RPycK85*VlW|RT0Hsoh;j|64-1tO0AtC5`dtl#kcDq|sTBx)=V%nsI7tBzr^jAk zwFcj#Qdxj_rD!Fy&aA`N^~ia^=PK->lwb+KvdmXc%+vvQu?fEvjShssU$_Y5F~|&4 zoT2jGc_@X@1c}zeD^PQd37q29koskm4}2l{R*)acugY5G;IOe_Ux2il@_&FVVUoW} z2{+XaWg<)!L;(u$Rc33Nx|`NorD^@yeub>u`U~2`!eaJw-dyqRLp@lYk-G5C(yZ>y zpfu|H{w%4PnlrFeN1_tNa^Cl$4!-PE*t8b!?2BTj#du$+XcUfwc1DT}jPOZlmae)7 ziOvi*MuyoVzSfHWgGo1R8~a$_cjACoajI64cz$U#*oS@crKNeD=#XHTrn3K;QM-TB zPTfg6wdd&AO-VU|3Kg;*=^2lGc>ka-FofC?%p4$Ge>UY5@%hNA`RBt;$^HGv1nu=4 zrI(t8E~gH!bhl3~y|CFJy|!Nz743U7htj~}_%HSPyg}dL-sb<05F32#+ljB5M<1vC zYTic_(?05HA3d~>aoWcp+Q$y<cPO95Rd9&>j9#gpMW^<^ox@M`g%^}RC%2BtuiPSGiNjAZ{Gy5v`ha=RS zjFYXei*`IeJy;PqzPRIAMAfDo=Co*8i<783o_i!4^=ijL^58-antIsM3hlfc8ibT;{}uC4Qo?!vH%7q}cQj^bp0gvnt96|o&u zX*88IO~nzFx<>S2e`Ml6)nRs+IY{lu8PS`#AK`%tJ5XLeF>&T>Z7}xDO0stDVd#Ey z6F{$AC=}`SF5m>zr7_gT?yAPp+Porr2A}6G%zcG#Zxn+?EtSSpf@=+2ImSgRWamG- z)DiA($jwhY7hnXMp_z?s1s=%&asP}5=j zPyZ#Odxbi;hw3a}+ifekzUZzQJ*hoAV)E;4`(pB-sd)WA_r(=!(D#GPtiH+@ynDBV zD@N9M*sdjR$?q6n^jvd))BihFtfFUj=~a)mxh&&6=EG6zR(px{oxJ=0V^@vpOH9#g zcRVF|{QusU;M9I=oUUmz6eIOOf@|9L!wH4^#S>xW#TIy$^F@nSjQofbw-X|78YS@I z3m(ylfWl=U(9N0d2lu{a?#-gq_VF&B~!PXm}jb;+Ey(vS&wNa8(bfU4#$?@&-F4$-ArM!h`YpPB7MB*5;vGhls=RmT>qSr-ht@E4o;mw>k!w?ZSN`7jmowBy~XtI-35aWs9EqkN65cZOr>5ppr#U6x+@Z%8~Cmy zYkH+`zxX68;K(|@{#))?Np4COh4jruuOEA3F}=#7M8SFC;<)yc)zO_XKFTL*GuGH|w2lBqJC1ho~^(lYx7`!>jQ5SB`h<rW^YyEnU3Rv% zT+RzkMo9!uloW2(jeW~$x1KZi5B_NBY)_8GZdn*8bWN00OfCrryO*kOzN(zTtat6o zj>SJ4vW({tBq=Gyzj1c^-Prc?vu$Mat@-w@f|(!7dasD%I&xj(Iv(s*%Bbm%8M}a@ zX2ST|mdW~u2}{pDS5Nu3ADfpmy>Hqt8E*}S1;#Ib;FGKMT%G=z`#esz^sl?UE>X9O zoXH%I-%b)bH*C4}T*oy&i?s4dS32v_U++hi%}Y-oYo zer$Ghj?yg9*R`+ko!R>NQZb=YbWv#Td&=c5t2Mc;z?9LS0j?M9Te)T84+>l5Ie-3j z5akcox=CO=$@l zo;xKWD^+Vdagv>D!p|`4{QXz5dkq7%KCP+tV~C29Ig@7Yn0296r`JRk$sFQmx=UEU zhjb}K^?&{4Jd`WQfl1Mh3N&E{1f3}lYrI-phtVhlZ+4Z)N8D@02)5QLX%K4Y(VH~+ zCOJuL=_p@Vz%T!G)-g8eeN1|Lw2is)XR@R#^S$#+%+P1Wf$yj&J@=4O_H43W@}a?J zvL#DhhUw>Wv-;Y%RV`2Orlb5YPpuQ?xx&094w%zVo1^}ag06{SYnAu1^p1A@pXR@# zXQcN>+n48g%5@)7q+)6AQa_V3cxmpma;t87wVRHL8;?qWyP&V&?i0-&uWM}a=jo=7 z%{aDJS(@M%4~eH-J%0SNRDFkH!n)q5B21X*Vze=z9en(MYL1y{qeTgLNSRKcMcJm+ zBMNyP%ym@s(Lr9S;cTsPY>@msz4STbZm=F;gq$M5I+N=&c`2SIa2uxae8x$xGX#BG zWn&xQfO+GvYI537@Bs|4%1;t;9iGaxh#IhJY2pyYhY_OG;vfoNwSJl`%=Tg0ZC{;5 zuQLVptg@XLI0ZSqpgGqDYk3y1=EMh;^qmFYfnQu)8cu~h=@X}%K|g5>L^#bM7e0nS z&2m!#RXVNM$izP3xk1Z=w|OtcY_;>YYoCew&ju2;S+abb z=zYrr1$<}JbUFKy1Q}Z&b%Y?}+LH~~8q;umXn|u^4=Yaj-b!Ry`2KxFc(+)|H?ZL> zXY+m5hF>~7e;o;18{`sco=BVKZ$}y&O4xjt{}-^(@F(f*lFq3>e$imzhTJuQg|1qz z${f8N<#sV+HKtbcyHT?*Jr(y;#DsD!Ta#iu)U|jT4pPn${Yzg&uS`wSHMrho@!ft= z{u7%$fWU7je&F(SA3oVo@ruv4)!_8TmHxYfQEA@SxOhT|gJU+iy7#TT7sfLN^KN-o z&e{u=k-Odb@CJSL^m_5LOq%1^WS_#mPq~GbYTg69BceeCndgWDN;$CynY}zrsFu4n zlyw`IHk-a7*27<#x&v0b#>azp9{q0v!y~n^`10ML>*TSZP&1c>gc~~_b2655I%WmW z;+Flaa_e+R*GR8J7@942{#p5h_l4dI9J#l$?p(Fm*|}z;{2}_FsplonVVS`#N}Z>6M=SO< z=ix#Br9rNWS8qiFP~l-}!MwYHGdv5a3C9L2j`&}DMf~|O$Fq#sjw011HycW@%S8%W z=tmcx^?B=3Z&viGm#)aC{C_c8PHcWV_j%J7pCF2snjL-`EFu{3)0`<02J-i~^cw%+ z8*UD!cWTI8*gG2x4A7}eyOxhjw8u_%A@;e9J zu)Nnkd0Nr;C##%H_vzwyDp!Qr0VL@`jUUe*X$NMEL}AC+LT#Lm_>y-r-jd=NCK?7K z!xr}5{rBsbROZ+I+%5LOvz|Fu<5ohCNcsQZ*%NP}YdUxPZx{nfc9Ez0chhyJVtwM< zeCE=qpwTJzks2kP<`@0pL8dlw2b9l|*r%S!vE-H{i;lgEXQLPJ%&U0xXBZdIVK6?RL zPQOe6LT;S{Pg?-RY_tFk;B^OlWBtLcIy*2i{nuvs4gk*n5)Lg$vL7viDOZ<)0yBmN zQYKSqzdf@8>gp?jFE0^E4eZ2~5Rp7)-q#(-3G`Q@)3@S^AG76A(>}EEsw+%M(M}GlwQEDeg;9WYi&O?=`I7NZKo>?eZj&pEi(R!5NjHG@azoQY$?rp zuyP-u0XY<^uC#%eN6dLuhJin1p5=HZQUxRho^4_8*KWH=d#GuW7?TmDFAYP9}7N^)N&N#!wr=`_a&p=H+z+I2Scw zNm9iicQnHFt!XgqWzBJj5(JC#dFYgem`Bj&v(^Vt^IuhPUh5bT69zle_(w=(1E8|0 z;6F#2TcH74hwXQ>uI2)+d1 z{a1#r7lqUgREt~`@!ykUY8z6}FFgEva2;BPgM7Ibn*e5&26pqc3+5Jbj03oqX&=p| z$$y|h*cljyYG_0IZ4D^zAHn!%1z3*ka|x#Jby@)mwbuvIrD=v=>xUx16pKPfXTu90AGP@R?%2ffMqR!*dWL}8O?=5VEo?+ zVK@T1(JOajc&&keI17Du#=aWRGh7C}t*d}$qxspg&m|QA&msW8`~5=@tb{alv(14E zTK~2@xDCC-1HizL;s(fCp3wQ+$fuzj1~2;WR-hl~Gk`!)`JaX^q5yabH)u&kF9Gbk z1^};dE>J}h^QV|?iXq-cF$7lKHjL4NhGaBgmmh+TLX&X$oEj&i6m;Ki>VQfXQdLZa zbx?uc*P3TQNz?*)r27osau;NfWJn$ngeJiE_4I*O z`g4~otY``4{-*+hXws6(@L7l^1@HN=1SDIQ0Y-Yzs#*gtX!1Si0#+!=(eZ?M)4`ye zg;<1-p=iZxBxX z9_)r;ec0v&`z%~At=v8U!8g@_-}niQ+>6aH!D|Qv`4eMaMYKlmO*Y-x!owLLR2~7M z-^MP3X9m(zVF9Qvra}~MumncdU}1v_-E7O0cQv*P4D2OuVVE7Icb{_?E7+H(RBpZ1Et+6NwCX-O@AE5RW zIw8X}pf%DF*JcaH0mfDkgVt*w&8;>p8}zd7EAUbnzXCmigVWAiko|{t+$}cvHFV>+ zf#>+mUp_bZy%%OtHTak;{MGUE z+~5*0C}e0-77EA;pY`R@&^>ks!URGGb}c&)4x{5R&I<(Ia;Vp-82_VCwj*rQvV<^W zYa>*FagCk=C#nK23^4#;Y%vMPQb@-R?tY7^3N-`b-RHY zF#}@nR1#1p$53S9^P`Yr54`tkgvy~@5}dDIIP{ZWRmqMsK+gP4p(hgufEd|lfcD^j zVVk~Q1-?ZAl1+twZ&Qxw`QW&}9aGK(+9~Zvi4~RP)8DnOyh+ zy?q-t>>ucjwgwt=Xo>Qj?5PjomM?*cB@Atc!fab8S4#;Nudw`cqD~HcD{bTp0L|h6 zuNpLVB(?xG7m5v<%B^en`LG6z$%|0v6_y6>#qSJs22Vg&Y!)+67paWEK0I*pL5@MW zihjWGFOKp8zakFY#t#!%GZead70ZEu@L|^|bU;G0u{@An#c7Gq1l;$E z)+ zdlv5ir#;L7UuYIjfQ*r0 zhECx8Pon+{@Gm|exFNj&I*r1hX<$)i;2ZG+7XA@sQJoW7hNXnv_iwf4+@Ur8252AV z&t9RD0zaMX-ZzN(sO_~+6dj-j?(O>@&W=q^iXje(VguB{B(BVL?d(Qt4vyj5a}3&qJ8`9m88GVW8}gD96i=Alo_YCThnV!=%M;Wan>Lb{8ceZ+ z(zaHp+XuZ4ROJflT^idIbBRY5e=Jg(@`QZlKZ_6_%TG?1FJLfK3<*NeX1GygOp@+I?=cHfiHjiQAB z!cg9>(%7N>a(T~c?Jy~ae>!F7r#ETG2`j&gmh$`+V6QcIDa!vFll>vCzm}nFNsw*+ zj=kjYHOEV(#&RcbtxsA1{&mE1sIYMPYw3qv%8p~#3CVR;hd5ofZa1$vBVS zjGMJ$;be1ffIJ21F1I_s@37u`xqo5XCGAXG&&bIq7S|bDJY6Mx4qi2vE(aRd`$;7b z_$=Q^m?;TLa-KTzpqR?g*iwixMs%LAN2_t8KPWEgK9C&OIfmKODh`^sd3)1w`IU>t zx{-@k2p>=88@=KhN00l` zDW=%rOz&A@?k*GSgL={OgmWeJ?ShoTjBhy>)`>6ldHIzTjTBdYHqc^;ITG9qpJ8D&)ws83N-6VRN%Ec}sgzo* zAe(P=)uy3cX)ZH7JYwoJY*LJT#k4wlebCfcE&f>|s<$F_yLM!C)N*O21|=f;3@bAk zPE7bb#9fxIK37|#Ru<@gC#l**0qqZ*Olgn)q!(pmq&0pClknGi9x_#_MGG_w4_;QJ zyi(}2>3?bac2R++!&{{vA7 z&_c&H3A0}f&PxS$V>4#ES7y7|=DVEcyK3gU&gQ#`=DQ8%yEEpySLVCe7Q38bqiPnr z&KA3g7P}3@AWxmADiBdxDpt=^nv)d~d=)9eCwC&GDpHgxQnV^kj4D#BDpDL3BD^Y6 z0u>@6aUvp;DpIm4Qi>{4$|_RoDpHy%Qo1TqhAL7f%cXb2p1i{-4x}7aq+A_Nb9K(E z;$}N_&L5Ff%2lMQRix@=1Voxuq}nP( zI#r~49Zs(G&c2sJSVN;6LnN|9HcZ3Z6jU)OrZIf6yjrn*>-<|^1oplN9DNZu`yz1l zMd0p>z*8P4`()Re<-W&33Oe$hnT7MCc^r;+pOpA+F!F1jHu`hat6Z)4A_Z_6=FZ|%Np9Ho_( z&u^@Z9p#c*qW#uXrtqXL1^*_yJ0^c z94jFu?ndL*KFL2P8J;?m#GS7G0TIuivi4gs8?O`)A zDCKwE(o)URTs7Mw4C-07?sc*`4lZ8c4O;lJqC{rJ)0}OLMph@aQKOa&_B+OULVqOI z?PqkI@o+t@!I)H6pn#MGbg4Vb`3pz!64s5EWzW>j%utv^Gm9IarMm#aPFTj+0{6@#C3-;Tt07iVuzKFP1 z&htT_0V&_ded0GG3r?$W**0(AA8)oI2`&c1ej@|?%il+z-i(YAza1GBbb52j=_{ts z_GTGwczmkO{!NoQ8K30-)7z;be*4e~H@LhMFmT)g2M>H+iW_|VE9k@kNnd0Bo&p!o ziR2z$C7CY}2-R<@IIW6y>6pCJei5kEDU^{jU0=gT{yWE8h_0> zk7>7o4|g((AH`4# zEFE^H?6(1UHj)p&LLG*G5=W|A_tDw17yVbh;wBIv|CJxJ1z6T!`Sbq>x!n4Umw+t| zHm=+m3GBoU98Z))aaTY;)m=v=J53{9ZtEZtT;>pHO8;lM1e%Ozccuajk|a@@6}M4N zGD(+0{{;j#HUH&jU$8rb#=0w`pVIz=xum*(-#A+aAOO>0eIJJZ@SSw|0}${EAYE1g z>?2^!0s0l3KvNIi&IpVVCX7YABud9ebQVVhz(=t&g%3<`gnDOc;_vuWg7Qed;x1sd z0YQ68KrjTTKnPT@7%7|kCxn)t!Y3)aPT2&U+=$rDRE8&)>kcK55Ct$qslxF2BS@E_ zh-?B|7CCQkHcizpP7NVOt)kQ|sIT2`HomvNh;?7RQjE?(D^*_FsVB*+ zYbwvXrdIQ&{p<7lhnGXU|D+T9m2&cl?y>PM@r|D}oeB(kjpGiQ$;HmNDn-uNN>B{C zNj1&*s>IJwHK%OhuS#JpYpHW9@!{gyt}^kYuGaF)ldo)p$xACotI>6vsy(U+{IKK7 z{2KYn{KS%b7k$X~iqhFBL||Q}9e;$$^pbL~VY(I&{1&kaMPGUSI&o-@Xt*?sdF8Gr zS$cSinjd9D+|++W(pSUewZ3}%< zwf^xH8~b;m5bcaN8@U{)!k&^mWpz}JFKIpJr2#ABJ;xMpN-6kIk^JylU&th#8<%=E zLqflzSE81)Dif>%cXbsN)1uaY|DFec*eZrRwK<~e$>Anm7ve3J;Pl%U*(aLb@ZY)h2ZxZL;w*}q z{z!%fe!W^%4Hf&V5yptFNmi*@4QT-d?AMQ{uF3XEE${e}w={d4Sk|L0*oAHXys=_= zYMSFnwDbIe%JbtL>GzG|FN-yE6V&b)+|APz1DA?{w9!s?C{`}2c(HDGC}Jg#NW;R9 zA?#;MY&Qf;Y+2^!-SN4yvO>oH8J~YfPp18U=J|a$`wsvLef{TcM#{3}3I-nKz%HXx z{=s+-!Do36IhMY=jxAf7THq8Vng>Z5Tt$f0YJ?E0OPZd#!iH7>VI_irT?^k z{0CD12Qpqek(iAG?HarJe!zdObGp0#q9Ub7*D(Yr32*KLN~ewgWS!qU`h;X1$gmoN z&bd*3z`H(25d7H?vNs0B!AtKT{zt1Z207rN{OBP%ITsm(p>;&~HxsI`y8rk{k3L*F zDpE?6AhsBQfq!-X-DqS3HkJ}JDLW1%qdof&ASJi}nq?-Sb3NE+AN@RHf$-N(c*eVX zL%zE1mH_zAe?I_YDPD(4l}NKk(M|eV&TVk}Mz|&-ik6y0!_7&kueI)rb&uN5UJrd}FoHIn-LMkB zi!$;-Co$F}F4iPI*5nUlq&^+$t#tKBFiL5tz0t>AdB%eo)oLXfi6l){e%iP+7bC-LFGGzA{G&%#B#0PDE zn{Ryhvu^jiL}o9vO!qV0!obbv-ZNmu$1umfo%Y<_2Ri$q1w(h$btUOKa3!q0bM21T zchb)2>3vIFi=oqV(UZD;YA>sOZdd)pDOWpvOVFk4Dmn|rq5DHc_6otYObaziW*gb7 zedo&MU&j_4<#U(ks~vGZ>6eMqN;;R-F31UAi+V=7ed+LmlTf2Y#7Z0O_*&Pv=lE&+ zX~7Bx58uyMdN;>LEmXJmR?eBzqXIJfMakx$uNAhg?T1W1UwL^v zk@3WQb<1`%RLg{^jLI5b169CUk$>sQa4I^N)XP+zN>v&?;#F*RD+8bQ%_XvHWb)5U zg!0!hmL!7W9fCtAKOn{=--pn4y$zgA)`r`cbPFkADMcP1(uH5dxRr>ar9iQ#7DVd1 zo0k~VRSIn9mc01lA!lj8p<|h3jI~^YiZ5K-$?EB0#~dDIjwHHagtr`miuJPRPy4`> zFOe4~hnTU&+$8qUG^OfdfJiQ+kGSOW1CTCc%T{_KmB zNDJq^NJlH*c}d`Snw!uI`^f1hL#EQ)}D^vaD8 z3^8p-guUyaL$#hU{Pg?Jd(`!H-FWL7%$vkY_HSz@lx-%kU;m6QOL#9HN!%q{gsi5r zA(~!g1^d!ze_aj7>wEC%2#EmmA|~COhWv8qq7(kQA??|4|Mu%>MOWWkZZ~#`#~7wL za~IX`7pDexrltz^6@KL(*Wf7jmNnwdbgQ?4mvuUx6NO>yY|wC(IzC0u-p2xVv1_ES z0c{y|Wp`9xFQ>Hn648!B(ip=~6rRs;kd4UbJ6^^-`WpU_etlHH3&A7E!Pg2AK#`uT z#x)e#W$W1Mmi)q1Sb6b8V1($QP2*)zJXD_#E2`$=rxvno2BZIjhKrlNYP+bxbcs7ycg`>gd=F9u6!^E)L5a zLV|9Ukiz(Kal6U{#rZk^#yh&kDDk_yv^W;X{v&<+m+yw7NFil%L1l zJo?_>2jAta~ebKeVwSRGyd|;tcY}Is>Dip*iF2`(DQom#%hwj_GFtaSCV`mxC+shxM2|EUvJJW6HExT#>X48@qU`Z5|jHAuw=5mEwW^<0AVh2ftDB98DwcWn< zir9PhGQY6cUdn6<@YhYO6skf-_t@s+8L-}GTm5_TpE;ME*xvVtE49$?0YTUZbaGFW zl1b{J#U;fUlY|Kz!Xhkg-{h~RD4%{aduiMqWW8;BeYzv!;$;)-Dz#sIK*BMlQ#@Ok zzX)DSQWsRN=4To8e~OmpqGlAs6SZ+qsS{A1M5^TU(em7F1nltj;Ki8 z*VoKkGGSNG@qHsw0q>KC2sUL#Hox0jzS5Z_F47=TlK@54HA?W$+wpsXGIBQr)J=ofkY??iaX>G{;(Sr)j;Y-k!aTQTCd= zY&vI{*XW$rObK2qS1fXe12>lWMJz9tugO%0EGNww7WileEWewxF0)g%BLxSQrIcsO zpE6qWsXo(y#Y|RY6syJUgscn8PbE(st*^_o37Duo-W z${Q+_TPmB|g8EZw)0JaI>y6^np=N@mc7hl?2jZ3Wfp_aQbJ${@vxxU+5-e*(4#fNG zuEQNxO+Gj+p0hvhON90mv$hpIRx-~z_?80sI1=v#t$(q07!{>@4`iOT@!dxK`?*YM z!2xR?*n&z@Pv$DW>%xM+jTw@a(Xd`ov0i<^zxn{V{E&L_q51NI)+MQ&9fmcDs`9JE zsgw0ap=e4OT8nxN3194d6%^79O&A1WV85uEz`%%0Ai^L~VtxoVj>m+NkU&I6qGbON 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 z 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

bawY;=>3~te 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 z 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%0AJNc;mGINL3y=Ua= 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

}F&?Qk5@`hO0r0XTz5>b+C{{N(hIYYo_< zD0rH@uvHRF*H8Y53I^;9dF#6ov6IV-hwlWHf&Ker%lm+K&xX^53!FC~VHH~g7=asD z8}VXFxJ;;E@KV+H4P7064E0X5AZT^~cVEM$(bpI`5rySeBdD+QsM9GRo4G|(LM5^k z`~_?)yO$%v+#1|e#3G%4LEr-E8OT~foQ$7>rz~>QKS+4nymv>a$5I3dA^d&@uRDdW z{|?UIhetCKlE}Y`Xs@_Slfs|9`bx Qbpk>> normal = datetime(2009, 9, 1) >>> ambiguous = datetime(2009, 10, 31, 23, 30) -the ``is_dst`` parameter is ignormed for most timestamps, but -is used to resolve the ambiguity during ambiguous periods caused -to DST transitions. +The ``is_dst`` parameter is ignored for most timestamps. It is only used +during DST transition ambiguous periods to resulve that ambiguity. >>> tz.utcoffset(normal, is_dst=True) datetime.timedelta(-1, 77400) diff --git a/lib/pytz/__init__.py b/lib/pytz/__init__.py index c4a3462740ae..8887140f1e1b 100644 --- a/lib/pytz/__init__.py +++ b/lib/pytz/__init__.py @@ -9,7 +9,7 @@ ''' # The Olson database is updated several times a year. -OLSON_VERSION = '2011k' +OLSON_VERSION = '2012d' VERSION = OLSON_VERSION # Version format for a patch release - only one so far. #VERSION = OLSON_VERSION + '.2' @@ -199,12 +199,8 @@ def _unmunge_zone(zone): class UTC(datetime.tzinfo): """UTC - Identical to the reference UTC implementation given in Python docs except - that it unpickles using the single module global instance defined beneath - this class declaration. - - Also contains extra attributes and methods to match other pytz tzinfo - instances. + Optimized UTC implementation. It unpickles using the single module global + instance defined beneath this class declaration. """ zone = "UTC" @@ -212,6 +208,11 @@ class UTC(datetime.tzinfo): _dst = ZERO _tzname = zone + def fromutc(self, dt): + if dt.tzinfo is None: + return self.localize(dt) + return super(utc.__class__, self).fromutc(dt) + def utcoffset(self, dt): return ZERO @@ -232,9 +233,11 @@ def localize(self, dt, is_dst=False): def normalize(self, dt, is_dst=False): '''Correct the timezone information on the given datetime''' + if dt.tzinfo is self: + return dt if dt.tzinfo is None: raise ValueError('Naive time - no tzinfo set') - return dt.replace(tzinfo=self) + return dt.astimezone(self) def __repr__(self): return "" @@ -616,6 +619,7 @@ def _test(): 'America/Coral_Harbour', 'America/Cordoba', 'America/Costa_Rica', + 'America/Creston', 'America/Cuiaba', 'America/Curacao', 'America/Danmarkshavn', @@ -1187,6 +1191,7 @@ def _test(): 'America/Chicago', 'America/Chihuahua', 'America/Costa_Rica', + 'America/Creston', 'America/Cuiaba', 'America/Curacao', 'America/Danmarkshavn', diff --git a/lib/pytz/tests/test_tzinfo.py b/lib/pytz/tests/test_tzinfo.py index d8e5ddf33397..24abb91ee844 100644 --- a/lib/pytz/tests/test_tzinfo.py +++ b/lib/pytz/tests/test_tzinfo.py @@ -17,11 +17,11 @@ import pytz from pytz import reference from pytz.tzfile import _byte_string -from pytz.tzinfo import StaticTzInfo +from pytz.tzinfo import DstTzInfo, StaticTzInfo # I test for expected version to ensure the correct version of pytz is # actually being tested. -EXPECTED_VERSION='2011k' +EXPECTED_VERSION='2012d' fmt = '%Y-%m-%d %H:%M:%S %Z%z' @@ -533,6 +533,24 @@ class TahitiTestCase(USEasternDSTStartTestCase): } +class SamoaInternationalDateLineChange(USEasternDSTStartTestCase): + # At the end of 2011, Samoa will switch from being east of the + # international dateline to the west. There will be no Dec 30th + # 2011 and it will switch from UTC-10 to UTC+14. + tzinfo = pytz.timezone('Pacific/Apia') + transition_time = datetime(2011, 12, 30, 10, 0, 0, tzinfo=UTC) + before = { + 'tzname': 'WSDT', + 'utcoffset': timedelta(hours=-10), + 'dst': timedelta(hours=1), + } + after = { + 'tzname': 'WSDT', + 'utcoffset': timedelta(hours=14), + 'dst': timedelta(hours=1), + } + + class ReferenceUSEasternDSTStartTestCase(USEasternDSTStartTestCase): tzinfo = reference.Eastern def test_arithmetic(self): @@ -701,6 +719,85 @@ def test_belfast(self): self.assertFalse('Europe/Belfast' in pytz.common_timezones_set) +class BaseTzInfoTestCase: + '''Ensure UTC, StaticTzInfo and DstTzInfo work consistently. + + These tests are run for each type of tzinfo. + ''' + tz = None # override + tz_class = None # override + + def test_expectedclass(self): + self.assertTrue(isinstance(self.tz, self.tz_class)) + + def test_fromutc(self): + # naive datetime. + dt1 = datetime(2011, 10, 31) + + # localized datetime, same timezone. + dt2 = self.tz.localize(dt1) + + # Both should give the same results. Note that the standard + # Python tzinfo.fromutc() only supports the second. + for dt in [dt1, dt2]: + loc_dt = self.tz.fromutc(dt) + loc_dt2 = pytz.utc.localize(dt1).astimezone(self.tz) + self.assertEqual(loc_dt, loc_dt2) + + # localized datetime, different timezone. + new_tz = pytz.timezone('Europe/Paris') + self.assertTrue(self.tz is not new_tz) + dt3 = new_tz.localize(dt1) + self.assertRaises(ValueError, self.tz.fromutc, dt3) + + def test_normalize(self): + other_tz = pytz.timezone('Europe/Paris') + self.assertTrue(self.tz is not other_tz) + + dt = datetime(2012, 3, 26, 12, 0) + other_dt = other_tz.localize(dt) + + local_dt = self.tz.normalize(other_dt) + + self.assertTrue(local_dt.tzinfo is not other_dt.tzinfo) + self.assertNotEqual( + local_dt.replace(tzinfo=None), other_dt.replace(tzinfo=None)) + + def test_astimezone(self): + other_tz = pytz.timezone('Europe/Paris') + self.assertTrue(self.tz is not other_tz) + + dt = datetime(2012, 3, 26, 12, 0) + other_dt = other_tz.localize(dt) + + local_dt = other_dt.astimezone(self.tz) + + self.assertTrue(local_dt.tzinfo is not other_dt.tzinfo) + self.assertNotEqual( + local_dt.replace(tzinfo=None), other_dt.replace(tzinfo=None)) + + +class OptimizedUTCTestCase(unittest.TestCase, BaseTzInfoTestCase): + tz = pytz.utc + tz_class = tz.__class__ + + +class LegacyUTCTestCase(unittest.TestCase, BaseTzInfoTestCase): + # Deprecated timezone, but useful for comparison tests. + tz = pytz.timezone('Etc/UTC') + tz_class = StaticTzInfo + + +class StaticTzInfoTestCase(unittest.TestCase, BaseTzInfoTestCase): + tz = pytz.timezone('GMT') + tz_class = StaticTzInfo + + +class DstTzInfoTestCase(unittest.TestCase, BaseTzInfoTestCase): + tz = pytz.timezone('Australia/Melbourne') + tz_class = DstTzInfo + + def test_suite(): suite = unittest.TestSuite() suite.addTest(doctest.DocTestSuite('pytz')) diff --git a/lib/pytz/tzfile.py b/lib/pytz/tzfile.py index 05944daf22e0..9c007c80995a 100644 --- a/lib/pytz/tzfile.py +++ b/lib/pytz/tzfile.py @@ -97,7 +97,9 @@ def build_tzinfo(zone, fp): break dst = inf[0] - prev_inf[0] # dst offset - if dst <= 0: # Bad dst? Look further. + # Bad dst? Look further. DST > 24 hours happens when + # a timzone has moved across the international dateline. + if dst <= 0 or dst > 3600*3: for j in range(i+1, len(transitions)): stdinf = ttinfo[lindexes[j]] if not stdinf[1]: diff --git a/lib/pytz/tzinfo.py b/lib/pytz/tzinfo.py index 1bb57c250039..a1e43cdf0c01 100644 --- a/lib/pytz/tzinfo.py +++ b/lib/pytz/tzinfo.py @@ -74,6 +74,8 @@ class StaticTzInfo(BaseTzInfo): ''' def fromutc(self, dt): '''See datetime.tzinfo.fromutc''' + if dt.tzinfo is not None and dt.tzinfo is not self: + raise ValueError('fromutc: dt.tzinfo is not self') return (dt + self._utcoffset).replace(tzinfo=self) def utcoffset(self, dt, is_dst=None): @@ -176,6 +178,9 @@ def __init__(self, _inf=None, _tzinfos=None): def fromutc(self, dt): '''See datetime.tzinfo.fromutc''' + if (dt.tzinfo is not None + and getattr(dt.tzinfo, '_tzinfos', None) is not self._tzinfos): + raise ValueError('fromutc: dt.tzinfo is not self') dt = dt.replace(tzinfo=None) idx = max(0, bisect_right(self._utc_transition_times, dt) - 1) inf = self._transition_info[idx] diff --git a/lib/pytz/zoneinfo/Africa/Casablanca b/lib/pytz/zoneinfo/Africa/Casablanca index 77b88cffa389c297821a5faf9d379cc72bcfe68a..d3d6da917d16c409ff41894e5fd23b8547cd3ec0 100644 GIT binary patch literal 1362 zcmd7ROGs2v9LMo%C5`42DncqwMNA7*GhIYNNtj|zIyz~ZR+gEQnO7^dvbuyDq1S4X zkobp^1Vt^vBq6LwiEz^cETacx1z`;?!VsFy_p}IX5$!s|ozI<_#Vqdk=PUD9r&@oU zaQzJz$Ez>y;{)FBor9sd&d}Ct_Rx!Q=gH;N;AnccHTuOJoLb(ve(L^L+g01{G83=kBr-ZeOt$FQ^aZWPWgR`j^_d%Mz^IGtcc!uLhjF ziZR=Bq0iZzb~>2fDN^9-mx5InRl(jK@wT3l!t8b_Dz6fsyH>VjY?R{J9w}M4LP|a+ zOKEtPDjkZKvN5;Xb~8zpKa5Zn=i}7&?$2sR{e;@tHmoZ1pQ&9{H`MOrURC9JEPG-* zRQ1a1QayP~YNF3c%}7A};|;Q}uSIHyi)4RCnbh^#>Of0|)CUTcU0JFcn$lEb=2~^I zc)mKcWRW_YKB=0lkZPXyQZ>JQr&@k|lOqEU)X~=?a_s6GX}x<#jm1Gt1=Cd~F>-X{f!;=r`!_!9! zKq@fm5|A2@B8<8Uqzt33gMX(Gqpk!gg+nb!F-SE?IY>Q7K^!VVN;2x2kfMybDx@r= zE~GG|GNd%5Hlr@isH;QDL+V2cL@Go|L~2BeH0mmmGL5=Uq)?<%q*SCqZJkDo093YDbDksz=I4>PHrUtN>X8vIb-k$SRO!81*`k pg&-?ImV&GWSq!ooWI6bMttV0sDurbwdeV~8lTs2rYan@b98`XAv1KqzEe)FHF%z(bs~q%PO%9v5SskW*40XFQYb2Vm4*pR0Khg z*|(F5Ll6WmJWHLU57dqVt?Kp3U#wp65TiYJTngc#s+2vJf7d zsI$k9K9Cc)QhHMMna1Q1Z7SGo5;Z$C@w-}D;%l_!<0fe>{G+YUmgUs!CvCg)Lrzc6 z+4k;ta%OVIo~?T#=k89~^Hpz6M|#|L78{eSzhsk3ZzNULY*U{vn6C9%?RtLLbT1^d zXCf)RU-oD^SKBOoFH5w)ZJP{4OL}qtYRQalu!9@tB-{SiW*28<=-@Xy^mR&xOJCdJ z_tWO`@?$$P`Ae>R&)eM1F?039BfZu+XhxrgdcFRhgtt31%E$IbW3lZ~Wl$WwifxTX zf_RX9@i6!qgaz*LY2@R`=aB$N1SA9!!|Q?|QM@h;636QTA(40LgAnqQVywy z6htZ_C6St5R}`u0b!CydURM~YjFd)dV>%bs3J2AZ@<@GT0b~Va31khgTLf9f>y|;* z@w$bOm5`;7wJ>+UO~%1&$aKhj$b`s@m@mr+-bmG~oOPX>b!W+;#->DhLzPzSuFy&? KZ`k$!DEbGANZLmL delta 40 qcmey!`-pvlGNbiGl`oSW*{mn8XH%Wr$OIJFyp-tyBUDI>kqZDT91TPO diff --git a/lib/pytz/zoneinfo/America/Blanc-Sablon b/lib/pytz/zoneinfo/America/Blanc-Sablon index 8526259c7a5a657160dc9abc7389044365b3c6b5..8a33789afcbb422ff086f021a0716992e463eb11 100644 GIT binary patch delta 18 XcmbQqG?Qt9A=9qA6OEferDM5PED delta 18 XcmbQqG?Qt9A=3fniN?(!az`QnI@t!Z diff --git a/lib/pytz/zoneinfo/America/Coral_Harbour b/lib/pytz/zoneinfo/America/Coral_Harbour index c63a32a2a171ec749221a5dfdb2b64c61cc89285..1b49e37c943b55e971162900aa3c7ed4d2d6698f 100644 GIT binary patch delta 18 Xcmdnbw4Z5$A=9p(6OE^U$dhFNOXmpI delta 18 Xcmdnbw4Z5$A=3f-iN;ev;cgr8$dMJ7AD63|0f**Sp&2TXbsRZ4hY-FH-rJz MLIwsdpny3S0OcGtc>n+a literal 0 HcmV?d00001 diff --git a/lib/pytz/zoneinfo/America/Dawson_Creek b/lib/pytz/zoneinfo/America/Dawson_Creek index 01ed5354f840f60cfcbe9663a89d8b47d527a0ec..c3fb166b0887753eb80b078c47bf4c5876774662 100644 GIT binary patch delta 21 bcmeC==;WAS$h2E@qw!=$Ahr1fqazalOUnko delta 21 bcmeC==;WAS$aEljqw!=$Ahr1fqazalQDz5K diff --git a/lib/pytz/zoneinfo/America/Edmonton b/lib/pytz/zoneinfo/America/Edmonton index ba6dbb46cfabf01e9890972ad699d3c96d0e982c..3fa0579891a9762b7c131ec5ece5d6d02495bfc0 100644 GIT binary patch delta 21 bcmca2bVX=_DbsHDjpilHKx*?^=H;vaSEdJu delta 21 bcmca2bVX=_DboSpjpilHKx*?^=H;vaT|o#Q diff --git a/lib/pytz/zoneinfo/America/Glace_Bay b/lib/pytz/zoneinfo/America/Glace_Bay index 199f0b03044791350290f374970604949a4982d8..48412a4cbf9241ea83887876b1b8b22c367ff4fd 100644 GIT binary patch delta 21 bcmbOrI6-iNDbudI8_o5Yfz;-7W=&QASKSAm delta 21 bcmbOrI6-iNDboSvjplmHKx%V3vnDG5N{t3K diff --git a/lib/pytz/zoneinfo/America/Goose_Bay b/lib/pytz/zoneinfo/America/Goose_Bay index f2a981849d1d546ed15149f2684a77eb99cd53c2..83e5a9b398fd1b600e8f0a72995855dc274d0bd3 100644 GIT binary patch delta 21 ccmew<@l#@gA=9pF8;$3&0IAKFS(dQ_0B?2)#Q*>R delta 21 bcmew<@l#@gA=3ewjmGm>fYj#8EX&vdVkQV( diff --git a/lib/pytz/zoneinfo/America/Halifax b/lib/pytz/zoneinfo/America/Halifax index b98c3a77340fe1d504a65a3cc4022e8760575cf4..756099abe6cee44295a5566ad6cd0c352fb82e64 100644 GIT binary patch delta 21 bcmaDL^+0NZEz_>M8|~k*0IALTtcDx_ZA}RF delta 21 bcmaDL^+0NZEz<$zjrQ+YfYfGvRznT|U;PJ; diff --git a/lib/pytz/zoneinfo/America/Havana b/lib/pytz/zoneinfo/America/Havana index b519c0947008a2f2704901487fd714bcbf7caba9..96eaf81ee9e489a84458d298e9fe9d67298a954e 100644 GIT binary patch delta 37 ncmaDY^jc`cQAYOtei!`9A6(dchLMGp8^~b*0oaZqA{DbudI8_gS7fYj!lEFJ6sW!DK6 delta 21 bcmX>oaZqA{DboSvjphw3Kx*?&mJW6RSceC# diff --git a/lib/pytz/zoneinfo/America/Montreal b/lib/pytz/zoneinfo/America/Montreal index 0ddffb2f299ab9101af2189da58961d549f80f5a..47633bd49f89e35d20ed118cb813e7c7bc9ca335 100644 GIT binary patch delta 21 bcmbO#Jym*wCDX3g8?Aq_0IAL9tZ^IwV@n9P delta 21 bcmbO#Jym*wCDQ@Jjn=(^wKF?ogh1Gm24dvk9XHqW}XCfMh^4NOp1zlgi{e GCQkqi7!WJ~ delta 32 ocmaFNdYpBFGNbZDl_?VsC{KJE!Kkv?j!}bgav77#=MiC|eRm}$e delta 21 bcmcb@euaI4DboSpjppr)Kx*>=MiC|eTWANA diff --git a/lib/pytz/zoneinfo/America/Santiago b/lib/pytz/zoneinfo/America/Santiago index a8cafe6a88993c1e006477f10b9e7dfabcc5a43a..de74ddf1a095c9b3d026dfe928a3962da8e42339 100644 GIT binary patch delta 67 zcmeD7nCr3ODkIyRbsGYlZf?HKc%6~4fAePMRAw%q5Caf^gq7GCCHaADX2&@JAVFrQ QT_u~96#AGauTzc%09Ah$fB*mh delta 51 zcmbR1(e1I}DkEErs6jxL#pc_L*BKdmH*aQ6W#$43F#rKbSc#oca%FzJ0 Cx(~Vl diff --git a/lib/pytz/zoneinfo/America/Sitka b/lib/pytz/zoneinfo/America/Sitka index d2f43a2fd50b72a111f0f17377a1531feffbe6ae..f2ae47a323e7ae30dc82ab37bb67ef6ca0464b54 100644 GIT binary patch delta 25 hcmbOtG(~7bB{TDZOOcyvm^oNk7#J=spWMOG0|0au2+{xm delta 25 hcmbOtG(~7bB{TD(^5vUrm^oNk{{PpFoZP|D0|0!d3DN)n diff --git a/lib/pytz/zoneinfo/America/St_Johns b/lib/pytz/zoneinfo/America/St_Johns index 27416c3797327dd0451404b37be7e866b46af759..e7a18d601d0255c26885313540cbe755e009a77d 100644 GIT binary patch delta 21 bcmdlcvrT4#CDX2J8?9|wfz;+I);$~mVR;C) delta 21 bcmdlcvrT4#CDQ?!jn=lTKx%Up>mCjOR4E5e diff --git a/lib/pytz/zoneinfo/America/Swift_Current b/lib/pytz/zoneinfo/America/Swift_Current index 8224028413efe8915266243cdbb6947268723e95..8e9ef255eeb11515b84126d9ee5c0c6b3c72f2a0 100644 GIT binary patch delta 20 acmdnMvVmoSDbsHDiRK@H*+ diff --git a/lib/pytz/zoneinfo/America/Vancouver b/lib/pytz/zoneinfo/America/Vancouver index b69358c4502ef8eb0af82a82373e90ccbb5d4ac4..0c1fa52690498b3cd087a90ba9ba4d4f0467d532 100644 GIT binary patch delta 21 bcmdljwp(n1A=7TrjmFX}Kx%UU%WF0OP@4w> delta 21 bcmdljwp(n1A=82AjmFX}Kx%UU%WF0ORyGHj diff --git a/lib/pytz/zoneinfo/America/Winnipeg b/lib/pytz/zoneinfo/America/Winnipeg index 5f9e35c391b53a98e4434412f51fffcd2e475d48..2d22791686e86b2f17a0f7fa53ad71f03a3384fc 100644 GIT binary patch delta 21 bcmdlewozjn*nGKx%U$%LO(7Q_=@q diff --git a/lib/pytz/zoneinfo/Antarctica/Casey b/lib/pytz/zoneinfo/Antarctica/Casey index 76d0794e956578671becc6975b8c136ee027557f..8ebf0598ff90ab24c884305f36947b002058691a 100644 GIT binary patch delta 95 zcmaFN_@8ltvJxu;0|N^X^Zt`N)8KWBO~JeW)Ca$na}@lY&rV=uVq{{TxL$*m5vT&F envr#4kAf(W%>YsXqLEecfK_pY2Z!idZ~*|?MHbTl delta 67 zcmey*_?U5mvIH{&0|N^X^Zt`N)8KWBO~JeW)CWc;#)+pjSb@R}3=@Pn={R3e>;=k_6F63XB1HFB!rB delta 57 zcmbQj^n-DNvH~ju0|N^Xb3UKr!0^rezQ8~C)eK&@L=3#A|8ihtV4V0+dt!w$BkROD J2FzftF#zvl5wHLN diff --git a/lib/pytz/zoneinfo/Antarctica/Palmer b/lib/pytz/zoneinfo/Antarctica/Palmer index 614c9b97b40da921c3fefbeb80047306149eabfa..c51d91e64ccf0a3951ab5d082765673a6fb4c62f 100644 GIT binary patch delta 340 zcmaFlbjD?aA*0%RCIgR;We%Qu@(sK$MmTuyVA$ZZ(aOR17`uUAK+^&LIqNnAINjVF z&bXhEF?X{#vnUfYP|IX}R#`2eQU)LZDF@LYEg%}C4Mc;qf@qNTGFC^4dLWxwo7)*A z$gHE8?f|A=tAhD@oStC5-f4C)U;m{xm~XH}#Q>zv@FXvoZ#0Ds%r{=~9?Ul>egWp2 zPU1cQQfC%?3d}bzd<*7V7_R~IEd$R7f(5K(PHX@vv^Lxb=3D<+1?JldP6qRB@AQEA vb{|W@eEU6lV7|kxNe&D^eU5Vizn0ns3BAR43qt%wdgiI=+ks>2RZ{2+ov2ok$R_`IK<%j@BH`@TOlcg?-|uFIVIBE`Z> zF&1mfXns*#IMtM~=nFOOnUnG0yo&EC4Yf3Yk8vGnJ#_%9$OVP5l;EhY!hX;m_iF_fMHS{zl|}yq9_BN0r~+kcICpbz`kA zZ*DzN;#PfK7grys$>Nf}{V1vKoGXJ7sO20h1+;c*dI{`Vp z`%lcg?U$7gT0DIEM^<0|RkNjzG#`IcjTOgoqv>$92AoAF*BREwg~*l2rO36&#mLpj z<+j%KNC8``0#X90ffPZiAZ5@b4?iSAG9jsuTu3q`8@|No9007#SBMgRZ+ delta 659 zcmW;JPe{{Y9LMorTZbXRY@mWDhICw;izHA4@!(1Ean;&p)2CJ&+uTyiZE9{ZA^LMD zn9`x5AdtL7I6bJBK(HW)M>}A`>amb_f+CXRVNQCD)s4` z9^YA3BK_(}WZw9LA@M7B00^XFPbUZ?cT z@jo&9Wl+z3*W%H8uby8&RfUD~y0~LD zH7Oe8<$=UVW+XL|8%d62N75ttkqIo#8IUO~%{h=skXevv45QI7*oOx;LUt-&a46Rm SkI&QT?QjqJIy{~H)%^!!ZruX_ diff --git a/lib/pytz/zoneinfo/Asia/Gaza b/lib/pytz/zoneinfo/Asia/Gaza index 063ed39e8d8c3c2a85331edad4ed6797109c0097..6f1cabc291503b7c3e7148e1fc20cb6193cbc056 100644 GIT binary patch delta 59 zcmeyzJ&R|8GGp9El?q07|B~AY0V(??&t{CB{Eab$leFty|Z_MN`*P>z;X|o(pq!wd09;i;~uN{*L-X_Y^PeSA1(o*Y;|4eZ5WtUruUp zxlD<*ntB_WJ*?zXiQS0**3G-wcB|o#4flPwk;pF_t=_b;ypJ{>-q!ffRh!6tr-}Cq zHo5a$Q!i4M+I*ntg-4osHlo{;Q}X7U(?!9Gv;sN*{K2$>v+3P{d-khinW0QC!+pFR zc|Xzs>43CAdLT`ZF21e}(#O{|LOLO>kX}eLblp7vKs+u8h(ts}A~BJmNK_;&5*G>V z>mnnek=RIZBswP6yc**`d}IJ*1Y`(g3}g^w6l54=9AqG0Hxe?GuNw;)3>ghm$K7%q hSPxkcSrPxge}r>_GNbE86&c3K0!%K9tdl#LlsFhz{{O#vfstkMW+ppEx6PlJESM&rVsm9= Yo9x1_!NI@*mgSgS!mh#+9AeA`0Q|ufkpKVy delta 737 zcmXZZO-PhM9LI4-9%-$lLk30*hPy?FZ82P=C?f3TkZg|avsk&=m?E01nJ<{TTTh21 zdV}DhOJ#IOf}}%45LD1X39G{pQ4k#lEIK3|!XUcXe1`^x&;R`W%~n2Ib0a1u9>=31 zXt|Qrvgx;J9T}E~>pq!G#+Ux8C6#Sxl-VC2RomJc+4lCCI`ZqUJUVkr9ee*pwqGr& z-19&Bcz=iLxcyn5@C!y2U+B(M&YWz&tGlXqo9>+#bobIm(-WVPJs-+VuNTPPm$j6QUNJ})If?LRgf}HTL&rRw3U!jNG+roQVl7G zwqBq(NQh)aQX)B#q)1jIt<&a35<6{XB(>A#Mv^1hk@T1^1q+IU36L3(DUdmkNsw8P zX^?r4iJW#OWGbhf3z-a=4Vey$F}oiJ8zMU*TcX=@v$sEN@uK#x5A)uZh={l?tHL{8 ae4U><(46rT=^e>!$@)Y(m261Xulxr&R_yWs diff --git a/lib/pytz/zoneinfo/Canada/Atlantic b/lib/pytz/zoneinfo/Canada/Atlantic index b98c3a77340fe1d504a65a3cc4022e8760575cf4..756099abe6cee44295a5566ad6cd0c352fb82e64 100644 GIT binary patch delta 21 bcmaDL^+0NZEz_>M8|~k*0IALTtcDx_ZA}RF delta 21 bcmaDL^+0NZEz<$zjrQ+YfYfGvRznT|U;PJ; diff --git a/lib/pytz/zoneinfo/Canada/Central b/lib/pytz/zoneinfo/Canada/Central index 5f9e35c391b53a98e4434412f51fffcd2e475d48..2d22791686e86b2f17a0f7fa53ad71f03a3384fc 100644 GIT binary patch delta 21 bcmdlewozjn*nGKx%U$%LO(7Q_=@q diff --git a/lib/pytz/zoneinfo/Canada/East-Saskatchewan b/lib/pytz/zoneinfo/Canada/East-Saskatchewan index fa9c6eec2fcd0657018bb99e86a84ec6ebcb6a01..20c9c84df491e4072ec4c5d2c931a7433d9fd394 100644 GIT binary patch delta 21 bcmcb@euaI4DbsHDjppr)Kx*>=MiC|eRm}$e delta 21 bcmcb@euaI4DboSpjppr)Kx*>=MiC|eTWANA diff --git a/lib/pytz/zoneinfo/Canada/Eastern b/lib/pytz/zoneinfo/Canada/Eastern index b126bc641119caf0dad771d7ba2d248d6c44f086..1698477a48773fb8f306dc4e8f106011d4d1a60b 100644 GIT binary patch delta 21 bcmbO#Jym*wA=9qc8;w7)0IALDta%&&Vgm@D delta 21 bcmbO#Jym*wA=3fFjmDo?fYfGn);taXRI>*+ diff --git a/lib/pytz/zoneinfo/Canada/Mountain b/lib/pytz/zoneinfo/Canada/Mountain index ba6dbb46cfabf01e9890972ad699d3c96d0e982c..3fa0579891a9762b7c131ec5ece5d6d02495bfc0 100644 GIT binary patch delta 21 bcmca2bVX=_DbsHDjpilHKx*?^=H;vaSEdJu delta 21 bcmca2bVX=_DboSpjpilHKx*?^=H;vaT|o#Q diff --git a/lib/pytz/zoneinfo/Canada/Newfoundland b/lib/pytz/zoneinfo/Canada/Newfoundland index 27416c3797327dd0451404b37be7e866b46af759..e7a18d601d0255c26885313540cbe755e009a77d 100644 GIT binary patch delta 21 bcmdlcvrT4#CDX2J8?9|wfz;+I);$~mVR;C) delta 21 bcmdlcvrT4#CDQ?!jn=lTKx%Up>mCjOR4E5e diff --git a/lib/pytz/zoneinfo/Canada/Pacific b/lib/pytz/zoneinfo/Canada/Pacific index b69358c4502ef8eb0af82a82373e90ccbb5d4ac4..0c1fa52690498b3cd087a90ba9ba4d4f0467d532 100644 GIT binary patch delta 21 bcmdljwp(n1A=7TrjmFX}Kx%UU%WF0OP@4w> delta 21 bcmdljwp(n1A=82AjmFX}Kx%UU%WF0ORyGHj diff --git a/lib/pytz/zoneinfo/Canada/Saskatchewan b/lib/pytz/zoneinfo/Canada/Saskatchewan index fa9c6eec2fcd0657018bb99e86a84ec6ebcb6a01..20c9c84df491e4072ec4c5d2c931a7433d9fd394 100644 GIT binary patch delta 21 bcmcb@euaI4DbsHDjppr)Kx*>=MiC|eRm}$e delta 21 bcmcb@euaI4DboSpjppr)Kx*>=MiC|eTWANA diff --git a/lib/pytz/zoneinfo/Chile/Continental b/lib/pytz/zoneinfo/Chile/Continental index a8cafe6a88993c1e006477f10b9e7dfabcc5a43a..de74ddf1a095c9b3d026dfe928a3962da8e42339 100644 GIT binary patch delta 67 zcmeD7nCr3ODkIyRbsGYlZf?HKc%6~4fAePMRAw%q5Caf^gq7GCCHaADX2&@JAVFrQ QT_u~96#AGauTzc%09Ah$fB*mh delta 51 zcmbR1(e1I}DkEErs6jxL#pc_L*BKdmH*aQ6W#$43F#rKbSc#oca%FzJ0 Cx(~Vl diff --git a/lib/pytz/zoneinfo/Chile/EasterIsland b/lib/pytz/zoneinfo/Chile/EasterIsland index 1f7bae5373b932a230b0922e7a76f373bb70596b..de6b8ff5839fdbdbcab3ac440f8e00a7af78f18c 100644 GIT binary patch delta 67 zcmbR1w%%>SOh&dj>ox>9-P}B%aTgAqF4-2?w$7ZH{7o%ftl~VgLe=a3C9_Dt>auFLUUV~xWG=go4ZaSt?izJF}wa6)((X7$z%a3vz(`uTr>;^$! zM7(f=a1kVkxCkkAGG=JT@e_El{?a7*{+dNjQ$r}c5j`wFC?`iwo^LZ zt7JLPqhIyd)@O3O>y4hM9+RHtY3;3e zqJ67X`@Y=M{=dU|@^wj1eaz^mdd)@b$)?1j;J!0^cUNB|@P5(0^V1VN%8VURdh69|cfghFEBz*La6 z7ozcia7a8PAQBM?iNr*LB2kgBNL;H4j6}AY&`4|?S#OGSp*m6?sgJw?Xy1Yz?)LDC uTfXGE?xw;IZp~)?_@CFnJd65%X2V9`PiMTAhT5juWL<;TQlGT9#^@r{rR5#~ delta 174 zcmeAaSi&_yT$GoAfdPa;zzK*!Y^9Al9E_7Wm>d~-Cf750urV-b88FCAKF%a3=jIv$ zQpv~&#*82u27nx(d3-=F2!nt#5QErin>Cpwm?pnub7JJ3oXGA6F;HppdUhpssDW5b O1PU^80Tt*Pa{&Omo)T^V diff --git a/lib/pytz/zoneinfo/Europe/Simferopol b/lib/pytz/zoneinfo/Europe/Simferopol index 08efa510178f2dcf5ef4d6ebb9e5f4bae7cc355d..ebb63b4450b0ac035c09d064ab515eb016850ff1 100644 GIT binary patch delta 882 zcmbW#J!n%=7>DtDO9s8E@>U4xVhXw_#x}K9J6Lq^R);29lh$fl>sLRtG1{sn>4$d^ zM2g4@SC9^Zf|L$YlvW)aL=kb2;!;%5#Ysd&P$>?A=Q-daP9_|FCpVDc|Ky$bL^K|& zbR37nYs?((iF?UvH^|(%rF)7+*?Z-pw(XzPeT81lZY^l8b(glsGun|{uN_M%?TocZ z=j&B^;Kw>S_~5(d7d`2^StZ@`pXE^SO?s{^$l;zvIWqA{k8Xb`$GTtY@tP^=ZJyP> zW%spzwQB#z>pJjjSWmnt>&f>y9h}LxYvK8joVwhs#p$e^9;neXml|cLZJP}D#pP^$ zLeBX=<$RSRBXuzy`T9XhE0?tN>Y0?kyw%aW(=xX3NXMt1>cs2~y->cb!PP*+ovt4S zuJ`wecu_AJPP)6pH*TWZY~Z@~z@L}v>e}Vw=FpEOpv!1O7VbNNHL@uQVywy6htZ_C6Ss)QLCwnl(m|=NMRh^U@~(dHIf@ij$}uh zz7%QM60Q87clbDxiL|D34*!lOe()cE5A)3P{oKY)zMst{(+#zawW+#>WV$|OZ=1c} D7kk`W delta 170 zcmX>oaEEJx_+$-c9!@s~1_oXrR@$f|!8loh$(503@?<6tHUr;t8^QoG TR2^z4R#Sn3j9fqky2e}p=n)j6 diff --git a/lib/pytz/zoneinfo/Europe/Uzhgorod b/lib/pytz/zoneinfo/Europe/Uzhgorod index 00584c1fca222e39b8e11198c7e7df60cf4eeaf5..7032ab9b34f97640d1ef631dc4cc790abeeed606 100644 GIT binary patch delta 834 zcmZ9}O-NK>6o>J9Wr!L~j=?Y@q>DC2la89yLTORAS~ycSS2HIw&98DA(@LBvyFm~U z5eIG%E~J7G7a>Jog1d-l5knh^7HwKZLmB==G1TBubuIFfuYUGBz?eGCDFmGCmRjiGYN#nixnBBnlD+#}Rcu7A1z?{30JJhKA(VYU9W2w`U;udGA^Du4p_~ z={OFDSJ52qi3dq>gUr2Ky1P)2Jy$Mh`@YM%H$R}+&3X0Pc4|jFqn*k1+PRq0uGkLg zdb>)yf7HnS$KN%#5S0TrtEA`AXXy>TN#C`y9PC?=LsOsh@YW~N-}73JR8Px5>zocQ zo!6l?szV>I>+r8}J^HGs$KLxoGMnqr{L3*peyLRpGg%oOuGSM5n`ErLMaBo?ax|mLU{UDPo7j^Q@3n_kir=|Nda;E%L&rUzrsks|^u6Rd-tAU0s?zV8$ zmA}rC@VvV#EW3%-=3jSRd*IK@b#>jclKHg4oV5>|D{3kNzGEL`BV;FJD`YQZGh{bp zJ7hnr*$~;$YPLl7L^efsMYC;SFAU5BMn;B4#zqE5Mn{H6#zz7m5s(m869Wl?L_xyf z$ZU|a7XtBsNJuCo77`4JhJ-`nApwzyNJy)Ri3GKps7P2WZ7_AYP#CFf8OEkNG8&j_8op5TljSOh&dj>ox>9-P}B%aTgAqF4-2?w$7ZH{7o%ftl~VgLe=a3C9_NNVL0-Dfg!{@1jJ+r!EOjMPzr=W w0Av7&&G8=y>dZqsK!RWcng0KeuV7#Ro67<=m&M071a3A10~gR5T|*Nt06uCSE&u=k literal 140 zcmWHE%1kq2zyORu5fFv}5S!)y|KbD&h7j)%ASVR7J|>_P2!jAf4~Wh29|-EqLpvD% a|BtU=U;rD#;^P|vHHv|O3uvaH0T%#d-4(h3 diff --git a/lib/pytz/zoneinfo/Pacific/Fiji b/lib/pytz/zoneinfo/Pacific/Fiji index b2f6cac9c242ee4dfdf104cdfb314c2ac5f7f65d..797842aa3e1e02795df1f57e7382e31a456322ae 100644 GIT binary patch delta 56 zcmZ3%bcAVwG9&jy6&)_WMQ0NHrH(vcVw@Nd2ozcrAjAL!AYl*ib diff --git a/lib/pytz/zoneinfo/iso3166.tab b/lib/pytz/zoneinfo/iso3166.tab index 950c40f1db66..b952ca1c5900 100644 --- a/lib/pytz/zoneinfo/iso3166.tab +++ b/lib/pytz/zoneinfo/iso3166.tab @@ -1,5 +1,4 @@ #
-# @(#)iso3166.tab	8.11
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 # ISO 3166 alpha-2 country codes
diff --git a/lib/pytz/zoneinfo/zone.tab b/lib/pytz/zoneinfo/zone.tab
index f197b948dd97..6bda8266ba97 100644
--- a/lib/pytz/zoneinfo/zone.tab
+++ b/lib/pytz/zoneinfo/zone.tab
@@ -1,5 +1,4 @@
 # 
-# @(#)zone.tab	8.49
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 #
@@ -131,6 +130,7 @@ CA	+5333-11328	America/Edmonton	Mountain Time - Alberta, east British Columbia &
 CA	+690650-1050310	America/Cambridge_Bay	Mountain Time - west Nunavut
 CA	+6227-11421	America/Yellowknife	Mountain Time - central Northwest Territories
 CA	+682059-1334300	America/Inuvik	Mountain Time - west Northwest Territories
+CA	+4906-11631	America/Creston	Mountain Standard Time - Creston, British Columbia
 CA	+5946-12014	America/Dawson_Creek	Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia
 CA	+4916-12307	America/Vancouver	Pacific Time - west British Columbia
 CA	+6043-13503	America/Whitehorse	Pacific Time - south Yukon
@@ -333,7 +333,7 @@ RS	+4450+02030	Europe/Belgrade
 RU	+5443+02030	Europe/Kaliningrad	Moscow-01 - Kaliningrad
 RU	+5545+03735	Europe/Moscow	Moscow+00 - west Russia
 RU	+4844+04425	Europe/Volgograd	Moscow+00 - Caspian Sea
-RU	+5312+05009	Europe/Samara	Moscow - Samara, Udmurtia
+RU	+5312+05009	Europe/Samara	Moscow+00 - Samara, Udmurtia
 RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
 RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
 RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
diff --git a/setup.py b/setup.py
index 62a8888d4fab..6340514b5619 100644
--- a/setup.py
+++ b/setup.py
@@ -48,7 +48,7 @@
      check_for_qt, check_for_qt4, check_for_pyside, check_for_cairo, \
      check_provide_pytz, check_provide_dateutil,\
      check_for_dvipng, check_for_ghostscript, check_for_latex, \
-     check_for_pdftops, check_for_datetime, options, build_png, build_tri
+     check_for_pdftops, options, build_png, build_tri
 
 # jdh
 packages = [
@@ -108,6 +108,8 @@
                               'backends/Matplotlib.nib/*',
                               ]}
 
+package_dir = {'': 'lib'}
+
 if 1:
     # TODO: exclude these when making release?
     baseline_images = glob.glob(os.path.join('lib','matplotlib','tests',
@@ -187,46 +189,46 @@ def chop_package(fname):
 print_raw("")
 print_raw("OPTIONAL DATE/TIMEZONE DEPENDENCIES")
 
-hasdatetime = check_for_datetime()
-provide_dateutil = check_provide_dateutil(hasdatetime)
-provide_pytz = check_provide_pytz(hasdatetime)
-
-if hasdatetime: # dates require python23 datetime
-    # only install pytz and dateutil if the user hasn't got them
-
-    def add_pytz():
-        packages.append('pytz')
-
-        resources = ['zone.tab', 'locales/pytz.pot']
-        for dirpath, dirnames, filenames in os.walk(
-            os.path.join('lib', 'pytz', 'zoneinfo')
-            ):
-
-            # remove the 'pytz' part of the path
-            basepath = os.path.join(*dirpath.split(os.path.sep)[2:])
-            #print dirpath, basepath
-            resources.extend([os.path.join(basepath, filename)
-                              for filename in filenames])
-        package_data['pytz'] = resources
-        #print resources
-        assert len(resources) > 10, 'zoneinfo files not found!'
-
-
-    def add_dateutil():
-        packages.append('dateutil')
-        packages.append('dateutil.zoneinfo')
-        package_data['dateutil'] = ['zoneinfo/zoneinfo*.tar.*']
+provide_dateutil = check_provide_dateutil()
+provide_pytz = check_provide_pytz()
+
+def add_pytz():
+    packages.append('pytz')
+
+    resources = ['zone.tab', 'locales/pytz.pot']
+    for dirpath, dirnames, filenames in os.walk(
+        os.path.join('lib', 'pytz', 'zoneinfo')
+        ):
+
+        # remove the 'pytz' part of the path
+        basepath = os.path.join(*dirpath.split(os.path.sep)[2:])
+        #print dirpath, basepath
+        resources.extend([os.path.join(basepath, filename)
+                          for filename in filenames])
+    package_data['pytz'] = resources
+    #print resources
+    assert len(resources) > 10, 'zoneinfo files not found!'
+
+def add_dateutil():
+    packages.append('dateutil')
+    packages.append('dateutil.zoneinfo')
+    package_data['dateutil'] = ['zoneinfo/zoneinfo*.tar.*']
+    if sys.version_info[0] >= 3:
+        package_dir['dateutil'] = 'lib/dateutil_py3'
+    else:
+        package_dir['dateutil'] = 'lib/dateutil_py2'
 
-    if sys.platform=='win32':
-        # always add these to the win32 installer
+if sys.platform=='win32':
+    # always add these to the win32 installer
+    add_pytz()
+    add_dateutil()
+else:
+    # only add them if we need them
+    if provide_pytz:
         add_pytz()
+        print_raw("adding pytz")
+    if provide_dateutil:
         add_dateutil()
-    else:
-        # only add them if we need them
-        if provide_pytz:
-            add_pytz()
-            print_raw("adding pytz")
-        if provide_dateutil: add_dateutil()
 
 print_raw("")
 print_raw("OPTIONAL USETEX DEPENDENCIES")
@@ -259,8 +261,15 @@ def add_dateutil():
         mod.extra_compile_args.append('-DVERBOSE')
 
 if sys.version_info[0] >= 3:
+    def should_2to3(file, root):
+        file = os.path.abspath(file)[len(os.path.abspath(root)):]
+        if ('py3' in file or
+            file.startswith('pytz') or
+            file.startswith('dateutil')):
+            return False
+        return True
+
     import multiprocessing
-    from distutils import util
     def refactor(x):
         from lib2to3.refactor import RefactoringTool, get_fixers_from_package
         class DistutilsRefactoringTool(RefactoringTool):
@@ -276,7 +285,7 @@ class build_py(original_build_py):
         def run_2to3(self, files):
             # We need to skip certain files that have already been
             # converted to Python 3.x
-            filtered = [x for x in files if 'py3' not in x]
+            filtered = [x for x in files if should_2to3(x, self.build_lib)]
             if sys.platform.startswith('win'):
                 # doing this in parallel on windows may crash your computer
                 [refactor(f) for f in filtered]
@@ -306,7 +315,7 @@ def run_2to3(self, files):
       platforms='any',
       py_modules = py_modules,
       ext_modules = ext_modules,
-      package_dir = {'': 'lib'},
+      package_dir = package_dir,
       package_data = package_data,
       cmdclass = {'build_py': build_py},
       **additional_params
diff --git a/setupext.py b/setupext.py
index 7dc1e2a9285b..b5d8c0c7d200 100644
--- a/setupext.py
+++ b/setupext.py
@@ -431,24 +431,14 @@ def check_for_cairo():
         print_status("Cairo", cairo.version)
         return True
 
-def check_for_datetime():
-    try:
-        import datetime
-    except ImportError:
-        print_status("datetime", "no")
-        return False
-    else:
-        print_status("datetime", "present, version unknown")
-        return True
-
-def check_provide_pytz(hasdatetime=True):
-    if hasdatetime and (options['provide_pytz'] is True):
+def check_provide_pytz():
+    if options['provide_pytz'] is True:
         print_status("pytz", "matplotlib will provide")
         return True
     try:
         import pytz
     except ImportError:
-        if hasdatetime and options['provide_pytz']:
+        if options['provide_pytz']:
             print_status("pytz", "matplotlib will provide")
             return True
         else:
@@ -462,14 +452,14 @@ def check_provide_pytz(hasdatetime=True):
             print_status("pytz", pytz.__version__)
             return False
 
-def check_provide_dateutil(hasdatetime=True):
-    if hasdatetime and (options['provide_dateutil'] is True):
+def check_provide_dateutil():
+    if options['provide_dateutil'] is True:
         print_status("dateutil", "matplotlib will provide")
         return True
     try:
         import dateutil
     except ImportError:
-        if hasdatetime and options['provide_dateutil']:
+        if options['provide_dateutil']:
             print_status("dateutil", "matplotlib will provide")
             return True
         else: