Merge branch 'unidata_15.1.1' of github.com:Unidata/awips2 into unidata_15.1.1
Former-commit-id: 3018131470
This commit is contained in:
commit
8b9529075e
37 changed files with 5753 additions and 23 deletions
BIN
pythonPackages/cython/Cython-0.23.4.tar.gz
Normal file
BIN
pythonPackages/cython/Cython-0.23.4.tar.gz
Normal file
Binary file not shown.
1
pythonPackages/pint
Submodule
1
pythonPackages/pint
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit b2287c5e0f345bcc691d158324b2abeddbb51962
|
31
pythonPackages/python-dateutil/LICENSE
Normal file
31
pythonPackages/python-dateutil/LICENSE
Normal file
|
@ -0,0 +1,31 @@
|
|||
dateutil - Extensions to the standard Python datetime module.
|
||||
|
||||
Copyright (c) 2003-2011 - Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
Copyright (c) 2012-2014 - Tomi Pieviläinen <tomi.pievilainen@iki.fi>
|
||||
Copyright (c) 2014 - Yaron de Leeuw <me@jarondl.net>
|
||||
|
||||
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.
|
1
pythonPackages/python-dateutil/MANIFEST.in
Normal file
1
pythonPackages/python-dateutil/MANIFEST.in
Normal file
|
@ -0,0 +1 @@
|
|||
include LICENSE NEWS zonefile_metadata.json updatezinfo.py
|
322
pythonPackages/python-dateutil/NEWS
Normal file
322
pythonPackages/python-dateutil/NEWS
Normal file
|
@ -0,0 +1,322 @@
|
|||
Version 2.5.0
|
||||
-------------
|
||||
- Updated zoneinfo to 2016a
|
||||
- zoneinfo_metadata file version increased to 2.0 - the updated updatezinfo.py
|
||||
script will work with older zoneinfo_metadata.json files, but new metadata
|
||||
files will not work with older updatezinfo.py versions. Additionally, we have
|
||||
started hosting our own mirror of the Olson databases on a github pages
|
||||
site (https://dateutil.github.io/tzdata/) (gh pr #183)
|
||||
- dateutil zoneinfo tarballs now contain the full zoneinfo_metadata file used
|
||||
to generate them. (gh issue #27, gh pr #85)
|
||||
- relativedelta can now be safely subclassed without derived objects reverting
|
||||
to base relativedelta objects as a result of arithmetic operations.
|
||||
(lp:1010199, gh issue #44, pr #49)
|
||||
- relativedelta 'weeks' parameter can now be set and retrieved as a property of
|
||||
relativedelta instances. (lp: 727525, gh issue #45, pr #49)
|
||||
- relativedelta now explicitly supports fractional relative weeks, days, hours,
|
||||
minutes and seconds. Fractional values in absolute parameters (year, day, etc)
|
||||
are now deprecated. (gh issue #40, pr #190)
|
||||
- relativedelta objects previously did not use microseconds to determine of two
|
||||
relativedelta objects were equal. This oversight has been corrected.
|
||||
Contributed by @elprans (gh pr #113)
|
||||
- rrule now has an xafter() method for retrieving multiple recurrences after a
|
||||
specified date. (gh pr #38)
|
||||
- str(rrule) now returns an RFC2445-compliant rrule string, contributed by
|
||||
@schinckel and @armicron (lp:1406305, gh issue #47, prs #50, #62 and #160)
|
||||
- rrule performance under certain conditions has been significantly improved
|
||||
thanks to a patch contributed by @dekoza, based on an article by Brian Beck
|
||||
(@exogen) (gh pr #136)
|
||||
- The use of both the 'until' and 'count' parameters is now deprecated as
|
||||
inconsistent with RFC2445 (gh pr #62, #185)
|
||||
- Parsing an empty string will now raise a ValueError, rather than returning the
|
||||
datetime passed to the 'default' parameter. (gh issue #78, pr #187)
|
||||
- tzwinlocal objects now have a meaningful repr() and str() implementation
|
||||
(gh issue #148, prs #184 and #186)
|
||||
- Added equality logic for tzwin and tzwinlocal objects. (gh issue #151,
|
||||
pr #180, #184)
|
||||
- Added some flexibility in subclassing timelex, and switched the default
|
||||
behavior over to using string methods rather than comparing against a fixed
|
||||
list. (gh pr #122, #139)
|
||||
- An issue causing tzstr() to crash on Python 2.x was fixed. (lp: 1331576,
|
||||
gh issue #51, pr #55)
|
||||
- An issue with string encoding causing exceptions under certain circumstances
|
||||
when tzname() is called was fixed. (gh issue #60, #74, pr #75)
|
||||
- Parser issue where calling parse() on dates with no day specified when the
|
||||
day of the month in the default datetime (which is "today" if unspecified) is
|
||||
greater than the number of days in the parsed month was fixed (this issue
|
||||
tended to crop up between the 29th and 31st of the month, for obvious reasons)
|
||||
(canonical gh issue #25, pr #30, #191)
|
||||
- Fixed parser issue causing fuzzy_with_tokens to raise an unexpected exception
|
||||
in certain circumstances. Contributed by @MichaelAquilina (gh pr #91)
|
||||
- Fixed parser issue where years > 100 AD were incorrectly parsed. Contributed
|
||||
by @Bachmann1234 (gh pr #130)
|
||||
- Fixed parser issue where commas were not a valid separator between seconds
|
||||
and microseconds, preventing parsing of ISO 8601 dates. Contributed by
|
||||
@ryanss (gh issue #28, pr #106)
|
||||
- Fixed issue with tzwin encoding in locales with non-Latin alphabets
|
||||
(gh issue #92, pr #98)
|
||||
- Fixed an issue where tzwin was not being properly imported on Windows.
|
||||
Contributed by @labrys. (gh pr #134)
|
||||
- Fixed a problem causing issues importing zoneinfo in certain circumstances.
|
||||
Issue and solution contributed by @alexxv (gh issue #97, pr #99)
|
||||
- Fixed an issue where dateutil timezones were not compatible with basic time
|
||||
objects. One of many, many timezone related issues contributed and tested by
|
||||
@labrys. (gh issue #132, pr #181)
|
||||
- Fixed issue where tzwinlocal had an invalid utcoffset. (gh issue #135,
|
||||
pr #141, #142)
|
||||
- Fixed issue with tzwin and tzwinlocal where DST transitions were incorrectly
|
||||
parsed from the registry. (gh issue #143, pr #178)
|
||||
- updatezinfo.py no longer suppresses certain OSErrors. Contributed by @bjamesv
|
||||
(gh pr #164)
|
||||
- An issue that arose when timezone locale changes during runtime has been
|
||||
fixed by @carlosxl and @mjschultz (gh issue #100, prs #107, #109)
|
||||
- Python 3.5 was added to the supported platforms in the metadata (@tacaswell
|
||||
gh pr #159) and the test suites (@moreati gh pr #117).
|
||||
- An issue with tox failing without unittest2 installed in Python 2.6 was fixed
|
||||
by @moreati (gh pr #115)
|
||||
- Several deprecated functions were replaced in the tests by @moreati
|
||||
(gh pr #116)
|
||||
- Improved the logic in Travis and Appveyor to alleviate issues where builds
|
||||
were failing due to connection issues when downloading the IANA timezone
|
||||
files. In addition to adding our own mirror for the files (gh pr #183), the
|
||||
download is now retried a number of times (with a delay) (gh pr #177)
|
||||
- Many failing doctests were fixed by @moreati. (gh pr #120)
|
||||
- Many fixes to the documentation (gh pr #103, gh pr #87 from @radarhere,
|
||||
gh pr #154 from @gpoesia, gh pr #156 from @awsum, gh pr #168 from @ja8zyjits)
|
||||
- Added a code coverage tool to the CI to help improve the library. (gh pr #182)
|
||||
- We now have a mailing list - dateutil@python.org, graciously hosted by
|
||||
Python.org.
|
||||
|
||||
|
||||
Version 2.4.2
|
||||
-------------
|
||||
- Updated zoneinfo to 2015b.
|
||||
- Fixed issue with parsing of tzstr on Python 2.7.x; tzstr will now be decoded
|
||||
if not a unicode type. gh #51 (lp:1331576), gh pr #55.
|
||||
- Fix a parser issue where AM and PM tokens were showing up in fuzzy date
|
||||
stamps, triggering inappropriate errors. gh #56 (lp: 1428895), gh pr #63.
|
||||
- Missing function "setcachesize" removed from zoneinfo __all__ list by @ryanss,
|
||||
fixing an issue with wildcard imports of dateutil.zoneinfo. (gh pr #66).
|
||||
- (PyPi only) Fix an issue with source distributions not including the test
|
||||
suite.
|
||||
|
||||
|
||||
Version 2.4.1
|
||||
-------------
|
||||
|
||||
- Added explicit check for valid hours if AM/PM is specified in parser.
|
||||
(gh pr #22, issue #21)
|
||||
- Fix bug in rrule introduced in 2.4.0 where byweekday parameter was not
|
||||
handled properly. (gh pr #35, issue #34)
|
||||
- Fix error where parser allowed some invalid dates, overwriting existing hours
|
||||
with the last 2-digit number in the string. (gh pr #32, issue #31)
|
||||
- Fix and add test for Python 2.x compatibility with boolean checking of
|
||||
relativedelta objects. Implemented by @nimasmi (gh pr #43) and Cédric Krier
|
||||
(lp: 1035038)
|
||||
- Replaced parse() calls with explicit datetime objects in unit tests unrelated
|
||||
to parser. (gh pr #36)
|
||||
- Changed private _byxxx from sets to sorted tuples and fixed one currently
|
||||
unreachable bug in _construct_byset. (gh pr #54)
|
||||
- Additional documentation for parser (gh pr #29, #33, #41) and rrule.
|
||||
- Formatting fixes to documentation of rrule and README.rst.
|
||||
- Updated zoneinfo to 2015a.
|
||||
|
||||
Version 2.4.0
|
||||
-------------
|
||||
|
||||
- Fix an issue with relativedelta and freezegun (lp:1374022)
|
||||
- Fix tzinfo in windows for timezones without dst (lp:1010050, gh #2)
|
||||
- Ignore missing timezones in windows like in POSIX
|
||||
- Fix minimal version requirement for six (gh #6)
|
||||
- Many rrule changes and fixes by @pganssle (gh pull requests #13 #14 #17),
|
||||
including defusing some infinite loops (gh #4)
|
||||
|
||||
Version 2.3
|
||||
-----------
|
||||
|
||||
- Cleanup directory structure, moved test.py to dateutil/tests/test.py
|
||||
|
||||
- Changed many aspects of dealing with the zone info file. Instead of a cache,
|
||||
all the zones are loaded to memory, but symbolic links are loaded only once,
|
||||
so not much memory is used.
|
||||
|
||||
- The package is now zip-safe, and universal-wheelable, thanks to changes in
|
||||
the handling of the zoneinfo file.
|
||||
|
||||
- Fixed tzwin silently not imported on windows python2
|
||||
|
||||
- New maintainer, together with new hosting: GitHub, Travis, Read-The-Docs
|
||||
|
||||
Version 2.2
|
||||
-----------
|
||||
|
||||
- Updated zoneinfo to 2013h
|
||||
|
||||
- fuzzy_with_tokens parse addon from Christopher Corley
|
||||
|
||||
- Bug with LANG=C fixed by Mike Gilbert
|
||||
|
||||
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.
|
||||
|
27
pythonPackages/python-dateutil/PKG-INFO
Normal file
27
pythonPackages/python-dateutil/PKG-INFO
Normal file
|
@ -0,0 +1,27 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: python-dateutil
|
||||
Version: 2.5.0
|
||||
Summary: Extensions to the standard Python datetime module
|
||||
Home-page: https://dateutil.readthedocs.org
|
||||
Author: Paul Ganssle, Yaron de Leeuw
|
||||
Author-email: dateutil@python.org
|
||||
License: Simplified BSD
|
||||
Description:
|
||||
The dateutil module provides powerful extensions to the
|
||||
datetime module available in the Python standard library.
|
||||
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.2
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Topic :: Software Development :: Libraries
|
||||
Requires: six
|
143
pythonPackages/python-dateutil/README.rst
Normal file
143
pythonPackages/python-dateutil/README.rst
Normal file
|
@ -0,0 +1,143 @@
|
|||
dateutil - powerful extensions to datetime
|
||||
==========================================
|
||||
|
||||
.. image:: https://img.shields.io/travis/dateutil/dateutil/master.svg?style=flat-square
|
||||
:target: https://travis-ci.org/dateutil/dateutil
|
||||
:alt: travis build status
|
||||
|
||||
.. image:: https://img.shields.io/appveyor/ci/dateutil/dateutil/master.svg?style=flat-square
|
||||
:target: https://ci.appveyor.com/project/dateutil/dateutil
|
||||
:alt: appveyor build status
|
||||
|
||||
.. image:: https://codecov.io/github/dateutil/dateutil/coverage.svg?branch=master
|
||||
:target: https://codecov.io/github/dateutil/dateutil?branch=master
|
||||
:alt: Code coverage
|
||||
|
||||
.. image:: https://img.shields.io/pypi/dd/python-dateutil.svg?style=flat-square
|
||||
:target: https://pypi.python.org/pypi/python-dateutil/
|
||||
:alt: pypi downloads per day
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/python-dateutil.svg?style=flat-square
|
||||
:target: https://pypi.python.org/pypi/python-dateutil/
|
||||
:alt: pypi version
|
||||
|
||||
|
||||
The `dateutil` module provides powerful extensions to
|
||||
the standard `datetime` module, available in Python.
|
||||
|
||||
|
||||
Download
|
||||
========
|
||||
dateutil is available on PyPI
|
||||
https://pypi.python.org/pypi/python-dateutil/
|
||||
|
||||
The documentation is hosted at:
|
||||
https://dateutil.readthedocs.org/
|
||||
|
||||
Code
|
||||
====
|
||||
https://github.com/dateutil/dateutil/
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
* Computing of relative deltas (next month, next year,
|
||||
next monday, last week of month, etc);
|
||||
* Computing of relative deltas between two given
|
||||
date and/or datetime objects;
|
||||
* Computing of dates based on very flexible recurrence rules,
|
||||
using a superset of the `iCalendar <https://www.ietf.org/rfc/rfc2445.txt>`_
|
||||
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;
|
||||
* A comprehensive test suite.
|
||||
|
||||
Quick example
|
||||
=============
|
||||
Here's a snapshot, just to give an idea about the power of the
|
||||
package. For more examples, look at the documentation.
|
||||
|
||||
Suppose you want to know how much time is left, in
|
||||
years/months/days/etc, before the next easter happening on a
|
||||
year with a Friday 13th in August, and you want to get today's
|
||||
date out of the "date" unix system command. Here is the code:
|
||||
|
||||
.. doctest:: readmeexample
|
||||
|
||||
>>> from dateutil.relativedelta import *
|
||||
>>> from dateutil.easter import *
|
||||
>>> from dateutil.rrule import *
|
||||
>>> from dateutil.parser import *
|
||||
>>> from datetime import *
|
||||
>>> now = parse("Sat Oct 11 17:13:46 UTC 2003")
|
||||
>>> today = now.date()
|
||||
>>> year = rrule(YEARLY,dtstart=now,bymonth=8,bymonthday=13,byweekday=FR)[0].year
|
||||
>>> rdelta = relativedelta(easter(year), today)
|
||||
>>> print("Today is: %s" % today)
|
||||
Today is: 2003-10-11
|
||||
>>> print("Year with next Aug 13th on a Friday is: %s" % year)
|
||||
Year with next Aug 13th on a Friday is: 2004
|
||||
>>> print("How far is the Easter of that year: %s" % rdelta)
|
||||
How far is the Easter of that year: relativedelta(months=+6)
|
||||
>>> print("And the Easter of that year is: %s" % (today+rdelta))
|
||||
And the Easter of that year is: 2004-04-11
|
||||
|
||||
Being exactly 6 months ahead was **really** a coincidence :)
|
||||
|
||||
|
||||
Author
|
||||
======
|
||||
The dateutil module was written by Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
in 2003.
|
||||
|
||||
It is maintained by:
|
||||
|
||||
* Gustavo Niemeyer <gustavo@niemeyer.net> 2003-2011
|
||||
* Tomi Pieviläinen <tomi.pievilainen@iki.fi> 2012-2014
|
||||
* Yaron de Leeuw <me@jarondl.net> 2014-
|
||||
* Paul Ganssle <paul@ganssle.io> 2015-
|
||||
|
||||
Our mailing list is available at `dateutil@python.org <https://mail.python.org/mailman/listinfo/dateutil>`_. As it is hosted by the PSF, it is subject to the `PSF code of
|
||||
conduct <https://www.python.org/psf/codeofconduct/>`_.
|
||||
|
||||
Building and releasing
|
||||
======================
|
||||
When you get the source, it does not contain the internal zoneinfo
|
||||
database. To get (and update) the database, run the updatezinfo.py script. Make sure
|
||||
that the zic command is in your path, and that you have network connectivity
|
||||
to get the latest timezone information from IANA, or from `our mirror of the
|
||||
IANA database <https://dateutil.github.io/tzdata/>`_.
|
||||
|
||||
Starting with version 2.4.1, all source and binary distributions will be signed
|
||||
by a PGP key that has, at the very least, been signed by the key which made the
|
||||
previous release. A table of release signing keys can be found below:
|
||||
|
||||
=========== ============================
|
||||
Releases Signing key fingerprint
|
||||
=========== ============================
|
||||
2.4.1- `0xCD54FCE3D964BEFB`_
|
||||
=========== ============================
|
||||
|
||||
Testing
|
||||
=======
|
||||
dateutil has a comprehensive test suite, which can be run simply by running
|
||||
`python setup.py test [-q]` in the project root. Note that if you don't have the internal
|
||||
zoneinfo database, some tests will fail. Apart from that, all tests should pass.
|
||||
|
||||
To easily test dateutil against all supported Python versions, you can use
|
||||
`tox <https://tox.readthedocs.org/en/latest/>`_.
|
||||
|
||||
All github pull requests are automatically tested using travis and appveyor.
|
||||
|
||||
|
||||
.. _0xCD54FCE3D964BEFB:
|
||||
https://pgp.mit.edu/pks/lookup?op=vindex&search=0xCD54FCE3D964BEFB
|
2
pythonPackages/python-dateutil/dateutil/__init__.py
Normal file
2
pythonPackages/python-dateutil/dateutil/__init__.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
__version__ = "2.5.0"
|
89
pythonPackages/python-dateutil/dateutil/easter.py
Normal file
89
pythonPackages/python-dateutil/dateutil/easter.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
This module offers a generic easter computing method for any given year, using
|
||||
Western, Orthodox or Julian algorithms.
|
||||
"""
|
||||
|
||||
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))
|
1353
pythonPackages/python-dateutil/dateutil/parser.py
Normal file
1353
pythonPackages/python-dateutil/dateutil/parser.py
Normal file
File diff suppressed because it is too large
Load diff
516
pythonPackages/python-dateutil/dateutil/relativedelta.py
Normal file
516
pythonPackages/python-dateutil/dateutil/relativedelta.py
Normal file
|
@ -0,0 +1,516 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
import calendar
|
||||
|
||||
from six import integer_types
|
||||
from warnings import warn
|
||||
|
||||
__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 excellent
|
||||
work done by M.-A. Lemburg in his
|
||||
`mx.DateTime <http://www.egenix.com/files/python/mxDateTime.html>`_ 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 are two different ways to build a relativedelta instance. The
|
||||
first one is passing it two date/datetime classes::
|
||||
|
||||
relativedelta(datetime1, datetime2)
|
||||
|
||||
The second one is passing it any number of the following keyword arguments::
|
||||
|
||||
relativedelta(arg1=x,arg2=y,arg3=z...)
|
||||
|
||||
year, month, day, hour, minute, second, microsecond:
|
||||
Absolute information (argument is singular); adding or subtracting a
|
||||
relativedelta with absolute information does not perform an aritmetic
|
||||
operation, but rather REPLACES the corresponding value in the
|
||||
original datetime with the value(s) in relativedelta.
|
||||
|
||||
years, months, weeks, days, hours, minutes, seconds, microseconds:
|
||||
Relative information, may be negative (argument is plural); adding
|
||||
or subtracting a relativedelta with relative information performs
|
||||
the corresponding aritmetic operation on the original datetime value
|
||||
with the information in the relativedelta.
|
||||
|
||||
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):
|
||||
|
||||
# Check for non-integer values in integer-only quantities
|
||||
if any(x is not None and x != int(x) for x in (years, months)):
|
||||
raise ValueError("Non-integer years and months are "
|
||||
"ambiguous and not currently supported.")
|
||||
|
||||
if dt1 and dt2:
|
||||
# datetime is a subclass of date. So both must be date
|
||||
if not (isinstance(dt1, datetime.date) and
|
||||
isinstance(dt2, datetime.date)):
|
||||
raise TypeError("relativedelta only diffs datetime/date")
|
||||
|
||||
# We allow two dates, or two datetimes, so we coerce them to be
|
||||
# of the same type
|
||||
if (isinstance(dt1, datetime.datetime) !=
|
||||
isinstance(dt2, datetime.datetime)):
|
||||
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:
|
||||
# Relative information
|
||||
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
|
||||
|
||||
# Absolute information
|
||||
self.year = year
|
||||
self.month = month
|
||||
self.day = day
|
||||
self.hour = hour
|
||||
self.minute = minute
|
||||
self.second = second
|
||||
self.microsecond = microsecond
|
||||
|
||||
# Absolute information
|
||||
if any(x is not None and int(x) != x
|
||||
for x in (year, month, day, hour,
|
||||
minute, second, microsecond)):
|
||||
# For now we'll deprecate floats - later it'll be an error.
|
||||
warn("Non-integer value passed as absolute information. " +
|
||||
"This is not a well-defined condition and will raise " +
|
||||
"errors in future versions.", DeprecationWarning)
|
||||
|
||||
|
||||
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
|
||||
|
||||
@property
|
||||
def weeks(self):
|
||||
return self.days // 7
|
||||
@weeks.setter
|
||||
def weeks(self, value):
|
||||
self.days = self.days - (self.weeks * 7) + value * 7
|
||||
|
||||
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 normalized(self):
|
||||
"""
|
||||
Return a version of this object represented entirely using integer
|
||||
values for the relative attributes.
|
||||
|
||||
>>> relativedelta(days=1.5, hours=2).normalized()
|
||||
relativedelta(days=1, hours=14)
|
||||
|
||||
:return:
|
||||
Returns a :class:`dateutil.relativedelta.relativedelta` object.
|
||||
"""
|
||||
# Cascade remainders down (rounding each to roughly nearest microsecond)
|
||||
days = int(self.days)
|
||||
|
||||
hours_f = round(self.hours + 24 * (self.days - days), 11)
|
||||
hours = int(hours_f)
|
||||
|
||||
minutes_f = round(self.minutes + 60 * (hours_f - hours), 10)
|
||||
minutes = int(minutes_f)
|
||||
|
||||
seconds_f = round(self.seconds + 60 * (minutes_f - minutes), 8)
|
||||
seconds = int(seconds_f)
|
||||
|
||||
microseconds = round(self.microseconds + 1e6 * (seconds_f - seconds))
|
||||
|
||||
# Constructor carries overflow back up with call to _fix()
|
||||
return self.__class__(years=self.years, months=self.months,
|
||||
days=days, hours=hours, minutes=minutes,
|
||||
seconds=seconds, microseconds=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 __add__(self, other):
|
||||
if isinstance(other, relativedelta):
|
||||
return self.__class__(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 self.__class__(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 self.__class__(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)
|
||||
# Compatibility with Python 2.x
|
||||
__nonzero__ = __bool__
|
||||
|
||||
def __mul__(self, other):
|
||||
f = float(other)
|
||||
return self.__class__(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.microseconds == other.microseconds 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("{attr}={value:+g}".format(attr=attr, value=value))
|
||||
for attr in ["year", "month", "day", "weekday",
|
||||
"hour", "minute", "second", "microsecond"]:
|
||||
value = getattr(self, attr)
|
||||
if value is not None:
|
||||
l.append("{attr}={value}".format(attr=attr, value=repr(value)))
|
||||
return "{classname}({attrs})".format(classname=self.__class__.__name__,
|
||||
attrs=", ".join(l))
|
||||
|
||||
# vim:ts=4:sw=4:et
|
1550
pythonPackages/python-dateutil/dateutil/rrule.py
Normal file
1550
pythonPackages/python-dateutil/dateutil/rrule.py
Normal file
File diff suppressed because it is too large
Load diff
20
pythonPackages/python-dateutil/dateutil/tz/__init__.py
Normal file
20
pythonPackages/python-dateutil/dateutil/tz/__init__.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from .tz import *
|
||||
from six import PY3
|
||||
|
||||
__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
|
||||
"tzstr", "tzical", "tzwin", "tzwinlocal", "gettz"]
|
||||
|
||||
def tzname_in_python2(namefunc):
|
||||
"""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 adjust_encoding(*args, **kwargs):
|
||||
name = namefunc(*args, **kwargs)
|
||||
if name is not None and not PY3:
|
||||
name = name.encode()
|
||||
|
||||
return name
|
||||
|
||||
return adjust_encoding
|
979
pythonPackages/python-dateutil/dateutil/tz/tz.py
Normal file
979
pythonPackages/python-dateutil/dateutil/tz/tz.py
Normal file
|
@ -0,0 +1,979 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
This module offers timezone implementations subclassing the abstract
|
||||
:py:`datetime.tzinfo` type. There are classes to handle tzfile format files
|
||||
(usually are in :file:`/etc/localtime`, :file:`/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.
|
||||
"""
|
||||
import datetime
|
||||
import struct
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
|
||||
from six import string_types, PY3
|
||||
from .__init__ import tzname_in_python2
|
||||
|
||||
try:
|
||||
from .win import tzwin, tzwinlocal
|
||||
except ImportError:
|
||||
tzwin = tzwinlocal = None
|
||||
|
||||
relativedelta = None
|
||||
parser = None
|
||||
rrule = None
|
||||
|
||||
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):
|
||||
def __init__(self):
|
||||
self._std_offset = datetime.timedelta(seconds=-time.timezone)
|
||||
if time.daylight:
|
||||
self._dst_offset = datetime.timedelta(seconds=-time.altzone)
|
||||
else:
|
||||
self._dst_offset = self._std_offset
|
||||
|
||||
def utcoffset(self, dt):
|
||||
if dt is None:
|
||||
return 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):
|
||||
return (isinstance(other, tzlocal) and
|
||||
(self._std_offset == other._std_offset and
|
||||
self._dst_offset == other._dst_offset))
|
||||
|
||||
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, filename=None):
|
||||
file_opened_here = False
|
||||
if isinstance(fileobj, string_types):
|
||||
self._filename = fileobj
|
||||
fileobj = open(fileobj, 'rb')
|
||||
file_opened_here = True
|
||||
elif filename is not None:
|
||||
self._filename = filename
|
||||
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).
|
||||
try:
|
||||
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 **
|
||||
finally:
|
||||
if file_opened_here:
|
||||
fileobj.close()
|
||||
|
||||
# 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 dt is None:
|
||||
return None
|
||||
|
||||
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 dt is None:
|
||||
return None
|
||||
|
||||
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):
|
||||
if dt is None:
|
||||
return None
|
||||
|
||||
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 "<tzicalvtz %s>" % 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
|
||||
# ical should be encoded in UTF-8 with CRLF
|
||||
fileobj = open(fileobj, 'r')
|
||||
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 is not None:
|
||||
try:
|
||||
tz = tzwin(name)
|
||||
except WindowsError:
|
||||
tz = None
|
||||
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
|
316
pythonPackages/python-dateutil/dateutil/tz/win.py
Normal file
316
pythonPackages/python-dateutil/dateutil/tz/win.py
Normal file
|
@ -0,0 +1,316 @@
|
|||
# This code was originally contributed by Jeffrey Harris.
|
||||
import datetime
|
||||
import struct
|
||||
|
||||
from six.moves import winreg
|
||||
|
||||
try:
|
||||
import ctypes
|
||||
from ctypes import wintypes
|
||||
except ValueError:
|
||||
# ValueError is raised on non-Windows systems for some horrible reason.
|
||||
raise ImportError("Running tzwin on non-Windows system")
|
||||
|
||||
from .__init__ import tzname_in_python2
|
||||
|
||||
__all__ = ["tzwin", "tzwinlocal", "tzres"]
|
||||
|
||||
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():
|
||||
handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||
try:
|
||||
winreg.OpenKey(handle, TZKEYNAMENT).Close()
|
||||
TZKEYNAME = TZKEYNAMENT
|
||||
except WindowsError:
|
||||
TZKEYNAME = TZKEYNAME9X
|
||||
handle.Close()
|
||||
return TZKEYNAME
|
||||
|
||||
TZKEYNAME = _settzkeyname()
|
||||
|
||||
|
||||
class tzres(object):
|
||||
"""
|
||||
Class for accessing `tzres.dll`, which contains timezone name related
|
||||
resources.
|
||||
|
||||
..versionadded:: 2.5.0
|
||||
"""
|
||||
p_wchar = ctypes.POINTER(wintypes.WCHAR) # Pointer to a wide char
|
||||
|
||||
def __init__(self, tzres_loc='tzres.dll'):
|
||||
# Load the user32 DLL so we can load strings from tzres
|
||||
user32 = ctypes.WinDLL('user32')
|
||||
|
||||
# Specify the LoadStringW function
|
||||
user32.LoadStringW.argtypes = (wintypes.HINSTANCE,
|
||||
wintypes.UINT,
|
||||
wintypes.LPWSTR,
|
||||
ctypes.c_int)
|
||||
|
||||
self.LoadStringW = user32.LoadStringW
|
||||
self._tzres = ctypes.WinDLL(tzres_loc)
|
||||
self.tzres_loc = tzres_loc
|
||||
|
||||
def load_name(self, offset):
|
||||
"""
|
||||
Load a timezone name from a DLL offset (integer).
|
||||
|
||||
>>> from dateutil.tzwin import tzres
|
||||
>>> tzr = tzres()
|
||||
>>> print(tzr.load_name(112))
|
||||
'Eastern Standard Time'
|
||||
|
||||
:param offset:
|
||||
A positive integer value referring to a string from the tzres dll.
|
||||
|
||||
..note:
|
||||
Offsets found in the registry are generally of the form
|
||||
`@tzres.dll,-114`. The offset in this case if 114, not -114.
|
||||
|
||||
"""
|
||||
resource = self.p_wchar()
|
||||
lpBuffer = ctypes.cast(ctypes.byref(resource), wintypes.LPWSTR)
|
||||
nchar = self.LoadStringW(self._tzres._handle, offset, lpBuffer, 0)
|
||||
return resource[:nchar]
|
||||
|
||||
def name_from_string(self, tzname_str):
|
||||
"""
|
||||
Parse strings as returned from the Windows registry into the time zone
|
||||
name as defined in the registry.
|
||||
|
||||
>>> from dateutil.tzwin import tzres
|
||||
>>> tzr = tzres()
|
||||
>>> print(tzr.name_from_string('@tzres.dll,-251'))
|
||||
'Dateline Daylight Time'
|
||||
>>> print(tzr.name_from_string('Eastern Standard Time'))
|
||||
'Eastern Standard Time'
|
||||
|
||||
:param tzname_str:
|
||||
A timezone name string as returned from a Windows registry key.
|
||||
|
||||
:return:
|
||||
Returns the localized timezone string from tzres.dll if the string
|
||||
is of the form `@tzres.dll,-offset`, else returns the input string.
|
||||
"""
|
||||
if not tzname_str.startswith('@'):
|
||||
return tzname_str
|
||||
|
||||
name_splt = tzname_str.split(',-')
|
||||
try:
|
||||
offset = int(name_splt[1])
|
||||
except:
|
||||
raise ValueError("Malformed timezone string.")
|
||||
|
||||
return self.load_name(offset)
|
||||
|
||||
class tzwinbase(datetime.tzinfo):
|
||||
"""tzinfo class based on win32's timezones available in the registry."""
|
||||
def __eq__(self, other):
|
||||
# Compare on all relevant dimensions, including name.
|
||||
return (isinstance(other, tzwinbase) and
|
||||
(self._stdoffset == other._stdoffset and
|
||||
self._dstoffset == other._dstoffset and
|
||||
self._stddayofweek == other._stddayofweek and
|
||||
self._dstdayofweek == other._dstdayofweek and
|
||||
self._stdweeknumber == other._stdweeknumber and
|
||||
self._dstweeknumber == other._dstweeknumber and
|
||||
self._stdhour == other._stdhour and
|
||||
self._dsthour == other._dsthour and
|
||||
self._stdminute == other._stdminute and
|
||||
self._dstminute == other._dstminute and
|
||||
self._stdname == other._stdname and
|
||||
self._dstname == other._dstname))
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
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)
|
||||
|
||||
@tzname_in_python2
|
||||
def tzname(self, dt):
|
||||
if self._isdst(dt):
|
||||
return self._dstname
|
||||
else:
|
||||
return self._stdname
|
||||
|
||||
@staticmethod
|
||||
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
|
||||
|
||||
def display(self):
|
||||
return self._display
|
||||
|
||||
def _isdst(self, dt):
|
||||
if not self._dstmonth:
|
||||
# dstmonth == 0 signals the zone has no daylight saving time
|
||||
return False
|
||||
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
|
||||
|
||||
# multiple contexts only possible in 2.7 and 3.1, we still support 2.6
|
||||
with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
|
||||
with winreg.OpenKey(handle,
|
||||
"%s\%s" % (TZKEYNAME, name)) as tzkey:
|
||||
keydict = valuestodict(tzkey)
|
||||
|
||||
self._stdname = keydict["Std"]
|
||||
self._dstname = keydict["Dlt"]
|
||||
|
||||
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
|
||||
|
||||
# for the meaning see the win32 TIME_ZONE_INFORMATION structure docs
|
||||
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx
|
||||
(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):
|
||||
with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
|
||||
|
||||
with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey:
|
||||
keydict = valuestodict(tzlocalkey)
|
||||
|
||||
self._stdname = keydict["StandardName"]
|
||||
self._dstname = keydict["DaylightName"]
|
||||
|
||||
try:
|
||||
with winreg.OpenKey(
|
||||
handle, "%s\%s" % (TZKEYNAME, self._stdname)) as tzkey:
|
||||
_keydict = valuestodict(tzkey)
|
||||
self._display = _keydict["Display"]
|
||||
except OSError:
|
||||
self._display = None
|
||||
|
||||
self._stdoffset = -keydict["Bias"]-keydict["StandardBias"]
|
||||
self._dstoffset = self._stdoffset-keydict["DaylightBias"]
|
||||
|
||||
# For reasons unclear, in this particular key, the day of week has been
|
||||
# moved to the END of the SYSTEMTIME structure.
|
||||
tup = struct.unpack("=8h", keydict["StandardStart"])
|
||||
|
||||
(self._stdmonth,
|
||||
self._stdweeknumber, # Last = 5
|
||||
self._stdhour,
|
||||
self._stdminute) = tup[1:5]
|
||||
|
||||
self._stddayofweek = tup[7]
|
||||
|
||||
tup = struct.unpack("=8h", keydict["DaylightStart"])
|
||||
|
||||
(self._dstmonth,
|
||||
self._dstweeknumber, # Last = 5
|
||||
self._dsthour,
|
||||
self._dstminute) = tup[1:5]
|
||||
|
||||
self._dstdayofweek = tup[7]
|
||||
|
||||
def __repr__(self):
|
||||
return "tzwinlocal()"
|
||||
|
||||
def __str__(self):
|
||||
# str will return the standard name, not the daylight name.
|
||||
return "tzwinlocal(%s)" % repr(self._stdname)
|
||||
|
||||
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)
|
||||
|
||||
# This will work if dayofweek is ISO weekday (1-7) or Microsoft-style (0-6),
|
||||
# Because 7 % 7 = 0
|
||||
weekdayone = first.replace(day=((dayofweek - first.isoweekday()) % 7) + 1)
|
||||
wd = weekdayone + ((whichweek - 1) * ONEWEEK)
|
||||
if (wd.month != month):
|
||||
wd -= ONEWEEK
|
||||
|
||||
return wd
|
||||
|
||||
|
||||
def valuestodict(key):
|
||||
"""Convert a registry key's values to a dictionary."""
|
||||
dout = {}
|
||||
size = winreg.QueryInfoKey(key)[1]
|
||||
tz_res = None
|
||||
|
||||
for i in range(size):
|
||||
key_name, value, dtype = winreg.EnumValue(key, i)
|
||||
if dtype == winreg.REG_DWORD or dtype == winreg.REG_DWORD_LITTLE_ENDIAN:
|
||||
# If it's a DWORD (32-bit integer), it's stored as unsigned - convert
|
||||
# that to a proper signed integer
|
||||
if value & (1 << 31):
|
||||
value = value - (1 << 32)
|
||||
elif dtype == winreg.REG_SZ:
|
||||
# If it's a reference to the tzres DLL, load the actual string
|
||||
if value.startswith('@tzres'):
|
||||
tz_res = tz_res or tzres()
|
||||
value = tz_res.name_from_string(value)
|
||||
|
||||
value = value.rstrip('\x00') # Remove trailing nulls
|
||||
|
||||
dout[key_name] = value
|
||||
|
||||
return dout
|
2
pythonPackages/python-dateutil/dateutil/tzwin.py
Normal file
2
pythonPackages/python-dateutil/dateutil/tzwin.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
# tzwin has moved to dateutil.tz.win
|
||||
from .tz.win import *
|
102
pythonPackages/python-dateutil/dateutil/zoneinfo/__init__.py
Normal file
102
pythonPackages/python-dateutil/dateutil/zoneinfo/__init__.py
Normal file
|
@ -0,0 +1,102 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import os
|
||||
import warnings
|
||||
import tempfile
|
||||
import shutil
|
||||
import json
|
||||
|
||||
from subprocess import check_call
|
||||
from tarfile import TarFile
|
||||
from pkgutil import get_data
|
||||
from io import BytesIO
|
||||
from contextlib import closing
|
||||
|
||||
from dateutil.tz import tzfile
|
||||
|
||||
__all__ = ["gettz", "gettz_db_metadata", "rebuild"]
|
||||
|
||||
ZONEFILENAME = "dateutil-zoneinfo.tar.gz"
|
||||
METADATA_FN = 'METADATA'
|
||||
|
||||
# python2.6 compatability. Note that TarFile.__exit__ != TarFile.close, but
|
||||
# it's close enough for python2.6
|
||||
tar_open = TarFile.open
|
||||
if not hasattr(TarFile, '__exit__'):
|
||||
def tar_open(*args, **kwargs):
|
||||
return closing(TarFile.open(*args, **kwargs))
|
||||
|
||||
|
||||
class tzfile(tzfile):
|
||||
def __reduce__(self):
|
||||
return (gettz, (self._filename,))
|
||||
|
||||
|
||||
def getzoneinfofile_stream():
|
||||
try:
|
||||
return BytesIO(get_data(__name__, ZONEFILENAME))
|
||||
except IOError as e: # TODO switch to FileNotFoundError?
|
||||
warnings.warn("I/O error({0}): {1}".format(e.errno, e.strerror))
|
||||
return None
|
||||
|
||||
|
||||
class ZoneInfoFile(object):
|
||||
def __init__(self, zonefile_stream=None):
|
||||
if zonefile_stream is not None:
|
||||
with tar_open(fileobj=zonefile_stream, mode='r') as tf:
|
||||
# dict comprehension does not work on python2.6
|
||||
# TODO: get back to the nicer syntax when we ditch python2.6
|
||||
# self.zones = {zf.name: tzfile(tf.extractfile(zf),
|
||||
# filename = zf.name)
|
||||
# for zf in tf.getmembers() if zf.isfile()}
|
||||
self.zones = dict((zf.name, tzfile(tf.extractfile(zf),
|
||||
filename=zf.name))
|
||||
for zf in tf.getmembers()
|
||||
if zf.isfile() and zf.name != METADATA_FN)
|
||||
# deal with links: They'll point to their parent object. Less
|
||||
# waste of memory
|
||||
# links = {zl.name: self.zones[zl.linkname]
|
||||
# for zl in tf.getmembers() if zl.islnk() or zl.issym()}
|
||||
links = dict((zl.name, self.zones[zl.linkname])
|
||||
for zl in tf.getmembers() if
|
||||
zl.islnk() or zl.issym())
|
||||
self.zones.update(links)
|
||||
try:
|
||||
metadata_json = tf.extractfile(tf.getmember(METADATA_FN))
|
||||
metadata_str = metadata_json.read().decode('UTF-8')
|
||||
self.metadata = json.loads(metadata_str)
|
||||
except KeyError:
|
||||
# no metadata in tar file
|
||||
self.metadata = None
|
||||
else:
|
||||
self.zones = dict()
|
||||
self.metadata = None
|
||||
|
||||
|
||||
# The current API has gettz as a module function, although in fact it taps into
|
||||
# a stateful class. So as a workaround for now, without changing the API, we
|
||||
# will create a new "global" class instance the first time a user requests a
|
||||
# timezone. Ugly, but adheres to the api.
|
||||
#
|
||||
# TODO: deprecate this.
|
||||
_CLASS_ZONE_INSTANCE = list()
|
||||
|
||||
|
||||
def gettz(name):
|
||||
if len(_CLASS_ZONE_INSTANCE) == 0:
|
||||
_CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream()))
|
||||
return _CLASS_ZONE_INSTANCE[0].zones.get(name)
|
||||
|
||||
|
||||
def gettz_db_metadata():
|
||||
""" Get the zonefile metadata
|
||||
|
||||
See `zonefile_metadata`_
|
||||
|
||||
:returns: A dictionary with the database metadata
|
||||
"""
|
||||
if len(_CLASS_ZONE_INSTANCE) == 0:
|
||||
_CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream()))
|
||||
return _CLASS_ZONE_INSTANCE[0].metadata
|
||||
|
||||
|
Binary file not shown.
51
pythonPackages/python-dateutil/dateutil/zoneinfo/rebuild.py
Normal file
51
pythonPackages/python-dateutil/dateutil/zoneinfo/rebuild.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
import logging
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
import json
|
||||
from subprocess import check_call
|
||||
|
||||
from dateutil.zoneinfo import tar_open, METADATA_FN, ZONEFILENAME
|
||||
|
||||
|
||||
def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None):
|
||||
"""Rebuild the internal timezone info in dateutil/zoneinfo/zoneinfo*tar*
|
||||
|
||||
filename is the timezone tarball from ftp.iana.org/tz.
|
||||
|
||||
"""
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
zonedir = os.path.join(tmpdir, "zoneinfo")
|
||||
moduledir = os.path.dirname(__file__)
|
||||
try:
|
||||
with tar_open(filename) as tf:
|
||||
for name in zonegroups:
|
||||
tf.extract(name, tmpdir)
|
||||
filepaths = [os.path.join(tmpdir, n) for n in zonegroups]
|
||||
try:
|
||||
check_call(["zic", "-d", zonedir] + filepaths)
|
||||
except OSError as e:
|
||||
_print_on_nosuchfile(e)
|
||||
raise
|
||||
# write metadata file
|
||||
with open(os.path.join(zonedir, METADATA_FN), 'w') as f:
|
||||
json.dump(metadata, f, indent=4, sort_keys=True)
|
||||
target = os.path.join(moduledir, ZONEFILENAME)
|
||||
with tar_open(target, "w:%s" % format) as tf:
|
||||
for entry in os.listdir(zonedir):
|
||||
entrypath = os.path.join(zonedir, entry)
|
||||
tf.add(entrypath, entry)
|
||||
finally:
|
||||
shutil.rmtree(tmpdir)
|
||||
|
||||
def _print_on_nosuchfile(e):
|
||||
"""Print helpful troubleshooting message
|
||||
|
||||
e is an exception raised by subprocess.check_call()
|
||||
|
||||
"""
|
||||
if e.errno == 2:
|
||||
logging.error(
|
||||
"Could not find zic. Perhaps you need to install "
|
||||
"libc-bin or some other package that provides it, "
|
||||
"or it's not in your PATH?")
|
|
@ -0,0 +1,27 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: python-dateutil
|
||||
Version: 2.5.0
|
||||
Summary: Extensions to the standard Python datetime module
|
||||
Home-page: https://dateutil.readthedocs.org
|
||||
Author: Paul Ganssle, Yaron de Leeuw
|
||||
Author-email: dateutil@python.org
|
||||
License: Simplified BSD
|
||||
Description:
|
||||
The dateutil module provides powerful extensions to the
|
||||
datetime module available in the Python standard library.
|
||||
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.2
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Topic :: Software Development :: Libraries
|
||||
Requires: six
|
|
@ -0,0 +1,26 @@
|
|||
LICENSE
|
||||
MANIFEST.in
|
||||
NEWS
|
||||
README.rst
|
||||
setup.cfg
|
||||
setup.py
|
||||
updatezinfo.py
|
||||
zonefile_metadata.json
|
||||
dateutil/__init__.py
|
||||
dateutil/easter.py
|
||||
dateutil/parser.py
|
||||
dateutil/relativedelta.py
|
||||
dateutil/rrule.py
|
||||
dateutil/tzwin.py
|
||||
dateutil/tz/__init__.py
|
||||
dateutil/tz/tz.py
|
||||
dateutil/tz/win.py
|
||||
dateutil/zoneinfo/__init__.py
|
||||
dateutil/zoneinfo/dateutil-zoneinfo.tar.gz
|
||||
dateutil/zoneinfo/rebuild.py
|
||||
python_dateutil.egg-info/PKG-INFO
|
||||
python_dateutil.egg-info/SOURCES.txt
|
||||
python_dateutil.egg-info/dependency_links.txt
|
||||
python_dateutil.egg-info/requires.txt
|
||||
python_dateutil.egg-info/top_level.txt
|
||||
python_dateutil.egg-info/zip-safe
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
six >=1.5
|
|
@ -0,0 +1 @@
|
|||
dateutil
|
|
@ -0,0 +1 @@
|
|||
|
8
pythonPackages/python-dateutil/setup.cfg
Normal file
8
pythonPackages/python-dateutil/setup.cfg
Normal file
|
@ -0,0 +1,8 @@
|
|||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
||||
[egg_info]
|
||||
tag_date = 0
|
||||
tag_build =
|
||||
tag_svn_revision = 0
|
||||
|
52
pythonPackages/python-dateutil/setup.py
Normal file
52
pythonPackages/python-dateutil/setup.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/python
|
||||
from os.path import isfile
|
||||
import codecs
|
||||
import os
|
||||
import re
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
if isfile("MANIFEST"):
|
||||
os.unlink("MANIFEST")
|
||||
|
||||
|
||||
TOPDIR = os.path.dirname(__file__) or "."
|
||||
VERSION = re.search('__version__ = "([^"]+)"',
|
||||
codecs.open(TOPDIR + "/dateutil/__init__.py",
|
||||
encoding='utf-8').read()).group(1)
|
||||
|
||||
|
||||
setup(name="python-dateutil",
|
||||
version=VERSION,
|
||||
description="Extensions to the standard Python datetime module",
|
||||
author="Paul Ganssle, Yaron de Leeuw",
|
||||
author_email="dateutil@python.org",
|
||||
url="https://dateutil.readthedocs.org",
|
||||
license="Simplified BSD",
|
||||
long_description="""
|
||||
The dateutil module provides powerful extensions to the
|
||||
datetime module available in the Python standard library.
|
||||
""",
|
||||
packages=["dateutil", "dateutil.zoneinfo", "dateutil.tz"],
|
||||
package_data={"dateutil.zoneinfo": ["dateutil-zoneinfo.tar.gz"]},
|
||||
zip_safe=True,
|
||||
requires=["six"],
|
||||
install_requires=["six >=1.5"], # XXX fix when packaging is sane again
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
],
|
||||
test_suite="dateutil.test"
|
||||
)
|
54
pythonPackages/python-dateutil/updatezinfo.py
Normal file
54
pythonPackages/python-dateutil/updatezinfo.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
import hashlib
|
||||
import json
|
||||
import io
|
||||
|
||||
from six.moves.urllib import request
|
||||
from six.moves.urllib import error as urllib_error
|
||||
|
||||
from dateutil.zoneinfo import rebuild
|
||||
|
||||
METADATA_FILE = "zonefile_metadata.json"
|
||||
|
||||
|
||||
def main():
|
||||
with io.open(METADATA_FILE, 'r') as f:
|
||||
metadata = json.load(f)
|
||||
|
||||
releases_urls = metadata['releases_url']
|
||||
if metadata['metadata_version'] < 2.0:
|
||||
# In later versions the releases URL is a mirror URL
|
||||
releases_urls = [releases_urls]
|
||||
|
||||
if not os.path.isfile(metadata['tzdata_file']):
|
||||
|
||||
for ii, releases_url in enumerate(releases_urls):
|
||||
print("Downloading tz file from mirror {ii}".format(ii=ii))
|
||||
try:
|
||||
request.urlretrieve(os.path.join(releases_url,
|
||||
metadata['tzdata_file']),
|
||||
metadata['tzdata_file'])
|
||||
except urllib_error.URLError as e:
|
||||
print("Download failed, trying next mirror.")
|
||||
last_error = e
|
||||
continue
|
||||
|
||||
last_error = None
|
||||
break
|
||||
|
||||
if last_error is not None:
|
||||
raise last_error
|
||||
|
||||
with open(metadata['tzdata_file'], 'rb') as tzfile:
|
||||
sha_hasher = hashlib.sha512()
|
||||
sha_hasher.update(tzfile.read())
|
||||
sha_512_file = sha_hasher.hexdigest()
|
||||
assert metadata['tzdata_file_sha512'] == sha_512_file, "SHA failed for"
|
||||
print("Updating timezone information...")
|
||||
rebuild.rebuild(metadata['tzdata_file'], zonegroups=metadata['zonegroups'],
|
||||
metadata=metadata)
|
||||
print("Done.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
25
pythonPackages/python-dateutil/zonefile_metadata.json
Normal file
25
pythonPackages/python-dateutil/zonefile_metadata.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"metadata_version": 2.0,
|
||||
"releases_url": [
|
||||
"https://dateutil.github.io/tzdata/tzdata/",
|
||||
"ftp://ftp.iana.org/tz/releases/"
|
||||
],
|
||||
"tzdata_file": "tzdata2016a.tar.gz",
|
||||
"tzdata_file_sha512": "9aa5f61a73afa5070dfb1d1982945d268ea8215663d0cd594216500aff14797ea5591ccfd488dc2280902fa1820bf782623624912b669873728431258fe10ec1",
|
||||
"tzversion": "2016a",
|
||||
"zonegroups": [
|
||||
"africa",
|
||||
"antarctica",
|
||||
"asia",
|
||||
"australasia",
|
||||
"europe",
|
||||
"northamerica",
|
||||
"southamerica",
|
||||
"pacificnew",
|
||||
"etcetera",
|
||||
"systemv",
|
||||
"factory",
|
||||
"backzone",
|
||||
"backward"
|
||||
]
|
||||
}
|
BIN
pythonPackages/six/six-1.10.0.tar.gz
Normal file
BIN
pythonPackages/six/six-1.10.0.tar.gz
Normal file
Binary file not shown.
|
@ -102,6 +102,18 @@ function lookupRPM()
|
|||
export RPM_SPECIFICATION="${python_site__dir}/Installer.pint"
|
||||
return 0
|
||||
fi
|
||||
if [ "${1}" = "awips2-python-six" ]; then
|
||||
export RPM_SPECIFICATION="${python_site__dir}/Installer.six"
|
||||
return 0
|
||||
fi
|
||||
if [ "${1}" = "awips2-python-cython" ]; then
|
||||
export RPM_SPECIFICATION="${python_site__dir}/Installer.cython"
|
||||
return 0
|
||||
fi
|
||||
if [ "${1}" = "awips2-python-dateutil" ]; then
|
||||
export RPM_SPECIFICATION="${python_site__dir}/Installer.dateutil"
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
||||
if [ "${1}" = "awips2-python-tables" ]; then
|
||||
|
|
|
@ -13,6 +13,7 @@ function usage()
|
|||
echo " -edex only build the EDEX rpms."
|
||||
echo " -shp only build the EDEX shapefile rpm."
|
||||
echo " -python build Python rpms."
|
||||
echo " -pydev build additional Python rpms."
|
||||
echo " -qpid build only the QPID rpms."
|
||||
echo " -ldm build the awips2-ldm rpm; requires root privileges."
|
||||
echo " -upc build the awips2-edex-upc rpm."
|
||||
|
|
|
@ -117,7 +117,25 @@ if [ "${1}" = "-WA" ]; then
|
|||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1}" = "-pydev" ]; then
|
||||
buildRPM "awips2-python-six"
|
||||
#buildRPM "awips2-python-cython"
|
||||
#buildRPM "awips2-python-dateutil"
|
||||
#buildRPM "awips2-python-metpy"
|
||||
|
||||
#buildRPM "awips2-python-numpy"
|
||||
#buildRPM "awips2-python-scipy"
|
||||
#buildRPM "awips2-python-matplotlib"
|
||||
|
||||
# DONE
|
||||
#buildRPM "awips2-python-pint"
|
||||
exit 0
|
||||
|
||||
fi
|
||||
|
||||
if [ "${1}" = "-python" ]; then
|
||||
buildRPM "awips2-python-pint"
|
||||
|
||||
buildRPM "awips2-python"
|
||||
buildRPM "awips2-python-h5py"
|
||||
buildRPM "awips2-python-qpid"
|
||||
|
@ -127,9 +145,6 @@ if [ "${1}" = "-python" ]; then
|
|||
buildRPM "awips2-python-jimporter"
|
||||
buildRPM "awips2-python-matplotlib"
|
||||
buildRPM "awips2-python-nose"
|
||||
#buildRPM "awips2-python-cython"
|
||||
#buildRPM "awips2-python-six"
|
||||
#buildRPM "awips2-python-dateutil"
|
||||
buildRPM "awips2-python-numpy"
|
||||
buildRPM "awips2-python-pil"
|
||||
buildRPM "awips2-python-pmw"
|
||||
|
@ -138,8 +153,6 @@ if [ "${1}" = "-python" ]; then
|
|||
buildRPM "awips2-python-scientific"
|
||||
buildRPM "awips2-python-scipy"
|
||||
buildRPM "awips2-python-pyparsing"
|
||||
buildRPM "awips2-python-pint"
|
||||
#buildRPM "awips2-python-metpy"
|
||||
buildRPM "awips2-python-tables"
|
||||
buildRPM "awips2-python-thrift"
|
||||
buildRPM "awips2-python-tpg"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
|
||||
%define _build_arch %(uname -i)
|
||||
%define _version 0.23.4
|
||||
%define _python_pkgs_dir "%{_baseline_workspace}/pythonPackages"
|
||||
%define _python_build_loc %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
|
@ -8,7 +9,7 @@
|
|||
#
|
||||
Name: awips2-python-cython
|
||||
Summary: AWIPS II Python cython Distribution
|
||||
Version: 0.22.1
|
||||
Version: %{_version}
|
||||
Release: 1
|
||||
Group: AWIPSII
|
||||
BuildRoot: %{_build_root}
|
||||
|
@ -46,7 +47,7 @@ mkdir -p %{_python_build_loc}
|
|||
|
||||
%build
|
||||
CYTHON_SRC_DIR="%{_python_pkgs_dir}/cython"
|
||||
CYTHON_TAR="Cython-0.22.1.tar.gz"
|
||||
CYTHON_TAR="Cython-%{_version}.tar.gz"
|
||||
cp -v ${CYTHON_SRC_DIR}/${CYTHON_TAR} \
|
||||
%{_python_build_loc}
|
||||
RC=$?
|
||||
|
@ -62,8 +63,8 @@ if [ ${RC} -ne 0 ]; then
|
|||
exit 1
|
||||
fi
|
||||
rm -fv ${CYTHON_TAR}
|
||||
if [ ! -d Cython-0.22.1 ]; then
|
||||
file Cython-0.22.1
|
||||
if [ ! -d Cython-%{_version} ]; then
|
||||
file Cython-%{_version}
|
||||
exit 1
|
||||
fi
|
||||
source /etc/profile.d/awips2.sh
|
||||
|
@ -71,7 +72,7 @@ RC=$?
|
|||
if [ ${RC} -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
cd Cython-0.22.1
|
||||
cd Cython-%{_version}
|
||||
/awips2/python/bin/python setup.py clean
|
||||
RC=$?
|
||||
if [ ${RC} -ne 0 ]; then
|
||||
|
@ -88,7 +89,7 @@ popd > /dev/null
|
|||
CYTHON_SRC_DIR="%{_python_pkgs_dir}/cython"
|
||||
|
||||
pushd . > /dev/null
|
||||
cd %{_python_build_loc}/Cython-0.22.1
|
||||
cd %{_python_build_loc}/Cython-%{_version}
|
||||
export LD_LIBRARY_PATH=/awips2/python/lib
|
||||
/awips2/python/bin/python setup.py install \
|
||||
--root=%{_build_root} \
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
|
||||
%define _build_arch %(uname -i)
|
||||
%define _version 2.5.0
|
||||
%define _python_pkgs_dir "%{_baseline_workspace}/pythonPackages"
|
||||
%define _python_build_loc %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
|
@ -8,7 +9,7 @@
|
|||
#
|
||||
Name: awips2-python-dateutil
|
||||
Summary: AWIPS II Python dateutil Distribution
|
||||
Version: 2.4.2
|
||||
Version: %{_version}
|
||||
Release: 1
|
||||
Group: AWIPSII
|
||||
BuildRoot: %{_build_root}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
# AWIPS II Python pint Spec File
|
||||
#
|
||||
Name: awips2-python-pint
|
||||
Summary: AWIPS II Python pint Distribution
|
||||
Version: 0.6
|
||||
Summary: AWIPS II Python Pint Distribution
|
||||
Version: 0.7.2
|
||||
Release: 1
|
||||
Group: AWIPSII
|
||||
BuildRoot: %{_build_root}
|
||||
|
@ -24,7 +24,7 @@ requires: awips2-python
|
|||
provides: awips2-python-pint
|
||||
|
||||
%description
|
||||
AWIPS II Python pint Site-Package
|
||||
AWIPS II Python Pint
|
||||
|
||||
%prep
|
||||
# Verify That The User Has Specified A BuildRoot.
|
||||
|
@ -43,9 +43,9 @@ fi
|
|||
mkdir -p %{_python_build_loc}
|
||||
|
||||
%build
|
||||
SCIPY_SRC_DIR="%{_python_pkgs_dir}/pint"
|
||||
PINT_SRC_DIR="%{_python_pkgs_dir}/pint"
|
||||
|
||||
cp -rv ${SCIPY_SRC_DIR}/* \
|
||||
cp -rv ${PINT_SRC_DIR}/* \
|
||||
%{_python_build_loc}
|
||||
RC=$?
|
||||
if [ ${RC} -ne 0 ]; then
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
%global __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')
|
||||
%define _build_arch %(uname -i)
|
||||
%define _version 1.10.0
|
||||
%define _python_pkgs_dir "%{_baseline_workspace}/pythonPackages"
|
||||
%define _python_build_loc %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
|
@ -8,7 +9,7 @@
|
|||
#
|
||||
Name: awips2-python-six
|
||||
Summary: AWIPS II Python six Distribution
|
||||
Version: 1.9.0
|
||||
Version: %{_version}
|
||||
Release: 1
|
||||
Group: AWIPSII
|
||||
BuildRoot: %{_build_root}
|
||||
|
@ -47,7 +48,7 @@ mkdir -p %{_python_build_loc}
|
|||
|
||||
%build
|
||||
SIX_SRC_DIR="%{_python_pkgs_dir}/six"
|
||||
SIX_TAR="six-1.9.0.tar.gz"
|
||||
SIX_TAR="six-%{_version}.tar.gz"
|
||||
cp -v ${SIX_SRC_DIR}/${SIX_TAR} \
|
||||
%{_python_build_loc}
|
||||
RC=$?
|
||||
|
@ -63,8 +64,8 @@ if [ ${RC} -ne 0 ]; then
|
|||
exit 1
|
||||
fi
|
||||
rm -fv ${SIX_TAR}
|
||||
if [ ! -d six-1.9.0 ]; then
|
||||
file six-1.9.0
|
||||
if [ ! -d six-%{_version} ]; then
|
||||
file six-%{_version}
|
||||
exit 1
|
||||
fi
|
||||
source /etc/profile.d/awips2.sh
|
||||
|
@ -72,7 +73,7 @@ RC=$?
|
|||
if [ ${RC} -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
cd six-1.9.0
|
||||
cd six-%{_version}
|
||||
/awips2/python/bin/python setup.py clean
|
||||
RC=$?
|
||||
if [ ${RC} -ne 0 ]; then
|
||||
|
@ -89,7 +90,7 @@ popd > /dev/null
|
|||
SIX_SRC_DIR="%{_python_pkgs_dir}/six"
|
||||
|
||||
pushd . > /dev/null
|
||||
cd %{_python_build_loc}/six-1.9.0
|
||||
cd %{_python_build_loc}/six-%{_version}
|
||||
export LD_LIBRARY_PATH=/awips2/python/lib
|
||||
/awips2/python/bin/python setup.py install \
|
||||
--root=%{_build_root} \
|
||||
|
|
Loading…
Add table
Reference in a new issue