Bläddra i källkod

[core] logging should be timezone aware for all systems

On ubuntu 12.04, timezone information is missing due to
http://bugs.python.org/issue1493676.

Adding a pytz formatter that is timezone aware.
Abraham Elmahrek 11 år sedan
förälder
incheckning
5a98108
100 ändrade filer med 4936 tillägg och 0 borttagningar
  1. 2 0
      desktop/conf.dist/log.conf
  2. 2 0
      desktop/conf/log.conf
  3. 54 0
      desktop/core/ext-py/pytz-2013.9/CHANGES.txt
  4. 19 0
      desktop/core/ext-py/pytz-2013.9/LICENSE.txt
  5. 5 0
      desktop/core/ext-py/pytz-2013.9/MANIFEST.in
  6. 578 0
      desktop/core/ext-py/pytz-2013.9/PKG-INFO
  7. 558 0
      desktop/core/ext-py/pytz-2013.9/README.txt
  8. 1508 0
      desktop/core/ext-py/pytz-2013.9/pytz/__init__.py
  9. 48 0
      desktop/core/ext-py/pytz-2013.9/pytz/exceptions.py
  10. 168 0
      desktop/core/ext-py/pytz-2013.9/pytz/lazy.py
  11. 127 0
      desktop/core/ext-py/pytz-2013.9/pytz/reference.py
  12. 36 0
      desktop/core/ext-py/pytz-2013.9/pytz/tests/test_docs.py
  13. 313 0
      desktop/core/ext-py/pytz-2013.9/pytz/tests/test_lazy.py
  14. 818 0
      desktop/core/ext-py/pytz-2013.9/pytz/tests/test_tzinfo.py
  15. 137 0
      desktop/core/ext-py/pytz-2013.9/pytz/tzfile.py
  16. 563 0
      desktop/core/ext-py/pytz-2013.9/pytz/tzinfo.py
  17. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Abidjan
  18. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Accra
  19. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Addis_Ababa
  20. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Algiers
  21. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Asmara
  22. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Asmera
  23. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Bamako
  24. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Bangui
  25. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Banjul
  26. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Bissau
  27. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Blantyre
  28. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Brazzaville
  29. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Bujumbura
  30. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Cairo
  31. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Casablanca
  32. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Ceuta
  33. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Conakry
  34. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Dakar
  35. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Dar_es_Salaam
  36. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Djibouti
  37. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Douala
  38. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/El_Aaiun
  39. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Freetown
  40. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Gaborone
  41. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Harare
  42. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Johannesburg
  43. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Juba
  44. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Kampala
  45. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Khartoum
  46. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Kigali
  47. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Kinshasa
  48. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Lagos
  49. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Libreville
  50. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Lome
  51. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Luanda
  52. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Lubumbashi
  53. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Lusaka
  54. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Malabo
  55. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Maputo
  56. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Maseru
  57. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Mbabane
  58. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Mogadishu
  59. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Monrovia
  60. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Nairobi
  61. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Ndjamena
  62. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Niamey
  63. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Nouakchott
  64. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Ouagadougou
  65. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Porto-Novo
  66. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Sao_Tome
  67. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Timbuktu
  68. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Tripoli
  69. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Tunis
  70. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Windhoek
  71. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Adak
  72. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Anchorage
  73. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Anguilla
  74. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Antigua
  75. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Araguaina
  76. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Buenos_Aires
  77. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Catamarca
  78. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/ComodRivadavia
  79. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Cordoba
  80. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Jujuy
  81. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/La_Rioja
  82. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Mendoza
  83. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Rio_Gallegos
  84. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Salta
  85. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/San_Juan
  86. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/San_Luis
  87. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Tucuman
  88. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Ushuaia
  89. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Aruba
  90. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Asuncion
  91. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Atikokan
  92. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Atka
  93. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Bahia
  94. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Bahia_Banderas
  95. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Barbados
  96. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Belem
  97. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Belize
  98. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Blanc-Sablon
  99. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Boa_Vista
  100. BIN
      desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Bogota

+ 2 - 0
desktop/conf.dist/log.conf

@@ -39,10 +39,12 @@ formatter=default
 args=('%LOG_DIR%/error.log', 'a', 5000000, 5)
 
 [formatter_default]
+class=desktop.log.formatter.Formatter
 format=[%(asctime)s] %(module)-12s %(levelname)-8s %(message)s
 datefmt=%d/%b/%Y %H:%M:%S %z
 
 [formatter_access]
+class=desktop.log.formatter.Formatter
 format=[%(asctime)s] %(levelname)-8s %(message)s
 datefmt=%d/%b/%Y %H:%M:%S %z
 

+ 2 - 0
desktop/conf/log.conf

@@ -44,10 +44,12 @@ formatter=default
 args=('%LOG_DIR%/%PROC_NAME%.log', 'a', 1000000, 3)
 
 [formatter_default]
+class=desktop.log.formatter.Formatter
 format=[%(asctime)s] %(module)-12s %(levelname)-8s %(message)s
 datefmt=%d/%b/%Y %H:%M:%S %z
 
 [formatter_access]
+class=desktop.log.formatter.Formatter
 format=[%(asctime)s] %(levelname)-8s %(message)s
 datefmt=%d/%b/%Y %H:%M:%S %z
 

+ 54 - 0
desktop/core/ext-py/pytz-2013.9/CHANGES.txt

@@ -0,0 +1,54 @@
+2004-07-25
+    
+    - Improved localtime handling, and added a localize() method enabling
+      correct creation of local times.
+
+2005-02-16
+
+    - Made available under the Zope Public Licence 2.1 (ZPL) and checked
+      into the Zope3 project. pytz may now be used and redistributed
+      under either the original MIT license or the ZPL 2.1.
+
+2005-05-13
+
+    - Move UTC into the top level pytz module and provide special
+      case pickle support for this singleton.
+
+2005-08-14
+
+    - Ensure all tzinfo instances are efficiently picklable.
+
+2005-12-31
+
+    - Add fixed offset timezone classes required by Zope 3
+    - Generate and distribute a PO template file listing all timezone
+      names. Translations are not yet available.
+
+2007-03-03
+
+    - Import work by James Henstridge, making pytz load timezone
+      information from zic compiled binaries at runtime rather than
+      processing them into Python classes.
+
+2007-03-26
+
+    - Update database to version 2007d
+    - Fix windows incompatibilities, working around limitations on that
+      platform.
+    - Fix 2.3 incompatibilities. Installation now requires distutils.
+    - Passing an invalid timezone name to timezone() now raises an
+      UnknownTimezoneError, which is a KeyError subclass for backwards
+      compatibility.
+
+2007-03-27
+
+    - Ensure API can accept Unicode strings (Bug #96957)
+
+2009-09-29
+
+    - Fix test_zdump tests and bugs the fixed tests picked up, including
+      the fix for Bug #427444.
+
+2011-02-08
+
+    - Python 3.1 support.

+ 19 - 0
desktop/core/ext-py/pytz-2013.9/LICENSE.txt

@@ -0,0 +1,19 @@
+Copyright (c) 2003-2009 Stuart Bishop <stuart@stuartbishop.net>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.

+ 5 - 0
desktop/core/ext-py/pytz-2013.9/MANIFEST.in

@@ -0,0 +1,5 @@
+include *.txt setup.py
+recursive-include pytz *.py
+recursive-include pytz *.pot
+graft pytz/zoneinfo
+exclude test_zdump.py

+ 578 - 0
desktop/core/ext-py/pytz-2013.9/PKG-INFO

@@ -0,0 +1,578 @@
+Metadata-Version: 1.1
+Name: pytz
+Version: 2013.9
+Summary: World timezone definitions, modern and historical
+Home-page: http://pythonhosted.org/pytz
+Author: Stuart Bishop
+Author-email: stuart@stuartbishop.net
+License: MIT
+Download-URL: http://pypi.python.org/pypi/pytz
+Description: pytz - World Timezone Definitions for Python
+        ============================================
+        
+        :Author: Stuart Bishop <stuart@stuartbishop.net>
+        
+        Introduction
+        ~~~~~~~~~~~~
+        
+        pytz brings the Olson tz database into Python. This library allows
+        accurate and cross platform timezone calculations using Python 2.4
+        or higher. It also solves the issue of ambiguous times at the end
+        of daylight savings, which you can read more about in the Python
+        Library Reference (``datetime.tzinfo``).
+        
+        Almost all of the Olson timezones are supported.
+        
+        .. note::
+        
+            This library differs from the documented Python API for
+            tzinfo implementations; if you want to create local wallclock
+            times you need to use the ``localize()`` method documented in this
+            document. In addition, if you perform date arithmetic on local
+            times that cross DST boundaries, the result may be in an incorrect
+            timezone (ie. subtract 1 minute from 2002-10-27 1:00 EST and you get
+            2002-10-27 0:59 EST instead of the correct 2002-10-27 1:59 EDT). A
+            ``normalize()`` method is provided to correct this. Unfortunately these
+            issues cannot be resolved without modifying the Python datetime
+            implementation (see PEP-431).
+        
+        
+        Installation
+        ~~~~~~~~~~~~
+        
+        This package can either be installed from a .egg file using setuptools,
+        or from the tarball using the standard Python distutils.
+        
+        If you are installing from a tarball, run the following command as an
+        administrative user::
+        
+            python setup.py install
+        
+        If you are installing using setuptools, you don't even need to download
+        anything as the latest version will be downloaded for you
+        from the Python package index::
+        
+            easy_install --upgrade pytz
+        
+        If you already have the .egg file, you can use that too::
+        
+            easy_install pytz-2008g-py2.6.egg
+        
+        
+        Example & Usage
+        ~~~~~~~~~~~~~~~
+        
+        Localized times and date arithmetic
+        -----------------------------------
+        
+        >>> from datetime import datetime, timedelta
+        >>> from pytz import timezone
+        >>> import pytz
+        >>> utc = pytz.utc
+        >>> utc.zone
+        'UTC'
+        >>> eastern = timezone('US/Eastern')
+        >>> eastern.zone
+        'US/Eastern'
+        >>> amsterdam = timezone('Europe/Amsterdam')
+        >>> fmt = '%Y-%m-%d %H:%M:%S %Z%z'
+        
+        This library only supports two ways of building a localized time. The
+        first is to use the ``localize()`` method provided by the pytz library.
+        This is used to localize a naive datetime (datetime with no timezone
+        information):
+        
+        >>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
+        >>> print(loc_dt.strftime(fmt))
+        2002-10-27 06:00:00 EST-0500
+        
+        The second way of building a localized time is by converting an existing
+        localized time using the standard ``astimezone()`` method:
+        
+        >>> ams_dt = loc_dt.astimezone(amsterdam)
+        >>> ams_dt.strftime(fmt)
+        '2002-10-27 12:00:00 CET+0100'
+        
+        Unfortunately using the tzinfo argument of the standard datetime
+        constructors ''does not work'' with pytz for many timezones.
+        
+        >>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt)
+        '2002-10-27 12:00:00 AMT+0020'
+        
+        It is safe for timezones without daylight savings trasitions though, such
+        as UTC:
+        
+        >>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=pytz.utc).strftime(fmt)
+        '2002-10-27 12:00:00 UTC+0000'
+        
+        The preferred way of dealing with times is to always work in UTC,
+        converting to localtime only when generating output to be read
+        by humans.
+        
+        >>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
+        >>> loc_dt = utc_dt.astimezone(eastern)
+        >>> loc_dt.strftime(fmt)
+        '2002-10-27 01:00:00 EST-0500'
+        
+        This library also allows you to do date arithmetic using local
+        times, although it is more complicated than working in UTC as you
+        need to use the ``normalize()`` method to handle daylight savings time
+        and other timezone transitions. In this example, ``loc_dt`` is set
+        to the instant when daylight savings time ends in the US/Eastern
+        timezone.
+        
+        >>> before = loc_dt - timedelta(minutes=10)
+        >>> before.strftime(fmt)
+        '2002-10-27 00:50:00 EST-0500'
+        >>> eastern.normalize(before).strftime(fmt)
+        '2002-10-27 01:50:00 EDT-0400'
+        >>> after = eastern.normalize(before + timedelta(minutes=20))
+        >>> after.strftime(fmt)
+        '2002-10-27 01:10:00 EST-0500'
+        
+        Creating local times is also tricky, and the reason why working with
+        local times is not recommended. Unfortunately, you cannot just pass
+        a ``tzinfo`` argument when constructing a datetime (see the next
+        section for more details)
+        
+        >>> dt = datetime(2002, 10, 27, 1, 30, 0)
+        >>> dt1 = eastern.localize(dt, is_dst=True)
+        >>> dt1.strftime(fmt)
+        '2002-10-27 01:30:00 EDT-0400'
+        >>> dt2 = eastern.localize(dt, is_dst=False)
+        >>> dt2.strftime(fmt)
+        '2002-10-27 01:30:00 EST-0500'
+        
+        Converting between timezones also needs special attention. We also need
+        to use the ``normalize()`` method to ensure the conversion is correct.
+        
+        >>> utc_dt = utc.localize(datetime.utcfromtimestamp(1143408899))
+        >>> utc_dt.strftime(fmt)
+        '2006-03-26 21:34:59 UTC+0000'
+        >>> au_tz = timezone('Australia/Sydney')
+        >>> au_dt = au_tz.normalize(utc_dt.astimezone(au_tz))
+        >>> au_dt.strftime(fmt)
+        '2006-03-27 08:34:59 EST+1100'
+        >>> utc_dt2 = utc.normalize(au_dt.astimezone(utc))
+        >>> utc_dt2.strftime(fmt)
+        '2006-03-26 21:34:59 UTC+0000'
+        
+        You can take shortcuts when dealing with the UTC side of timezone
+        conversions. ``normalize()`` and ``localize()`` are not really
+        necessary when there are no daylight savings time transitions to
+        deal with.
+        
+        >>> utc_dt = datetime.utcfromtimestamp(1143408899).replace(tzinfo=utc)
+        >>> utc_dt.strftime(fmt)
+        '2006-03-26 21:34:59 UTC+0000'
+        >>> au_tz = timezone('Australia/Sydney')
+        >>> au_dt = au_tz.normalize(utc_dt.astimezone(au_tz))
+        >>> au_dt.strftime(fmt)
+        '2006-03-27 08:34:59 EST+1100'
+        >>> utc_dt2 = au_dt.astimezone(utc)
+        >>> utc_dt2.strftime(fmt)
+        '2006-03-26 21:34:59 UTC+0000'
+        
+        
+        ``tzinfo`` API
+        --------------
+        
+        The ``tzinfo`` instances returned by the ``timezone()`` function have
+        been extended to cope with ambiguous times by adding an ``is_dst``
+        parameter to the ``utcoffset()``, ``dst()`` && ``tzname()`` methods.
+        
+        >>> tz = timezone('America/St_Johns')
+        
+        >>> normal = datetime(2009, 9, 1)
+        >>> ambiguous = datetime(2009, 10, 31, 23, 30)
+        
+        The ``is_dst`` parameter is ignored for most timestamps. It is only used
+        during DST transition ambiguous periods to resulve that ambiguity.
+        
+        >>> tz.utcoffset(normal, is_dst=True)
+        datetime.timedelta(-1, 77400)
+        >>> tz.dst(normal, is_dst=True)
+        datetime.timedelta(0, 3600)
+        >>> tz.tzname(normal, is_dst=True)
+        'NDT'
+        
+        >>> tz.utcoffset(ambiguous, is_dst=True)
+        datetime.timedelta(-1, 77400)
+        >>> tz.dst(ambiguous, is_dst=True)
+        datetime.timedelta(0, 3600)
+        >>> tz.tzname(ambiguous, is_dst=True)
+        'NDT'
+        
+        >>> tz.utcoffset(normal, is_dst=False)
+        datetime.timedelta(-1, 77400)
+        >>> tz.dst(normal, is_dst=False)
+        datetime.timedelta(0, 3600)
+        >>> tz.tzname(normal, is_dst=False)
+        'NDT'
+        
+        >>> tz.utcoffset(ambiguous, is_dst=False)
+        datetime.timedelta(-1, 73800)
+        >>> tz.dst(ambiguous, is_dst=False)
+        datetime.timedelta(0)
+        >>> tz.tzname(ambiguous, is_dst=False)
+        'NST'
+        
+        If ``is_dst`` is not specified, ambiguous timestamps will raise
+        an ``pytz.exceptions.AmbiguousTimeError`` exception.
+        
+        >>> tz.utcoffset(normal)
+        datetime.timedelta(-1, 77400)
+        >>> tz.dst(normal)
+        datetime.timedelta(0, 3600)
+        >>> tz.tzname(normal)
+        'NDT'
+        
+        >>> import pytz.exceptions
+        >>> try:
+        ...     tz.utcoffset(ambiguous)
+        ... except pytz.exceptions.AmbiguousTimeError:
+        ...     print('pytz.exceptions.AmbiguousTimeError: %s' % ambiguous)
+        pytz.exceptions.AmbiguousTimeError: 2009-10-31 23:30:00
+        >>> try:
+        ...     tz.dst(ambiguous)
+        ... except pytz.exceptions.AmbiguousTimeError:
+        ...     print('pytz.exceptions.AmbiguousTimeError: %s' % ambiguous)
+        pytz.exceptions.AmbiguousTimeError: 2009-10-31 23:30:00
+        >>> try:
+        ...     tz.tzname(ambiguous)
+        ... except pytz.exceptions.AmbiguousTimeError:
+        ...     print('pytz.exceptions.AmbiguousTimeError: %s' % ambiguous)
+        pytz.exceptions.AmbiguousTimeError: 2009-10-31 23:30:00
+        
+        
+        Problems with Localtime
+        ~~~~~~~~~~~~~~~~~~~~~~~
+        
+        The major problem we have to deal with is that certain datetimes
+        may occur twice in a year. For example, in the US/Eastern timezone
+        on the last Sunday morning in October, the following sequence
+        happens:
+        
+            - 01:00 EDT occurs
+            - 1 hour later, instead of 2:00am the clock is turned back 1 hour
+              and 01:00 happens again (this time 01:00 EST)
+        
+        In fact, every instant between 01:00 and 02:00 occurs twice. This means
+        that if you try and create a time in the 'US/Eastern' timezone using
+        the standard datetime syntax, there is no way to specify if you meant
+        before of after the end-of-daylight-savings-time transition.
+        
+        >>> loc_dt = datetime(2002, 10, 27, 1, 30, 00, tzinfo=eastern)
+        >>> loc_dt.strftime(fmt)
+        '2002-10-27 01:30:00 EST-0500'
+        
+        As you can see, the system has chosen one for you and there is a 50%
+        chance of it being out by one hour. For some applications, this does
+        not matter. However, if you are trying to schedule meetings with people
+        in different timezones or analyze log files it is not acceptable. 
+        
+        The best and simplest solution is to stick with using UTC.  The pytz
+        package encourages using UTC for internal timezone representation by
+        including a special UTC implementation based on the standard Python
+        reference implementation in the Python documentation.
+        
+        The UTC timezone unpickles to be the same instance, and pickles to a
+        smaller size than other pytz tzinfo instances.  The UTC implementation
+        can be obtained as pytz.utc, pytz.UTC, or pytz.timezone('UTC').
+        
+        >>> import pickle, pytz
+        >>> dt = datetime(2005, 3, 1, 14, 13, 21, tzinfo=utc)
+        >>> naive = dt.replace(tzinfo=None)
+        >>> p = pickle.dumps(dt, 1)
+        >>> naive_p = pickle.dumps(naive, 1)
+        >>> len(p) - len(naive_p)
+        17
+        >>> new = pickle.loads(p)
+        >>> new == dt
+        True
+        >>> new is dt
+        False
+        >>> new.tzinfo is dt.tzinfo
+        True
+        >>> pytz.utc is pytz.UTC is pytz.timezone('UTC')
+        True
+        
+        Note that this instance is not the same instance (or implementation) as
+        other timezones with the same meaning (GMT, Greenwich, Universal, etc.).
+        
+        >>> utc is pytz.timezone('GMT')
+        False
+        
+        If you insist on working with local times, this library provides a
+        facility for constructing them unambiguously:
+        
+        >>> loc_dt = datetime(2002, 10, 27, 1, 30, 00)
+        >>> est_dt = eastern.localize(loc_dt, is_dst=True)
+        >>> edt_dt = eastern.localize(loc_dt, is_dst=False)
+        >>> print(est_dt.strftime(fmt) + ' / ' + edt_dt.strftime(fmt))
+        2002-10-27 01:30:00 EDT-0400 / 2002-10-27 01:30:00 EST-0500
+        
+        If you pass None as the is_dst flag to localize(), pytz will refuse to
+        guess and raise exceptions if you try to build ambiguous or non-existent
+        times.
+        
+        For example, 1:30am on 27th Oct 2002 happened twice in the US/Eastern
+        timezone when the clocks where put back at the end of Daylight Savings
+        Time:
+        
+        >>> dt = datetime(2002, 10, 27, 1, 30, 00)
+        >>> try:
+        ...     eastern.localize(dt, is_dst=None)
+        ... except pytz.exceptions.AmbiguousTimeError:
+        ...     print('pytz.exceptions.AmbiguousTimeError: %s' % dt)
+        pytz.exceptions.AmbiguousTimeError: 2002-10-27 01:30:00
+        
+        Similarly, 2:30am on 7th April 2002 never happened at all in the
+        US/Eastern timezone, as the clocks where put forward at 2:00am skipping
+        the entire hour:
+        
+        >>> dt = datetime(2002, 4, 7, 2, 30, 00)
+        >>> try:
+        ...     eastern.localize(dt, is_dst=None)
+        ... except pytz.exceptions.NonExistentTimeError:
+        ...     print('pytz.exceptions.NonExistentTimeError: %s' % dt)
+        pytz.exceptions.NonExistentTimeError: 2002-04-07 02:30:00
+        
+        Both of these exceptions share a common base class to make error handling
+        easier:
+        
+        >>> isinstance(pytz.AmbiguousTimeError(), pytz.InvalidTimeError)
+        True
+        >>> isinstance(pytz.NonExistentTimeError(), pytz.InvalidTimeError)
+        True
+        
+        Although ``localize()`` handles many cases, it is still not possible
+        to handle all. In cases where countries change their timezone definitions,
+        cases like the end-of-daylight-savings-time occur with no way of resolving
+        the ambiguity. For example, in 1915 Warsaw switched from Warsaw time to
+        Central European time. So at the stroke of midnight on August 5th 1915
+        the clocks were wound back 24 minutes creating an ambiguous time period
+        that cannot be specified without referring to the timezone abbreviation
+        or the actual UTC offset. In this case midnight happened twice, neither
+        time during a daylight savings time period:
+        
+        >>> warsaw = pytz.timezone('Europe/Warsaw')
+        >>> loc_dt1 = warsaw.localize(datetime(1915, 8, 4, 23, 59, 59), is_dst=False)
+        >>> loc_dt1.strftime(fmt)
+        '1915-08-04 23:59:59 WMT+0124'
+        >>> loc_dt2 = warsaw.localize(datetime(1915, 8, 5, 00, 00, 00), is_dst=False)
+        >>> loc_dt2.strftime(fmt)
+        '1915-08-05 00:00:00 CET+0100'
+        >>> str(loc_dt2 - loc_dt1)
+        '0:24:01'
+        
+        The only way of creating a time during the missing 24 minutes is
+        converting from another timezone - because neither of the timezones
+        involved where in daylight savings mode the API simply provides no way
+        to express it:
+        
+        >>> utc_dt = datetime(1915, 8, 4, 22, 36, tzinfo=pytz.utc)
+        >>> utc_dt.astimezone(warsaw).strftime(fmt)
+        '1915-08-04 23:36:00 CET+0100'
+        
+        The standard Python way of handling all these ambiguities is not to
+        handle them, such as demonstrated in this example using the US/Eastern
+        timezone definition from the Python documentation (Note that this
+        implementation only works for dates between 1987 and 2006 - it is
+        included for tests only!):
+        
+        >>> from pytz.reference import Eastern # pytz.reference only for tests
+        >>> dt = datetime(2002, 10, 27, 0, 30, tzinfo=Eastern)
+        >>> str(dt)
+        '2002-10-27 00:30:00-04:00'
+        >>> str(dt + timedelta(hours=1))
+        '2002-10-27 01:30:00-05:00'
+        >>> str(dt + timedelta(hours=2))
+        '2002-10-27 02:30:00-05:00'
+        >>> str(dt + timedelta(hours=3))
+        '2002-10-27 03:30:00-05:00'
+        
+        Notice the first two results? At first glance you might think they are
+        correct, but taking the UTC offset into account you find that they are
+        actually two hours appart instead of the 1 hour we asked for.
+        
+        >>> from pytz.reference import UTC # pytz.reference only for tests
+        >>> str(dt.astimezone(UTC))
+        '2002-10-27 04:30:00+00:00'
+        >>> str((dt + timedelta(hours=1)).astimezone(UTC))
+        '2002-10-27 06:30:00+00:00'
+        
+        
+        Country Information
+        ~~~~~~~~~~~~~~~~~~~
+        
+        A mechanism is provided to access the timezones commonly in use
+        for a particular country, looked up using the ISO 3166 country code.
+        It returns a list of strings that can be used to retrieve the relevant
+        tzinfo instance using ``pytz.timezone()``:
+        
+        >>> print(' '.join(pytz.country_timezones['nz']))
+        Pacific/Auckland Pacific/Chatham
+        
+        The Olson database comes with a ISO 3166 country code to English country
+        name mapping that pytz exposes as a dictionary:
+        
+        >>> print(pytz.country_names['nz'])
+        New Zealand
+        
+        
+        What is UTC
+        ~~~~~~~~~~~
+        
+        'UTC' is Universal Time, also known as Greenwich Mean Time or GMT
+        in the United Kingdom. All other timezones are given as offsets from
+        UTC. No daylight savings time occurs in UTC, making it a useful timezone
+        to perform date arithmetic without worrying about the confusion and
+        ambiguities caused by daylight savings time transitions, your country
+        changing its timezone, or mobile computers that move roam through
+        multiple timezones.
+        
+        
+        Helpers
+        ~~~~~~~
+        
+        There are two lists of timezones provided.
+        
+        ``all_timezones`` is the exhaustive list of the timezone names that can
+        be used.
+        
+        >>> from pytz import all_timezones
+        >>> len(all_timezones) >= 500
+        True
+        >>> 'Etc/Greenwich' in all_timezones
+        True
+        
+        ``common_timezones`` is a list of useful, current timezones. It doesn't
+        contain deprecated zones or historical zones, except for a few I've
+        deemed in common usage, such as US/Eastern (open a bug report if you
+        think other timezones are deserving of being included here). It is also
+        a sequence of strings.
+        
+        >>> from pytz import common_timezones
+        >>> len(common_timezones) < len(all_timezones)
+        True
+        >>> 'Etc/Greenwich' in common_timezones
+        False
+        >>> 'Australia/Melbourne' in common_timezones
+        True
+        >>> 'US/Eastern' in common_timezones
+        True
+        >>> 'Canada/Eastern' in common_timezones
+        True
+        >>> 'US/Pacific-New' in all_timezones
+        True
+        >>> 'US/Pacific-New' in common_timezones
+        False
+        
+        Both ``common_timezones`` and ``all_timezones`` are alphabetically
+        sorted:
+        
+        >>> common_timezones_dupe = common_timezones[:]
+        >>> common_timezones_dupe.sort()
+        >>> common_timezones == common_timezones_dupe
+        True
+        >>> all_timezones_dupe = all_timezones[:]
+        >>> all_timezones_dupe.sort()
+        >>> all_timezones == all_timezones_dupe
+        True
+        
+        ``all_timezones`` and ``common_timezones`` are also available as sets.
+        
+        >>> from pytz import all_timezones_set, common_timezones_set
+        >>> 'US/Eastern' in all_timezones_set
+        True
+        >>> 'US/Eastern' in common_timezones_set
+        True
+        >>> 'Australia/Victoria' in common_timezones_set
+        False
+        
+        You can also retrieve lists of timezones used by particular countries
+        using the ``country_timezones()`` function. It requires an ISO-3166
+        two letter country code.
+        
+        >>> from pytz import country_timezones
+        >>> print(' '.join(country_timezones('ch')))
+        Europe/Zurich
+        >>> print(' '.join(country_timezones('CH')))
+        Europe/Zurich
+        
+        
+        License
+        ~~~~~~~
+        
+        MIT license.
+        
+        This code is also available as part of Zope 3 under the Zope Public
+        License,  Version 2.1 (ZPL).
+        
+        I'm happy to relicense this code if necessary for inclusion in other
+        open source projects.
+        
+        
+        Latest Versions
+        ~~~~~~~~~~~~~~~
+        
+        This package will be updated after releases of the Olson timezone
+        database.  The latest version can be downloaded from the `Python Package
+        Index <http://pypi.python.org/pypi/pytz/>`_.  The code that is used
+        to generate this distribution is hosted on launchpad.net and available
+        using the `Bazaar version control system <http://bazaar-vcs.org>`_
+        using::
+        
+            bzr branch lp:pytz
+        
+        Announcements of new releases are made on
+        `Launchpad <https://launchpad.net/pytz>`_, and the
+        `Atom feed <http://feeds.launchpad.net/pytz/announcements.atom>`_
+        hosted there.
+        
+        
+        Bugs, Feature Requests & Patches
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        
+        Bugs can be reported using `Launchpad <https://bugs.launchpad.net/pytz>`_.
+        
+        
+        Issues & Limitations
+        ~~~~~~~~~~~~~~~~~~~~
+        
+        - Offsets from UTC are rounded to the nearest whole minute, so timezones
+          such as Europe/Amsterdam pre 1937 will be up to 30 seconds out. This
+          is a limitation of the Python datetime library.
+        
+        - If you think a timezone definition is incorrect, I probably can't fix
+          it. pytz is a direct translation of the Olson timezone database, and
+          changes to the timezone definitions need to be made to this source.
+          If you find errors they should be reported to the time zone mailing
+          list, linked from http://www.iana.org/time-zones.
+        
+        
+        Further Reading
+        ~~~~~~~~~~~~~~~
+        
+        More info than you want to know about timezones:
+        http://www.twinsun.com/tz/tz-link.htm
+        
+        
+        Contact
+        ~~~~~~~
+        
+        Stuart Bishop <stuart@stuartbishop.net>
+        
+        
+        
+Keywords: timezone,tzinfo,datetime,olson,time
+Platform: Independant
+Classifier: Development Status :: 6 - Mature
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Topic :: Software Development :: Libraries :: Python Modules

+ 558 - 0
desktop/core/ext-py/pytz-2013.9/README.txt

@@ -0,0 +1,558 @@
+pytz - World Timezone Definitions for Python
+============================================
+
+:Author: Stuart Bishop <stuart@stuartbishop.net>
+
+Introduction
+~~~~~~~~~~~~
+
+pytz brings the Olson tz database into Python. This library allows
+accurate and cross platform timezone calculations using Python 2.4
+or higher. It also solves the issue of ambiguous times at the end
+of daylight savings, which you can read more about in the Python
+Library Reference (``datetime.tzinfo``).
+
+Almost all of the Olson timezones are supported.
+
+.. note::
+
+    This library differs from the documented Python API for
+    tzinfo implementations; if you want to create local wallclock
+    times you need to use the ``localize()`` method documented in this
+    document. In addition, if you perform date arithmetic on local
+    times that cross DST boundaries, the result may be in an incorrect
+    timezone (ie. subtract 1 minute from 2002-10-27 1:00 EST and you get
+    2002-10-27 0:59 EST instead of the correct 2002-10-27 1:59 EDT). A
+    ``normalize()`` method is provided to correct this. Unfortunately these
+    issues cannot be resolved without modifying the Python datetime
+    implementation (see PEP-431).
+
+
+Installation
+~~~~~~~~~~~~
+
+This package can either be installed from a .egg file using setuptools,
+or from the tarball using the standard Python distutils.
+
+If you are installing from a tarball, run the following command as an
+administrative user::
+
+    python setup.py install
+
+If you are installing using setuptools, you don't even need to download
+anything as the latest version will be downloaded for you
+from the Python package index::
+
+    easy_install --upgrade pytz
+
+If you already have the .egg file, you can use that too::
+
+    easy_install pytz-2008g-py2.6.egg
+
+
+Example & Usage
+~~~~~~~~~~~~~~~
+
+Localized times and date arithmetic
+-----------------------------------
+
+>>> from datetime import datetime, timedelta
+>>> from pytz import timezone
+>>> import pytz
+>>> utc = pytz.utc
+>>> utc.zone
+'UTC'
+>>> eastern = timezone('US/Eastern')
+>>> eastern.zone
+'US/Eastern'
+>>> amsterdam = timezone('Europe/Amsterdam')
+>>> fmt = '%Y-%m-%d %H:%M:%S %Z%z'
+
+This library only supports two ways of building a localized time. The
+first is to use the ``localize()`` method provided by the pytz library.
+This is used to localize a naive datetime (datetime with no timezone
+information):
+
+>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
+>>> print(loc_dt.strftime(fmt))
+2002-10-27 06:00:00 EST-0500
+
+The second way of building a localized time is by converting an existing
+localized time using the standard ``astimezone()`` method:
+
+>>> ams_dt = loc_dt.astimezone(amsterdam)
+>>> ams_dt.strftime(fmt)
+'2002-10-27 12:00:00 CET+0100'
+
+Unfortunately using the tzinfo argument of the standard datetime
+constructors ''does not work'' with pytz for many timezones.
+
+>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt)
+'2002-10-27 12:00:00 AMT+0020'
+
+It is safe for timezones without daylight savings trasitions though, such
+as UTC:
+
+>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=pytz.utc).strftime(fmt)
+'2002-10-27 12:00:00 UTC+0000'
+
+The preferred way of dealing with times is to always work in UTC,
+converting to localtime only when generating output to be read
+by humans.
+
+>>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
+>>> loc_dt = utc_dt.astimezone(eastern)
+>>> loc_dt.strftime(fmt)
+'2002-10-27 01:00:00 EST-0500'
+
+This library also allows you to do date arithmetic using local
+times, although it is more complicated than working in UTC as you
+need to use the ``normalize()`` method to handle daylight savings time
+and other timezone transitions. In this example, ``loc_dt`` is set
+to the instant when daylight savings time ends in the US/Eastern
+timezone.
+
+>>> before = loc_dt - timedelta(minutes=10)
+>>> before.strftime(fmt)
+'2002-10-27 00:50:00 EST-0500'
+>>> eastern.normalize(before).strftime(fmt)
+'2002-10-27 01:50:00 EDT-0400'
+>>> after = eastern.normalize(before + timedelta(minutes=20))
+>>> after.strftime(fmt)
+'2002-10-27 01:10:00 EST-0500'
+
+Creating local times is also tricky, and the reason why working with
+local times is not recommended. Unfortunately, you cannot just pass
+a ``tzinfo`` argument when constructing a datetime (see the next
+section for more details)
+
+>>> dt = datetime(2002, 10, 27, 1, 30, 0)
+>>> dt1 = eastern.localize(dt, is_dst=True)
+>>> dt1.strftime(fmt)
+'2002-10-27 01:30:00 EDT-0400'
+>>> dt2 = eastern.localize(dt, is_dst=False)
+>>> dt2.strftime(fmt)
+'2002-10-27 01:30:00 EST-0500'
+
+Converting between timezones also needs special attention. We also need
+to use the ``normalize()`` method to ensure the conversion is correct.
+
+>>> utc_dt = utc.localize(datetime.utcfromtimestamp(1143408899))
+>>> utc_dt.strftime(fmt)
+'2006-03-26 21:34:59 UTC+0000'
+>>> au_tz = timezone('Australia/Sydney')
+>>> au_dt = au_tz.normalize(utc_dt.astimezone(au_tz))
+>>> au_dt.strftime(fmt)
+'2006-03-27 08:34:59 EST+1100'
+>>> utc_dt2 = utc.normalize(au_dt.astimezone(utc))
+>>> utc_dt2.strftime(fmt)
+'2006-03-26 21:34:59 UTC+0000'
+
+You can take shortcuts when dealing with the UTC side of timezone
+conversions. ``normalize()`` and ``localize()`` are not really
+necessary when there are no daylight savings time transitions to
+deal with.
+
+>>> utc_dt = datetime.utcfromtimestamp(1143408899).replace(tzinfo=utc)
+>>> utc_dt.strftime(fmt)
+'2006-03-26 21:34:59 UTC+0000'
+>>> au_tz = timezone('Australia/Sydney')
+>>> au_dt = au_tz.normalize(utc_dt.astimezone(au_tz))
+>>> au_dt.strftime(fmt)
+'2006-03-27 08:34:59 EST+1100'
+>>> utc_dt2 = au_dt.astimezone(utc)
+>>> utc_dt2.strftime(fmt)
+'2006-03-26 21:34:59 UTC+0000'
+
+
+``tzinfo`` API
+--------------
+
+The ``tzinfo`` instances returned by the ``timezone()`` function have
+been extended to cope with ambiguous times by adding an ``is_dst``
+parameter to the ``utcoffset()``, ``dst()`` && ``tzname()`` methods.
+
+>>> tz = timezone('America/St_Johns')
+
+>>> normal = datetime(2009, 9, 1)
+>>> ambiguous = datetime(2009, 10, 31, 23, 30)
+
+The ``is_dst`` parameter is ignored for most timestamps. It is only used
+during DST transition ambiguous periods to resulve that ambiguity.
+
+>>> tz.utcoffset(normal, is_dst=True)
+datetime.timedelta(-1, 77400)
+>>> tz.dst(normal, is_dst=True)
+datetime.timedelta(0, 3600)
+>>> tz.tzname(normal, is_dst=True)
+'NDT'
+
+>>> tz.utcoffset(ambiguous, is_dst=True)
+datetime.timedelta(-1, 77400)
+>>> tz.dst(ambiguous, is_dst=True)
+datetime.timedelta(0, 3600)
+>>> tz.tzname(ambiguous, is_dst=True)
+'NDT'
+
+>>> tz.utcoffset(normal, is_dst=False)
+datetime.timedelta(-1, 77400)
+>>> tz.dst(normal, is_dst=False)
+datetime.timedelta(0, 3600)
+>>> tz.tzname(normal, is_dst=False)
+'NDT'
+
+>>> tz.utcoffset(ambiguous, is_dst=False)
+datetime.timedelta(-1, 73800)
+>>> tz.dst(ambiguous, is_dst=False)
+datetime.timedelta(0)
+>>> tz.tzname(ambiguous, is_dst=False)
+'NST'
+
+If ``is_dst`` is not specified, ambiguous timestamps will raise
+an ``pytz.exceptions.AmbiguousTimeError`` exception.
+
+>>> tz.utcoffset(normal)
+datetime.timedelta(-1, 77400)
+>>> tz.dst(normal)
+datetime.timedelta(0, 3600)
+>>> tz.tzname(normal)
+'NDT'
+
+>>> import pytz.exceptions
+>>> try:
+...     tz.utcoffset(ambiguous)
+... except pytz.exceptions.AmbiguousTimeError:
+...     print('pytz.exceptions.AmbiguousTimeError: %s' % ambiguous)
+pytz.exceptions.AmbiguousTimeError: 2009-10-31 23:30:00
+>>> try:
+...     tz.dst(ambiguous)
+... except pytz.exceptions.AmbiguousTimeError:
+...     print('pytz.exceptions.AmbiguousTimeError: %s' % ambiguous)
+pytz.exceptions.AmbiguousTimeError: 2009-10-31 23:30:00
+>>> try:
+...     tz.tzname(ambiguous)
+... except pytz.exceptions.AmbiguousTimeError:
+...     print('pytz.exceptions.AmbiguousTimeError: %s' % ambiguous)
+pytz.exceptions.AmbiguousTimeError: 2009-10-31 23:30:00
+
+
+Problems with Localtime
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The major problem we have to deal with is that certain datetimes
+may occur twice in a year. For example, in the US/Eastern timezone
+on the last Sunday morning in October, the following sequence
+happens:
+
+    - 01:00 EDT occurs
+    - 1 hour later, instead of 2:00am the clock is turned back 1 hour
+      and 01:00 happens again (this time 01:00 EST)
+
+In fact, every instant between 01:00 and 02:00 occurs twice. This means
+that if you try and create a time in the 'US/Eastern' timezone using
+the standard datetime syntax, there is no way to specify if you meant
+before of after the end-of-daylight-savings-time transition.
+
+>>> loc_dt = datetime(2002, 10, 27, 1, 30, 00, tzinfo=eastern)
+>>> loc_dt.strftime(fmt)
+'2002-10-27 01:30:00 EST-0500'
+
+As you can see, the system has chosen one for you and there is a 50%
+chance of it being out by one hour. For some applications, this does
+not matter. However, if you are trying to schedule meetings with people
+in different timezones or analyze log files it is not acceptable. 
+
+The best and simplest solution is to stick with using UTC.  The pytz
+package encourages using UTC for internal timezone representation by
+including a special UTC implementation based on the standard Python
+reference implementation in the Python documentation.
+
+The UTC timezone unpickles to be the same instance, and pickles to a
+smaller size than other pytz tzinfo instances.  The UTC implementation
+can be obtained as pytz.utc, pytz.UTC, or pytz.timezone('UTC').
+
+>>> import pickle, pytz
+>>> dt = datetime(2005, 3, 1, 14, 13, 21, tzinfo=utc)
+>>> naive = dt.replace(tzinfo=None)
+>>> p = pickle.dumps(dt, 1)
+>>> naive_p = pickle.dumps(naive, 1)
+>>> len(p) - len(naive_p)
+17
+>>> new = pickle.loads(p)
+>>> new == dt
+True
+>>> new is dt
+False
+>>> new.tzinfo is dt.tzinfo
+True
+>>> pytz.utc is pytz.UTC is pytz.timezone('UTC')
+True
+
+Note that this instance is not the same instance (or implementation) as
+other timezones with the same meaning (GMT, Greenwich, Universal, etc.).
+
+>>> utc is pytz.timezone('GMT')
+False
+
+If you insist on working with local times, this library provides a
+facility for constructing them unambiguously:
+
+>>> loc_dt = datetime(2002, 10, 27, 1, 30, 00)
+>>> est_dt = eastern.localize(loc_dt, is_dst=True)
+>>> edt_dt = eastern.localize(loc_dt, is_dst=False)
+>>> print(est_dt.strftime(fmt) + ' / ' + edt_dt.strftime(fmt))
+2002-10-27 01:30:00 EDT-0400 / 2002-10-27 01:30:00 EST-0500
+
+If you pass None as the is_dst flag to localize(), pytz will refuse to
+guess and raise exceptions if you try to build ambiguous or non-existent
+times.
+
+For example, 1:30am on 27th Oct 2002 happened twice in the US/Eastern
+timezone when the clocks where put back at the end of Daylight Savings
+Time:
+
+>>> dt = datetime(2002, 10, 27, 1, 30, 00)
+>>> try:
+...     eastern.localize(dt, is_dst=None)
+... except pytz.exceptions.AmbiguousTimeError:
+...     print('pytz.exceptions.AmbiguousTimeError: %s' % dt)
+pytz.exceptions.AmbiguousTimeError: 2002-10-27 01:30:00
+
+Similarly, 2:30am on 7th April 2002 never happened at all in the
+US/Eastern timezone, as the clocks where put forward at 2:00am skipping
+the entire hour:
+
+>>> dt = datetime(2002, 4, 7, 2, 30, 00)
+>>> try:
+...     eastern.localize(dt, is_dst=None)
+... except pytz.exceptions.NonExistentTimeError:
+...     print('pytz.exceptions.NonExistentTimeError: %s' % dt)
+pytz.exceptions.NonExistentTimeError: 2002-04-07 02:30:00
+
+Both of these exceptions share a common base class to make error handling
+easier:
+
+>>> isinstance(pytz.AmbiguousTimeError(), pytz.InvalidTimeError)
+True
+>>> isinstance(pytz.NonExistentTimeError(), pytz.InvalidTimeError)
+True
+
+Although ``localize()`` handles many cases, it is still not possible
+to handle all. In cases where countries change their timezone definitions,
+cases like the end-of-daylight-savings-time occur with no way of resolving
+the ambiguity. For example, in 1915 Warsaw switched from Warsaw time to
+Central European time. So at the stroke of midnight on August 5th 1915
+the clocks were wound back 24 minutes creating an ambiguous time period
+that cannot be specified without referring to the timezone abbreviation
+or the actual UTC offset. In this case midnight happened twice, neither
+time during a daylight savings time period:
+
+>>> warsaw = pytz.timezone('Europe/Warsaw')
+>>> loc_dt1 = warsaw.localize(datetime(1915, 8, 4, 23, 59, 59), is_dst=False)
+>>> loc_dt1.strftime(fmt)
+'1915-08-04 23:59:59 WMT+0124'
+>>> loc_dt2 = warsaw.localize(datetime(1915, 8, 5, 00, 00, 00), is_dst=False)
+>>> loc_dt2.strftime(fmt)
+'1915-08-05 00:00:00 CET+0100'
+>>> str(loc_dt2 - loc_dt1)
+'0:24:01'
+
+The only way of creating a time during the missing 24 minutes is
+converting from another timezone - because neither of the timezones
+involved where in daylight savings mode the API simply provides no way
+to express it:
+
+>>> utc_dt = datetime(1915, 8, 4, 22, 36, tzinfo=pytz.utc)
+>>> utc_dt.astimezone(warsaw).strftime(fmt)
+'1915-08-04 23:36:00 CET+0100'
+
+The standard Python way of handling all these ambiguities is not to
+handle them, such as demonstrated in this example using the US/Eastern
+timezone definition from the Python documentation (Note that this
+implementation only works for dates between 1987 and 2006 - it is
+included for tests only!):
+
+>>> from pytz.reference import Eastern # pytz.reference only for tests
+>>> dt = datetime(2002, 10, 27, 0, 30, tzinfo=Eastern)
+>>> str(dt)
+'2002-10-27 00:30:00-04:00'
+>>> str(dt + timedelta(hours=1))
+'2002-10-27 01:30:00-05:00'
+>>> str(dt + timedelta(hours=2))
+'2002-10-27 02:30:00-05:00'
+>>> str(dt + timedelta(hours=3))
+'2002-10-27 03:30:00-05:00'
+
+Notice the first two results? At first glance you might think they are
+correct, but taking the UTC offset into account you find that they are
+actually two hours appart instead of the 1 hour we asked for.
+
+>>> from pytz.reference import UTC # pytz.reference only for tests
+>>> str(dt.astimezone(UTC))
+'2002-10-27 04:30:00+00:00'
+>>> str((dt + timedelta(hours=1)).astimezone(UTC))
+'2002-10-27 06:30:00+00:00'
+
+
+Country Information
+~~~~~~~~~~~~~~~~~~~
+
+A mechanism is provided to access the timezones commonly in use
+for a particular country, looked up using the ISO 3166 country code.
+It returns a list of strings that can be used to retrieve the relevant
+tzinfo instance using ``pytz.timezone()``:
+
+>>> print(' '.join(pytz.country_timezones['nz']))
+Pacific/Auckland Pacific/Chatham
+
+The Olson database comes with a ISO 3166 country code to English country
+name mapping that pytz exposes as a dictionary:
+
+>>> print(pytz.country_names['nz'])
+New Zealand
+
+
+What is UTC
+~~~~~~~~~~~
+
+'UTC' is Universal Time, also known as Greenwich Mean Time or GMT
+in the United Kingdom. All other timezones are given as offsets from
+UTC. No daylight savings time occurs in UTC, making it a useful timezone
+to perform date arithmetic without worrying about the confusion and
+ambiguities caused by daylight savings time transitions, your country
+changing its timezone, or mobile computers that move roam through
+multiple timezones.
+
+
+Helpers
+~~~~~~~
+
+There are two lists of timezones provided.
+
+``all_timezones`` is the exhaustive list of the timezone names that can
+be used.
+
+>>> from pytz import all_timezones
+>>> len(all_timezones) >= 500
+True
+>>> 'Etc/Greenwich' in all_timezones
+True
+
+``common_timezones`` is a list of useful, current timezones. It doesn't
+contain deprecated zones or historical zones, except for a few I've
+deemed in common usage, such as US/Eastern (open a bug report if you
+think other timezones are deserving of being included here). It is also
+a sequence of strings.
+
+>>> from pytz import common_timezones
+>>> len(common_timezones) < len(all_timezones)
+True
+>>> 'Etc/Greenwich' in common_timezones
+False
+>>> 'Australia/Melbourne' in common_timezones
+True
+>>> 'US/Eastern' in common_timezones
+True
+>>> 'Canada/Eastern' in common_timezones
+True
+>>> 'US/Pacific-New' in all_timezones
+True
+>>> 'US/Pacific-New' in common_timezones
+False
+
+Both ``common_timezones`` and ``all_timezones`` are alphabetically
+sorted:
+
+>>> common_timezones_dupe = common_timezones[:]
+>>> common_timezones_dupe.sort()
+>>> common_timezones == common_timezones_dupe
+True
+>>> all_timezones_dupe = all_timezones[:]
+>>> all_timezones_dupe.sort()
+>>> all_timezones == all_timezones_dupe
+True
+
+``all_timezones`` and ``common_timezones`` are also available as sets.
+
+>>> from pytz import all_timezones_set, common_timezones_set
+>>> 'US/Eastern' in all_timezones_set
+True
+>>> 'US/Eastern' in common_timezones_set
+True
+>>> 'Australia/Victoria' in common_timezones_set
+False
+
+You can also retrieve lists of timezones used by particular countries
+using the ``country_timezones()`` function. It requires an ISO-3166
+two letter country code.
+
+>>> from pytz import country_timezones
+>>> print(' '.join(country_timezones('ch')))
+Europe/Zurich
+>>> print(' '.join(country_timezones('CH')))
+Europe/Zurich
+
+
+License
+~~~~~~~
+
+MIT license.
+
+This code is also available as part of Zope 3 under the Zope Public
+License,  Version 2.1 (ZPL).
+
+I'm happy to relicense this code if necessary for inclusion in other
+open source projects.
+
+
+Latest Versions
+~~~~~~~~~~~~~~~
+
+This package will be updated after releases of the Olson timezone
+database.  The latest version can be downloaded from the `Python Package
+Index <http://pypi.python.org/pypi/pytz/>`_.  The code that is used
+to generate this distribution is hosted on launchpad.net and available
+using the `Bazaar version control system <http://bazaar-vcs.org>`_
+using::
+
+    bzr branch lp:pytz
+
+Announcements of new releases are made on
+`Launchpad <https://launchpad.net/pytz>`_, and the
+`Atom feed <http://feeds.launchpad.net/pytz/announcements.atom>`_
+hosted there.
+
+
+Bugs, Feature Requests & Patches
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Bugs can be reported using `Launchpad <https://bugs.launchpad.net/pytz>`_.
+
+
+Issues & Limitations
+~~~~~~~~~~~~~~~~~~~~
+
+- Offsets from UTC are rounded to the nearest whole minute, so timezones
+  such as Europe/Amsterdam pre 1937 will be up to 30 seconds out. This
+  is a limitation of the Python datetime library.
+
+- If you think a timezone definition is incorrect, I probably can't fix
+  it. pytz is a direct translation of the Olson timezone database, and
+  changes to the timezone definitions need to be made to this source.
+  If you find errors they should be reported to the time zone mailing
+  list, linked from http://www.iana.org/time-zones.
+
+
+Further Reading
+~~~~~~~~~~~~~~~
+
+More info than you want to know about timezones:
+http://www.twinsun.com/tz/tz-link.htm
+
+
+Contact
+~~~~~~~
+
+Stuart Bishop <stuart@stuartbishop.net>
+
+

+ 1508 - 0
desktop/core/ext-py/pytz-2013.9/pytz/__init__.py

@@ -0,0 +1,1508 @@
+'''
+datetime.tzinfo timezone definitions generated from the
+Olson timezone database:
+
+    ftp://elsie.nci.nih.gov/pub/tz*.tar.gz
+
+See the datetime section of the Python Library Reference for information
+on how to use these modules.
+'''
+
+# The Olson database is updated several times a year.
+OLSON_VERSION = '2013i'
+VERSION = '2013.9'  # Switching to pip compatible version numbering.
+__version__ = VERSION
+
+OLSEN_VERSION = OLSON_VERSION # Old releases had this misspelling
+
+__all__ = [
+    'timezone', 'utc', 'country_timezones', 'country_names',
+    'AmbiguousTimeError', 'InvalidTimeError',
+    'NonExistentTimeError', 'UnknownTimeZoneError',
+    'all_timezones', 'all_timezones_set',
+    'common_timezones', 'common_timezones_set',
+    ]
+
+import sys, datetime, os.path, gettext
+
+try:
+    from pkg_resources import resource_stream
+except ImportError:
+    resource_stream = None
+
+from pytz.exceptions import AmbiguousTimeError
+from pytz.exceptions import InvalidTimeError
+from pytz.exceptions import NonExistentTimeError
+from pytz.exceptions import UnknownTimeZoneError
+from pytz.lazy import LazyDict, LazyList, LazySet
+from pytz.tzinfo import unpickler
+from pytz.tzfile import build_tzinfo, _byte_string
+
+
+try:
+    unicode
+
+except NameError: # Python 3.x
+
+    # Python 3.x doesn't have unicode(), making writing code
+    # for Python 2.3 and Python 3.x a pain.
+    unicode = str
+
+    def ascii(s):
+        r"""
+        >>> ascii('Hello')
+        'Hello'
+        >>> ascii('\N{TRADE MARK SIGN}') #doctest: +IGNORE_EXCEPTION_DETAIL
+        Traceback (most recent call last):
+            ...
+        UnicodeEncodeError: ...
+        """
+        s.encode('US-ASCII') # Raise an exception if not ASCII
+        return s # But return the original string - not a byte string.
+
+else: # Python 2.x
+
+    def ascii(s):
+        r"""
+        >>> ascii('Hello')
+        'Hello'
+        >>> ascii(u'Hello')
+        'Hello'
+        >>> ascii(u'\N{TRADE MARK SIGN}') #doctest: +IGNORE_EXCEPTION_DETAIL
+        Traceback (most recent call last):
+            ...
+        UnicodeEncodeError: ...
+        """
+        return s.encode('US-ASCII')
+
+
+def open_resource(name):
+    """Open a resource from the zoneinfo subdir for reading.
+
+    Uses the pkg_resources module if available and no standard file
+    found at the calculated location.
+    """
+    name_parts = name.lstrip('/').split('/')
+    for part in name_parts:
+        if part == os.path.pardir or os.path.sep in part:
+            raise ValueError('Bad path segment: %r' % part)
+    filename = os.path.join(os.path.dirname(__file__),
+                            'zoneinfo', *name_parts)
+    if not os.path.exists(filename) and resource_stream is not None:
+        # http://bugs.launchpad.net/bugs/383171 - we avoid using this
+        # unless absolutely necessary to help when a broken version of
+        # pkg_resources is installed.
+        return resource_stream(__name__, 'zoneinfo/' + name)
+    return open(filename, 'rb')
+
+
+def resource_exists(name):
+    """Return true if the given resource exists"""
+    try:
+        open_resource(name).close()
+        return True
+    except IOError:
+        return False
+
+
+# Enable this when we get some translations?
+# We want an i18n API that is useful to programs using Python's gettext
+# module, as well as the Zope3 i18n package. Perhaps we should just provide
+# the POT file and translations, and leave it up to callers to make use
+# of them.
+# 
+# t = gettext.translation(
+#         'pytz', os.path.join(os.path.dirname(__file__), 'locales'),
+#         fallback=True
+#         )
+# def _(timezone_name):
+#     """Translate a timezone name using the current locale, returning Unicode"""
+#     return t.ugettext(timezone_name)
+
+
+_tzinfo_cache = {}
+
+def timezone(zone):
+    r''' Return a datetime.tzinfo implementation for the given timezone 
+
+    >>> from datetime import datetime, timedelta
+    >>> utc = timezone('UTC')
+    >>> eastern = timezone('US/Eastern')
+    >>> eastern.zone
+    'US/Eastern'
+    >>> timezone(unicode('US/Eastern')) is eastern
+    True
+    >>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
+    >>> loc_dt = utc_dt.astimezone(eastern)
+    >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+    >>> loc_dt.strftime(fmt)
+    '2002-10-27 01:00:00 EST (-0500)'
+    >>> (loc_dt - timedelta(minutes=10)).strftime(fmt)
+    '2002-10-27 00:50:00 EST (-0500)'
+    >>> eastern.normalize(loc_dt - timedelta(minutes=10)).strftime(fmt)
+    '2002-10-27 01:50:00 EDT (-0400)'
+    >>> (loc_dt + timedelta(minutes=10)).strftime(fmt)
+    '2002-10-27 01:10:00 EST (-0500)'
+
+    Raises UnknownTimeZoneError if passed an unknown zone.
+
+    >>> try:
+    ...     timezone('Asia/Shangri-La')
+    ... except UnknownTimeZoneError:
+    ...     print('Unknown')
+    Unknown
+
+    >>> try:
+    ...     timezone(unicode('\N{TRADE MARK SIGN}'))
+    ... except UnknownTimeZoneError:
+    ...     print('Unknown')
+    Unknown
+
+    '''
+    if zone.upper() == 'UTC':
+        return utc
+
+    try:
+        zone = ascii(zone)
+    except UnicodeEncodeError:
+        # All valid timezones are ASCII
+        raise UnknownTimeZoneError(zone)
+
+    zone = _unmunge_zone(zone)
+    if zone not in _tzinfo_cache:
+        if zone in all_timezones_set:
+            fp = open_resource(zone)
+            try:
+                _tzinfo_cache[zone] = build_tzinfo(zone, fp)
+            finally:
+                fp.close()
+        else:
+            raise UnknownTimeZoneError(zone)
+
+    return _tzinfo_cache[zone]
+
+
+def _unmunge_zone(zone):
+    """Undo the time zone name munging done by older versions of pytz."""
+    return zone.replace('_plus_', '+').replace('_minus_', '-')
+
+
+ZERO = datetime.timedelta(0)
+HOUR = datetime.timedelta(hours=1)
+
+
+class UTC(datetime.tzinfo):
+    """UTC
+
+    Optimized UTC implementation. It unpickles using the single module global
+    instance defined beneath this class declaration.
+    """
+    zone = "UTC"
+
+    _utcoffset = ZERO
+    _dst = ZERO
+    _tzname = zone
+
+    def fromutc(self, dt):
+        if dt.tzinfo is None:
+            return self.localize(dt)
+        return super(utc.__class__, self).fromutc(dt)
+
+    def utcoffset(self, dt):
+        return ZERO
+
+    def tzname(self, dt):
+        return "UTC"
+
+    def dst(self, dt):
+        return ZERO
+
+    def __reduce__(self):
+        return _UTC, ()
+
+    def localize(self, dt, is_dst=False):
+        '''Convert naive time to local time'''
+        if dt.tzinfo is not None:
+            raise ValueError('Not naive datetime (tzinfo is already set)')
+        return dt.replace(tzinfo=self)
+
+    def normalize(self, dt, is_dst=False):
+        '''Correct the timezone information on the given datetime'''
+        if dt.tzinfo is self:
+            return dt
+        if dt.tzinfo is None:
+            raise ValueError('Naive time - no tzinfo set')
+        return dt.astimezone(self)
+
+    def __repr__(self):
+        return "<UTC>"
+
+    def __str__(self):
+        return "UTC"
+
+
+UTC = utc = UTC() # UTC is a singleton
+
+
+def _UTC():
+    """Factory function for utc unpickling.
+
+    Makes sure that unpickling a utc instance always returns the same 
+    module global.
+
+    These examples belong in the UTC class above, but it is obscured; or in
+    the README.txt, but we are not depending on Python 2.4 so integrating
+    the README.txt examples with the unit tests is not trivial.
+
+    >>> import datetime, pickle
+    >>> dt = datetime.datetime(2005, 3, 1, 14, 13, 21, tzinfo=utc)
+    >>> naive = dt.replace(tzinfo=None)
+    >>> p = pickle.dumps(dt, 1)
+    >>> naive_p = pickle.dumps(naive, 1)
+    >>> len(p) - len(naive_p)
+    17
+    >>> new = pickle.loads(p)
+    >>> new == dt
+    True
+    >>> new is dt
+    False
+    >>> new.tzinfo is dt.tzinfo
+    True
+    >>> utc is UTC is timezone('UTC')
+    True
+    >>> utc is timezone('GMT')
+    False
+    """
+    return utc
+_UTC.__safe_for_unpickling__ = True
+
+
+def _p(*args):
+    """Factory function for unpickling pytz tzinfo instances.
+
+    Just a wrapper around tzinfo.unpickler to save a few bytes in each pickle
+    by shortening the path.
+    """
+    return unpickler(*args)
+_p.__safe_for_unpickling__ = True
+
+
+
+class _CountryTimezoneDict(LazyDict):
+    """Map ISO 3166 country code to a list of timezone names commonly used
+    in that country.
+
+    iso3166_code is the two letter code used to identify the country.
+
+    >>> def print_list(list_of_strings):
+    ...     'We use a helper so doctests work under Python 2.3 -> 3.x'
+    ...     for s in list_of_strings:
+    ...         print(s)
+
+    >>> print_list(country_timezones['nz'])
+    Pacific/Auckland
+    Pacific/Chatham
+    >>> print_list(country_timezones['ch'])
+    Europe/Zurich
+    >>> print_list(country_timezones['CH'])
+    Europe/Zurich
+    >>> print_list(country_timezones[unicode('ch')])
+    Europe/Zurich
+    >>> print_list(country_timezones['XXX'])
+    Traceback (most recent call last):
+    ...
+    KeyError: 'XXX'
+
+    Previously, this information was exposed as a function rather than a
+    dictionary. This is still supported::
+
+    >>> print_list(country_timezones('nz'))
+    Pacific/Auckland
+    Pacific/Chatham
+    """
+    def __call__(self, iso3166_code):
+        """Backwards compatibility."""
+        return self[iso3166_code]
+
+    def _fill(self):
+        data = {}
+        zone_tab = open_resource('zone.tab')
+        try:
+            for line in zone_tab:
+                line = line.decode('US-ASCII')
+                if line.startswith('#'):
+                    continue
+                code, coordinates, zone = line.split(None, 4)[:3]
+                if zone not in all_timezones_set:
+                    continue
+                try:
+                    data[code].append(zone)
+                except KeyError:
+                    data[code] = [zone]
+            self.data = data
+        finally:
+            zone_tab.close()
+
+country_timezones = _CountryTimezoneDict()
+
+
+class _CountryNameDict(LazyDict):
+    '''Dictionary proving ISO3166 code -> English name.
+
+    >>> print(country_names['au'])
+    Australia
+    '''
+    def _fill(self):
+        data = {}
+        zone_tab = open_resource('iso3166.tab')
+        try:
+            for line in zone_tab.readlines():
+                line = line.decode('US-ASCII')
+                if line.startswith('#'):
+                    continue
+                code, name = line.split(None, 1)
+                data[code] = name.strip()
+            self.data = data
+        finally:
+            zone_tab.close()
+
+country_names = _CountryNameDict()
+
+
+# Time-zone info based solely on fixed offsets
+
+class _FixedOffset(datetime.tzinfo):
+
+    zone = None # to match the standard pytz API
+
+    def __init__(self, minutes):
+        if abs(minutes) >= 1440:
+            raise ValueError("absolute offset is too large", minutes)
+        self._minutes = minutes
+        self._offset = datetime.timedelta(minutes=minutes)
+
+    def utcoffset(self, dt):
+        return self._offset
+
+    def __reduce__(self):
+        return FixedOffset, (self._minutes, )
+
+    def dst(self, dt):
+        return ZERO
+
+    def tzname(self, dt):
+        return None
+
+    def __repr__(self):
+        return 'pytz.FixedOffset(%d)' % self._minutes
+
+    def localize(self, dt, is_dst=False):
+        '''Convert naive time to local time'''
+        if dt.tzinfo is not None:
+            raise ValueError('Not naive datetime (tzinfo is already set)')
+        return dt.replace(tzinfo=self)
+
+    def normalize(self, dt, is_dst=False):
+        '''Correct the timezone information on the given datetime'''
+        if dt.tzinfo is None:
+            raise ValueError('Naive time - no tzinfo set')
+        return dt.replace(tzinfo=self)
+
+
+def FixedOffset(offset, _tzinfos = {}):
+    """return a fixed-offset timezone based off a number of minutes.
+
+        >>> one = FixedOffset(-330)
+        >>> one
+        pytz.FixedOffset(-330)
+        >>> one.utcoffset(datetime.datetime.now())
+        datetime.timedelta(-1, 66600)
+        >>> one.dst(datetime.datetime.now())
+        datetime.timedelta(0)
+
+        >>> two = FixedOffset(1380)
+        >>> two
+        pytz.FixedOffset(1380)
+        >>> two.utcoffset(datetime.datetime.now())
+        datetime.timedelta(0, 82800)
+        >>> two.dst(datetime.datetime.now())
+        datetime.timedelta(0)
+
+    The datetime.timedelta must be between the range of -1 and 1 day,
+    non-inclusive.
+
+        >>> FixedOffset(1440)
+        Traceback (most recent call last):
+        ...
+        ValueError: ('absolute offset is too large', 1440)
+
+        >>> FixedOffset(-1440)
+        Traceback (most recent call last):
+        ...
+        ValueError: ('absolute offset is too large', -1440)
+
+    An offset of 0 is special-cased to return UTC.
+
+        >>> FixedOffset(0) is UTC
+        True
+
+    There should always be only one instance of a FixedOffset per timedelta.
+    This should be true for multiple creation calls.
+
+        >>> FixedOffset(-330) is one
+        True
+        >>> FixedOffset(1380) is two
+        True
+
+    It should also be true for pickling.
+
+        >>> import pickle
+        >>> pickle.loads(pickle.dumps(one)) is one
+        True
+        >>> pickle.loads(pickle.dumps(two)) is two
+        True
+    """
+    if offset == 0:
+        return UTC
+
+    info = _tzinfos.get(offset)
+    if info is None:
+        # We haven't seen this one before. we need to save it.
+
+        # Use setdefault to avoid a race condition and make sure we have
+        # only one
+        info = _tzinfos.setdefault(offset, _FixedOffset(offset))
+
+    return info
+
+FixedOffset.__safe_for_unpickling__ = True
+
+
+def _test():
+    import doctest, os, sys
+    sys.path.insert(0, os.pardir)
+    import pytz
+    return doctest.testmod(pytz)
+
+if __name__ == '__main__':
+    _test()
+
+all_timezones = \
+['Africa/Abidjan',
+ 'Africa/Accra',
+ 'Africa/Addis_Ababa',
+ 'Africa/Algiers',
+ 'Africa/Asmara',
+ 'Africa/Asmera',
+ 'Africa/Bamako',
+ 'Africa/Bangui',
+ 'Africa/Banjul',
+ 'Africa/Bissau',
+ 'Africa/Blantyre',
+ 'Africa/Brazzaville',
+ 'Africa/Bujumbura',
+ 'Africa/Cairo',
+ 'Africa/Casablanca',
+ 'Africa/Ceuta',
+ 'Africa/Conakry',
+ 'Africa/Dakar',
+ 'Africa/Dar_es_Salaam',
+ 'Africa/Djibouti',
+ 'Africa/Douala',
+ 'Africa/El_Aaiun',
+ 'Africa/Freetown',
+ 'Africa/Gaborone',
+ 'Africa/Harare',
+ 'Africa/Johannesburg',
+ 'Africa/Juba',
+ 'Africa/Kampala',
+ 'Africa/Khartoum',
+ 'Africa/Kigali',
+ 'Africa/Kinshasa',
+ 'Africa/Lagos',
+ 'Africa/Libreville',
+ 'Africa/Lome',
+ 'Africa/Luanda',
+ 'Africa/Lubumbashi',
+ 'Africa/Lusaka',
+ 'Africa/Malabo',
+ 'Africa/Maputo',
+ 'Africa/Maseru',
+ 'Africa/Mbabane',
+ 'Africa/Mogadishu',
+ 'Africa/Monrovia',
+ 'Africa/Nairobi',
+ 'Africa/Ndjamena',
+ 'Africa/Niamey',
+ 'Africa/Nouakchott',
+ 'Africa/Ouagadougou',
+ 'Africa/Porto-Novo',
+ 'Africa/Sao_Tome',
+ 'Africa/Timbuktu',
+ 'Africa/Tripoli',
+ 'Africa/Tunis',
+ 'Africa/Windhoek',
+ 'America/Adak',
+ 'America/Anchorage',
+ 'America/Anguilla',
+ 'America/Antigua',
+ 'America/Araguaina',
+ 'America/Argentina/Buenos_Aires',
+ 'America/Argentina/Catamarca',
+ 'America/Argentina/ComodRivadavia',
+ 'America/Argentina/Cordoba',
+ 'America/Argentina/Jujuy',
+ 'America/Argentina/La_Rioja',
+ 'America/Argentina/Mendoza',
+ 'America/Argentina/Rio_Gallegos',
+ 'America/Argentina/Salta',
+ 'America/Argentina/San_Juan',
+ 'America/Argentina/San_Luis',
+ 'America/Argentina/Tucuman',
+ 'America/Argentina/Ushuaia',
+ 'America/Aruba',
+ 'America/Asuncion',
+ 'America/Atikokan',
+ 'America/Atka',
+ 'America/Bahia',
+ 'America/Bahia_Banderas',
+ 'America/Barbados',
+ 'America/Belem',
+ 'America/Belize',
+ 'America/Blanc-Sablon',
+ 'America/Boa_Vista',
+ 'America/Bogota',
+ 'America/Boise',
+ 'America/Buenos_Aires',
+ 'America/Cambridge_Bay',
+ 'America/Campo_Grande',
+ 'America/Cancun',
+ 'America/Caracas',
+ 'America/Catamarca',
+ 'America/Cayenne',
+ 'America/Cayman',
+ 'America/Chicago',
+ 'America/Chihuahua',
+ 'America/Coral_Harbour',
+ 'America/Cordoba',
+ 'America/Costa_Rica',
+ 'America/Creston',
+ 'America/Cuiaba',
+ 'America/Curacao',
+ 'America/Danmarkshavn',
+ 'America/Dawson',
+ 'America/Dawson_Creek',
+ 'America/Denver',
+ 'America/Detroit',
+ 'America/Dominica',
+ 'America/Edmonton',
+ 'America/Eirunepe',
+ 'America/El_Salvador',
+ 'America/Ensenada',
+ 'America/Fort_Wayne',
+ 'America/Fortaleza',
+ 'America/Glace_Bay',
+ 'America/Godthab',
+ 'America/Goose_Bay',
+ 'America/Grand_Turk',
+ 'America/Grenada',
+ 'America/Guadeloupe',
+ 'America/Guatemala',
+ 'America/Guayaquil',
+ 'America/Guyana',
+ 'America/Halifax',
+ 'America/Havana',
+ 'America/Hermosillo',
+ 'America/Indiana/Indianapolis',
+ 'America/Indiana/Knox',
+ 'America/Indiana/Marengo',
+ 'America/Indiana/Petersburg',
+ 'America/Indiana/Tell_City',
+ 'America/Indiana/Vevay',
+ 'America/Indiana/Vincennes',
+ 'America/Indiana/Winamac',
+ 'America/Indianapolis',
+ 'America/Inuvik',
+ 'America/Iqaluit',
+ 'America/Jamaica',
+ 'America/Jujuy',
+ 'America/Juneau',
+ 'America/Kentucky/Louisville',
+ 'America/Kentucky/Monticello',
+ 'America/Knox_IN',
+ 'America/Kralendijk',
+ 'America/La_Paz',
+ 'America/Lima',
+ 'America/Los_Angeles',
+ 'America/Louisville',
+ 'America/Lower_Princes',
+ 'America/Maceio',
+ 'America/Managua',
+ 'America/Manaus',
+ 'America/Marigot',
+ 'America/Martinique',
+ 'America/Matamoros',
+ 'America/Mazatlan',
+ 'America/Mendoza',
+ 'America/Menominee',
+ 'America/Merida',
+ 'America/Metlakatla',
+ 'America/Mexico_City',
+ 'America/Miquelon',
+ 'America/Moncton',
+ 'America/Monterrey',
+ 'America/Montevideo',
+ 'America/Montreal',
+ 'America/Montserrat',
+ 'America/Nassau',
+ 'America/New_York',
+ 'America/Nipigon',
+ 'America/Nome',
+ 'America/Noronha',
+ 'America/North_Dakota/Beulah',
+ 'America/North_Dakota/Center',
+ 'America/North_Dakota/New_Salem',
+ 'America/Ojinaga',
+ 'America/Panama',
+ 'America/Pangnirtung',
+ 'America/Paramaribo',
+ 'America/Phoenix',
+ 'America/Port-au-Prince',
+ 'America/Port_of_Spain',
+ 'America/Porto_Acre',
+ 'America/Porto_Velho',
+ 'America/Puerto_Rico',
+ 'America/Rainy_River',
+ 'America/Rankin_Inlet',
+ 'America/Recife',
+ 'America/Regina',
+ 'America/Resolute',
+ 'America/Rio_Branco',
+ 'America/Rosario',
+ 'America/Santa_Isabel',
+ 'America/Santarem',
+ 'America/Santiago',
+ 'America/Santo_Domingo',
+ 'America/Sao_Paulo',
+ 'America/Scoresbysund',
+ 'America/Shiprock',
+ 'America/Sitka',
+ 'America/St_Barthelemy',
+ 'America/St_Johns',
+ 'America/St_Kitts',
+ 'America/St_Lucia',
+ 'America/St_Thomas',
+ 'America/St_Vincent',
+ 'America/Swift_Current',
+ 'America/Tegucigalpa',
+ 'America/Thule',
+ 'America/Thunder_Bay',
+ 'America/Tijuana',
+ 'America/Toronto',
+ 'America/Tortola',
+ 'America/Vancouver',
+ 'America/Virgin',
+ 'America/Whitehorse',
+ 'America/Winnipeg',
+ 'America/Yakutat',
+ 'America/Yellowknife',
+ 'Antarctica/Casey',
+ 'Antarctica/Davis',
+ 'Antarctica/DumontDUrville',
+ 'Antarctica/Macquarie',
+ 'Antarctica/Mawson',
+ 'Antarctica/McMurdo',
+ 'Antarctica/Palmer',
+ 'Antarctica/Rothera',
+ 'Antarctica/South_Pole',
+ 'Antarctica/Syowa',
+ 'Antarctica/Vostok',
+ 'Arctic/Longyearbyen',
+ 'Asia/Aden',
+ 'Asia/Almaty',
+ 'Asia/Amman',
+ 'Asia/Anadyr',
+ 'Asia/Aqtau',
+ 'Asia/Aqtobe',
+ 'Asia/Ashgabat',
+ 'Asia/Ashkhabad',
+ 'Asia/Baghdad',
+ 'Asia/Bahrain',
+ 'Asia/Baku',
+ 'Asia/Bangkok',
+ 'Asia/Beirut',
+ 'Asia/Bishkek',
+ 'Asia/Brunei',
+ 'Asia/Calcutta',
+ 'Asia/Choibalsan',
+ 'Asia/Chongqing',
+ 'Asia/Chungking',
+ 'Asia/Colombo',
+ 'Asia/Dacca',
+ 'Asia/Damascus',
+ 'Asia/Dhaka',
+ 'Asia/Dili',
+ 'Asia/Dubai',
+ 'Asia/Dushanbe',
+ 'Asia/Gaza',
+ 'Asia/Harbin',
+ 'Asia/Hebron',
+ 'Asia/Ho_Chi_Minh',
+ 'Asia/Hong_Kong',
+ 'Asia/Hovd',
+ 'Asia/Irkutsk',
+ 'Asia/Istanbul',
+ 'Asia/Jakarta',
+ 'Asia/Jayapura',
+ 'Asia/Jerusalem',
+ 'Asia/Kabul',
+ 'Asia/Kamchatka',
+ 'Asia/Karachi',
+ 'Asia/Kashgar',
+ 'Asia/Kathmandu',
+ 'Asia/Katmandu',
+ 'Asia/Khandyga',
+ 'Asia/Kolkata',
+ 'Asia/Krasnoyarsk',
+ 'Asia/Kuala_Lumpur',
+ 'Asia/Kuching',
+ 'Asia/Kuwait',
+ 'Asia/Macao',
+ 'Asia/Macau',
+ 'Asia/Magadan',
+ 'Asia/Makassar',
+ 'Asia/Manila',
+ 'Asia/Muscat',
+ 'Asia/Nicosia',
+ 'Asia/Novokuznetsk',
+ 'Asia/Novosibirsk',
+ 'Asia/Omsk',
+ 'Asia/Oral',
+ 'Asia/Phnom_Penh',
+ 'Asia/Pontianak',
+ 'Asia/Pyongyang',
+ 'Asia/Qatar',
+ 'Asia/Qyzylorda',
+ 'Asia/Rangoon',
+ 'Asia/Riyadh',
+ 'Asia/Saigon',
+ 'Asia/Sakhalin',
+ 'Asia/Samarkand',
+ 'Asia/Seoul',
+ 'Asia/Shanghai',
+ 'Asia/Singapore',
+ 'Asia/Taipei',
+ 'Asia/Tashkent',
+ 'Asia/Tbilisi',
+ 'Asia/Tehran',
+ 'Asia/Tel_Aviv',
+ 'Asia/Thimbu',
+ 'Asia/Thimphu',
+ 'Asia/Tokyo',
+ 'Asia/Ujung_Pandang',
+ 'Asia/Ulaanbaatar',
+ 'Asia/Ulan_Bator',
+ 'Asia/Urumqi',
+ 'Asia/Ust-Nera',
+ 'Asia/Vientiane',
+ 'Asia/Vladivostok',
+ 'Asia/Yakutsk',
+ 'Asia/Yekaterinburg',
+ 'Asia/Yerevan',
+ 'Atlantic/Azores',
+ 'Atlantic/Bermuda',
+ 'Atlantic/Canary',
+ 'Atlantic/Cape_Verde',
+ 'Atlantic/Faeroe',
+ 'Atlantic/Faroe',
+ 'Atlantic/Jan_Mayen',
+ 'Atlantic/Madeira',
+ 'Atlantic/Reykjavik',
+ 'Atlantic/South_Georgia',
+ 'Atlantic/St_Helena',
+ 'Atlantic/Stanley',
+ 'Australia/ACT',
+ 'Australia/Adelaide',
+ 'Australia/Brisbane',
+ 'Australia/Broken_Hill',
+ 'Australia/Canberra',
+ 'Australia/Currie',
+ 'Australia/Darwin',
+ 'Australia/Eucla',
+ 'Australia/Hobart',
+ 'Australia/LHI',
+ 'Australia/Lindeman',
+ 'Australia/Lord_Howe',
+ 'Australia/Melbourne',
+ 'Australia/NSW',
+ 'Australia/North',
+ 'Australia/Perth',
+ 'Australia/Queensland',
+ 'Australia/South',
+ 'Australia/Sydney',
+ 'Australia/Tasmania',
+ 'Australia/Victoria',
+ 'Australia/West',
+ 'Australia/Yancowinna',
+ 'Brazil/Acre',
+ 'Brazil/DeNoronha',
+ 'Brazil/East',
+ 'Brazil/West',
+ 'CET',
+ 'CST6CDT',
+ 'Canada/Atlantic',
+ 'Canada/Central',
+ 'Canada/East-Saskatchewan',
+ 'Canada/Eastern',
+ 'Canada/Mountain',
+ 'Canada/Newfoundland',
+ 'Canada/Pacific',
+ 'Canada/Saskatchewan',
+ 'Canada/Yukon',
+ 'Chile/Continental',
+ 'Chile/EasterIsland',
+ 'Cuba',
+ 'EET',
+ 'EST',
+ 'EST5EDT',
+ 'Egypt',
+ 'Eire',
+ 'Etc/GMT',
+ 'Etc/GMT+0',
+ 'Etc/GMT+1',
+ 'Etc/GMT+10',
+ 'Etc/GMT+11',
+ 'Etc/GMT+12',
+ 'Etc/GMT+2',
+ 'Etc/GMT+3',
+ 'Etc/GMT+4',
+ 'Etc/GMT+5',
+ 'Etc/GMT+6',
+ 'Etc/GMT+7',
+ 'Etc/GMT+8',
+ 'Etc/GMT+9',
+ 'Etc/GMT-0',
+ 'Etc/GMT-1',
+ 'Etc/GMT-10',
+ 'Etc/GMT-11',
+ 'Etc/GMT-12',
+ 'Etc/GMT-13',
+ 'Etc/GMT-14',
+ 'Etc/GMT-2',
+ 'Etc/GMT-3',
+ 'Etc/GMT-4',
+ 'Etc/GMT-5',
+ 'Etc/GMT-6',
+ 'Etc/GMT-7',
+ 'Etc/GMT-8',
+ 'Etc/GMT-9',
+ 'Etc/GMT0',
+ 'Etc/Greenwich',
+ 'Etc/UCT',
+ 'Etc/UTC',
+ 'Etc/Universal',
+ 'Etc/Zulu',
+ 'Europe/Amsterdam',
+ 'Europe/Andorra',
+ 'Europe/Athens',
+ 'Europe/Belfast',
+ 'Europe/Belgrade',
+ 'Europe/Berlin',
+ 'Europe/Bratislava',
+ 'Europe/Brussels',
+ 'Europe/Bucharest',
+ 'Europe/Budapest',
+ 'Europe/Busingen',
+ 'Europe/Chisinau',
+ 'Europe/Copenhagen',
+ 'Europe/Dublin',
+ 'Europe/Gibraltar',
+ 'Europe/Guernsey',
+ 'Europe/Helsinki',
+ 'Europe/Isle_of_Man',
+ 'Europe/Istanbul',
+ 'Europe/Jersey',
+ 'Europe/Kaliningrad',
+ 'Europe/Kiev',
+ 'Europe/Lisbon',
+ 'Europe/Ljubljana',
+ 'Europe/London',
+ 'Europe/Luxembourg',
+ 'Europe/Madrid',
+ 'Europe/Malta',
+ 'Europe/Mariehamn',
+ 'Europe/Minsk',
+ 'Europe/Monaco',
+ 'Europe/Moscow',
+ 'Europe/Nicosia',
+ 'Europe/Oslo',
+ 'Europe/Paris',
+ 'Europe/Podgorica',
+ 'Europe/Prague',
+ 'Europe/Riga',
+ 'Europe/Rome',
+ 'Europe/Samara',
+ 'Europe/San_Marino',
+ 'Europe/Sarajevo',
+ 'Europe/Simferopol',
+ 'Europe/Skopje',
+ 'Europe/Sofia',
+ 'Europe/Stockholm',
+ 'Europe/Tallinn',
+ 'Europe/Tirane',
+ 'Europe/Tiraspol',
+ 'Europe/Uzhgorod',
+ 'Europe/Vaduz',
+ 'Europe/Vatican',
+ 'Europe/Vienna',
+ 'Europe/Vilnius',
+ 'Europe/Volgograd',
+ 'Europe/Warsaw',
+ 'Europe/Zagreb',
+ 'Europe/Zaporozhye',
+ 'Europe/Zurich',
+ 'GB',
+ 'GB-Eire',
+ 'GMT',
+ 'GMT+0',
+ 'GMT-0',
+ 'GMT0',
+ 'Greenwich',
+ 'HST',
+ 'Hongkong',
+ 'Iceland',
+ 'Indian/Antananarivo',
+ 'Indian/Chagos',
+ 'Indian/Christmas',
+ 'Indian/Cocos',
+ 'Indian/Comoro',
+ 'Indian/Kerguelen',
+ 'Indian/Mahe',
+ 'Indian/Maldives',
+ 'Indian/Mauritius',
+ 'Indian/Mayotte',
+ 'Indian/Reunion',
+ 'Iran',
+ 'Israel',
+ 'Jamaica',
+ 'Japan',
+ 'Kwajalein',
+ 'Libya',
+ 'MET',
+ 'MST',
+ 'MST7MDT',
+ 'Mexico/BajaNorte',
+ 'Mexico/BajaSur',
+ 'Mexico/General',
+ 'NZ',
+ 'NZ-CHAT',
+ 'Navajo',
+ 'PRC',
+ 'PST8PDT',
+ 'Pacific/Apia',
+ 'Pacific/Auckland',
+ 'Pacific/Chatham',
+ 'Pacific/Chuuk',
+ 'Pacific/Easter',
+ 'Pacific/Efate',
+ 'Pacific/Enderbury',
+ 'Pacific/Fakaofo',
+ 'Pacific/Fiji',
+ 'Pacific/Funafuti',
+ 'Pacific/Galapagos',
+ 'Pacific/Gambier',
+ 'Pacific/Guadalcanal',
+ 'Pacific/Guam',
+ 'Pacific/Honolulu',
+ 'Pacific/Johnston',
+ 'Pacific/Kiritimati',
+ 'Pacific/Kosrae',
+ 'Pacific/Kwajalein',
+ 'Pacific/Majuro',
+ 'Pacific/Marquesas',
+ 'Pacific/Midway',
+ 'Pacific/Nauru',
+ 'Pacific/Niue',
+ 'Pacific/Norfolk',
+ 'Pacific/Noumea',
+ 'Pacific/Pago_Pago',
+ 'Pacific/Palau',
+ 'Pacific/Pitcairn',
+ 'Pacific/Pohnpei',
+ 'Pacific/Ponape',
+ 'Pacific/Port_Moresby',
+ 'Pacific/Rarotonga',
+ 'Pacific/Saipan',
+ 'Pacific/Samoa',
+ 'Pacific/Tahiti',
+ 'Pacific/Tarawa',
+ 'Pacific/Tongatapu',
+ 'Pacific/Truk',
+ 'Pacific/Wake',
+ 'Pacific/Wallis',
+ 'Pacific/Yap',
+ 'Poland',
+ 'Portugal',
+ 'ROC',
+ 'ROK',
+ 'Singapore',
+ 'Turkey',
+ 'UCT',
+ 'US/Alaska',
+ 'US/Aleutian',
+ 'US/Arizona',
+ 'US/Central',
+ 'US/East-Indiana',
+ 'US/Eastern',
+ 'US/Hawaii',
+ 'US/Indiana-Starke',
+ 'US/Michigan',
+ 'US/Mountain',
+ 'US/Pacific',
+ 'US/Pacific-New',
+ 'US/Samoa',
+ 'UTC',
+ 'Universal',
+ 'W-SU',
+ 'WET',
+ 'Zulu']
+all_timezones = LazyList(
+        tz for tz in all_timezones if resource_exists(tz))
+        
+all_timezones_set = LazySet(all_timezones)
+common_timezones = \
+['Africa/Abidjan',
+ 'Africa/Accra',
+ 'Africa/Addis_Ababa',
+ 'Africa/Algiers',
+ 'Africa/Asmara',
+ 'Africa/Bamako',
+ 'Africa/Bangui',
+ 'Africa/Banjul',
+ 'Africa/Bissau',
+ 'Africa/Blantyre',
+ 'Africa/Brazzaville',
+ 'Africa/Bujumbura',
+ 'Africa/Cairo',
+ 'Africa/Casablanca',
+ 'Africa/Ceuta',
+ 'Africa/Conakry',
+ 'Africa/Dakar',
+ 'Africa/Dar_es_Salaam',
+ 'Africa/Djibouti',
+ 'Africa/Douala',
+ 'Africa/El_Aaiun',
+ 'Africa/Freetown',
+ 'Africa/Gaborone',
+ 'Africa/Harare',
+ 'Africa/Johannesburg',
+ 'Africa/Juba',
+ 'Africa/Kampala',
+ 'Africa/Khartoum',
+ 'Africa/Kigali',
+ 'Africa/Kinshasa',
+ 'Africa/Lagos',
+ 'Africa/Libreville',
+ 'Africa/Lome',
+ 'Africa/Luanda',
+ 'Africa/Lubumbashi',
+ 'Africa/Lusaka',
+ 'Africa/Malabo',
+ 'Africa/Maputo',
+ 'Africa/Maseru',
+ 'Africa/Mbabane',
+ 'Africa/Mogadishu',
+ 'Africa/Monrovia',
+ 'Africa/Nairobi',
+ 'Africa/Ndjamena',
+ 'Africa/Niamey',
+ 'Africa/Nouakchott',
+ 'Africa/Ouagadougou',
+ 'Africa/Porto-Novo',
+ 'Africa/Sao_Tome',
+ 'Africa/Tripoli',
+ 'Africa/Tunis',
+ 'Africa/Windhoek',
+ 'America/Adak',
+ 'America/Anchorage',
+ 'America/Anguilla',
+ 'America/Antigua',
+ 'America/Araguaina',
+ 'America/Argentina/Buenos_Aires',
+ 'America/Argentina/Catamarca',
+ 'America/Argentina/Cordoba',
+ 'America/Argentina/Jujuy',
+ 'America/Argentina/La_Rioja',
+ 'America/Argentina/Mendoza',
+ 'America/Argentina/Rio_Gallegos',
+ 'America/Argentina/Salta',
+ 'America/Argentina/San_Juan',
+ 'America/Argentina/San_Luis',
+ 'America/Argentina/Tucuman',
+ 'America/Argentina/Ushuaia',
+ 'America/Aruba',
+ 'America/Asuncion',
+ 'America/Atikokan',
+ 'America/Bahia',
+ 'America/Bahia_Banderas',
+ 'America/Barbados',
+ 'America/Belem',
+ 'America/Belize',
+ 'America/Blanc-Sablon',
+ 'America/Boa_Vista',
+ 'America/Bogota',
+ 'America/Boise',
+ 'America/Cambridge_Bay',
+ 'America/Campo_Grande',
+ 'America/Cancun',
+ 'America/Caracas',
+ 'America/Cayenne',
+ 'America/Cayman',
+ 'America/Chicago',
+ 'America/Chihuahua',
+ 'America/Costa_Rica',
+ 'America/Creston',
+ 'America/Cuiaba',
+ 'America/Curacao',
+ 'America/Danmarkshavn',
+ 'America/Dawson',
+ 'America/Dawson_Creek',
+ 'America/Denver',
+ 'America/Detroit',
+ 'America/Dominica',
+ 'America/Edmonton',
+ 'America/Eirunepe',
+ 'America/El_Salvador',
+ 'America/Fortaleza',
+ 'America/Glace_Bay',
+ 'America/Godthab',
+ 'America/Goose_Bay',
+ 'America/Grand_Turk',
+ 'America/Grenada',
+ 'America/Guadeloupe',
+ 'America/Guatemala',
+ 'America/Guayaquil',
+ 'America/Guyana',
+ 'America/Halifax',
+ 'America/Havana',
+ 'America/Hermosillo',
+ 'America/Indiana/Indianapolis',
+ 'America/Indiana/Knox',
+ 'America/Indiana/Marengo',
+ 'America/Indiana/Petersburg',
+ 'America/Indiana/Tell_City',
+ 'America/Indiana/Vevay',
+ 'America/Indiana/Vincennes',
+ 'America/Indiana/Winamac',
+ 'America/Inuvik',
+ 'America/Iqaluit',
+ 'America/Jamaica',
+ 'America/Juneau',
+ 'America/Kentucky/Louisville',
+ 'America/Kentucky/Monticello',
+ 'America/Kralendijk',
+ 'America/La_Paz',
+ 'America/Lima',
+ 'America/Los_Angeles',
+ 'America/Lower_Princes',
+ 'America/Maceio',
+ 'America/Managua',
+ 'America/Manaus',
+ 'America/Marigot',
+ 'America/Martinique',
+ 'America/Matamoros',
+ 'America/Mazatlan',
+ 'America/Menominee',
+ 'America/Merida',
+ 'America/Metlakatla',
+ 'America/Mexico_City',
+ 'America/Miquelon',
+ 'America/Moncton',
+ 'America/Monterrey',
+ 'America/Montevideo',
+ 'America/Montreal',
+ 'America/Montserrat',
+ 'America/Nassau',
+ 'America/New_York',
+ 'America/Nipigon',
+ 'America/Nome',
+ 'America/Noronha',
+ 'America/North_Dakota/Beulah',
+ 'America/North_Dakota/Center',
+ 'America/North_Dakota/New_Salem',
+ 'America/Ojinaga',
+ 'America/Panama',
+ 'America/Pangnirtung',
+ 'America/Paramaribo',
+ 'America/Phoenix',
+ 'America/Port-au-Prince',
+ 'America/Port_of_Spain',
+ 'America/Porto_Velho',
+ 'America/Puerto_Rico',
+ 'America/Rainy_River',
+ 'America/Rankin_Inlet',
+ 'America/Recife',
+ 'America/Regina',
+ 'America/Resolute',
+ 'America/Rio_Branco',
+ 'America/Santa_Isabel',
+ 'America/Santarem',
+ 'America/Santiago',
+ 'America/Santo_Domingo',
+ 'America/Sao_Paulo',
+ 'America/Scoresbysund',
+ 'America/Sitka',
+ 'America/St_Barthelemy',
+ 'America/St_Johns',
+ 'America/St_Kitts',
+ 'America/St_Lucia',
+ 'America/St_Thomas',
+ 'America/St_Vincent',
+ 'America/Swift_Current',
+ 'America/Tegucigalpa',
+ 'America/Thule',
+ 'America/Thunder_Bay',
+ 'America/Tijuana',
+ 'America/Toronto',
+ 'America/Tortola',
+ 'America/Vancouver',
+ 'America/Whitehorse',
+ 'America/Winnipeg',
+ 'America/Yakutat',
+ 'America/Yellowknife',
+ 'Antarctica/Casey',
+ 'Antarctica/Davis',
+ 'Antarctica/DumontDUrville',
+ 'Antarctica/Macquarie',
+ 'Antarctica/Mawson',
+ 'Antarctica/McMurdo',
+ 'Antarctica/Palmer',
+ 'Antarctica/Rothera',
+ 'Antarctica/Syowa',
+ 'Antarctica/Vostok',
+ 'Arctic/Longyearbyen',
+ 'Asia/Aden',
+ 'Asia/Almaty',
+ 'Asia/Amman',
+ 'Asia/Anadyr',
+ 'Asia/Aqtau',
+ 'Asia/Aqtobe',
+ 'Asia/Ashgabat',
+ 'Asia/Baghdad',
+ 'Asia/Bahrain',
+ 'Asia/Baku',
+ 'Asia/Bangkok',
+ 'Asia/Beirut',
+ 'Asia/Bishkek',
+ 'Asia/Brunei',
+ 'Asia/Choibalsan',
+ 'Asia/Chongqing',
+ 'Asia/Colombo',
+ 'Asia/Damascus',
+ 'Asia/Dhaka',
+ 'Asia/Dili',
+ 'Asia/Dubai',
+ 'Asia/Dushanbe',
+ 'Asia/Gaza',
+ 'Asia/Harbin',
+ 'Asia/Hebron',
+ 'Asia/Ho_Chi_Minh',
+ 'Asia/Hong_Kong',
+ 'Asia/Hovd',
+ 'Asia/Irkutsk',
+ 'Asia/Jakarta',
+ 'Asia/Jayapura',
+ 'Asia/Jerusalem',
+ 'Asia/Kabul',
+ 'Asia/Kamchatka',
+ 'Asia/Karachi',
+ 'Asia/Kashgar',
+ 'Asia/Kathmandu',
+ 'Asia/Khandyga',
+ 'Asia/Kolkata',
+ 'Asia/Krasnoyarsk',
+ 'Asia/Kuala_Lumpur',
+ 'Asia/Kuching',
+ 'Asia/Kuwait',
+ 'Asia/Macau',
+ 'Asia/Magadan',
+ 'Asia/Makassar',
+ 'Asia/Manila',
+ 'Asia/Muscat',
+ 'Asia/Nicosia',
+ 'Asia/Novokuznetsk',
+ 'Asia/Novosibirsk',
+ 'Asia/Omsk',
+ 'Asia/Oral',
+ 'Asia/Phnom_Penh',
+ 'Asia/Pontianak',
+ 'Asia/Pyongyang',
+ 'Asia/Qatar',
+ 'Asia/Qyzylorda',
+ 'Asia/Rangoon',
+ 'Asia/Riyadh',
+ 'Asia/Sakhalin',
+ 'Asia/Samarkand',
+ 'Asia/Seoul',
+ 'Asia/Shanghai',
+ 'Asia/Singapore',
+ 'Asia/Taipei',
+ 'Asia/Tashkent',
+ 'Asia/Tbilisi',
+ 'Asia/Tehran',
+ 'Asia/Thimphu',
+ 'Asia/Tokyo',
+ 'Asia/Ulaanbaatar',
+ 'Asia/Urumqi',
+ 'Asia/Ust-Nera',
+ 'Asia/Vientiane',
+ 'Asia/Vladivostok',
+ 'Asia/Yakutsk',
+ 'Asia/Yekaterinburg',
+ 'Asia/Yerevan',
+ 'Atlantic/Azores',
+ 'Atlantic/Bermuda',
+ 'Atlantic/Canary',
+ 'Atlantic/Cape_Verde',
+ 'Atlantic/Faroe',
+ 'Atlantic/Madeira',
+ 'Atlantic/Reykjavik',
+ 'Atlantic/South_Georgia',
+ 'Atlantic/St_Helena',
+ 'Atlantic/Stanley',
+ 'Australia/Adelaide',
+ 'Australia/Brisbane',
+ 'Australia/Broken_Hill',
+ 'Australia/Currie',
+ 'Australia/Darwin',
+ 'Australia/Eucla',
+ 'Australia/Hobart',
+ 'Australia/Lindeman',
+ 'Australia/Lord_Howe',
+ 'Australia/Melbourne',
+ 'Australia/Perth',
+ 'Australia/Sydney',
+ 'Canada/Atlantic',
+ 'Canada/Central',
+ 'Canada/Eastern',
+ 'Canada/Mountain',
+ 'Canada/Newfoundland',
+ 'Canada/Pacific',
+ 'Europe/Amsterdam',
+ 'Europe/Andorra',
+ 'Europe/Athens',
+ 'Europe/Belgrade',
+ 'Europe/Berlin',
+ 'Europe/Bratislava',
+ 'Europe/Brussels',
+ 'Europe/Bucharest',
+ 'Europe/Budapest',
+ 'Europe/Busingen',
+ 'Europe/Chisinau',
+ 'Europe/Copenhagen',
+ 'Europe/Dublin',
+ 'Europe/Gibraltar',
+ 'Europe/Guernsey',
+ 'Europe/Helsinki',
+ 'Europe/Isle_of_Man',
+ 'Europe/Istanbul',
+ 'Europe/Jersey',
+ 'Europe/Kaliningrad',
+ 'Europe/Kiev',
+ 'Europe/Lisbon',
+ 'Europe/Ljubljana',
+ 'Europe/London',
+ 'Europe/Luxembourg',
+ 'Europe/Madrid',
+ 'Europe/Malta',
+ 'Europe/Mariehamn',
+ 'Europe/Minsk',
+ 'Europe/Monaco',
+ 'Europe/Moscow',
+ 'Europe/Oslo',
+ 'Europe/Paris',
+ 'Europe/Podgorica',
+ 'Europe/Prague',
+ 'Europe/Riga',
+ 'Europe/Rome',
+ 'Europe/Samara',
+ 'Europe/San_Marino',
+ 'Europe/Sarajevo',
+ 'Europe/Simferopol',
+ 'Europe/Skopje',
+ 'Europe/Sofia',
+ 'Europe/Stockholm',
+ 'Europe/Tallinn',
+ 'Europe/Tirane',
+ 'Europe/Uzhgorod',
+ 'Europe/Vaduz',
+ 'Europe/Vatican',
+ 'Europe/Vienna',
+ 'Europe/Vilnius',
+ 'Europe/Volgograd',
+ 'Europe/Warsaw',
+ 'Europe/Zagreb',
+ 'Europe/Zaporozhye',
+ 'Europe/Zurich',
+ 'GMT',
+ 'Indian/Antananarivo',
+ 'Indian/Chagos',
+ 'Indian/Christmas',
+ 'Indian/Cocos',
+ 'Indian/Comoro',
+ 'Indian/Kerguelen',
+ 'Indian/Mahe',
+ 'Indian/Maldives',
+ 'Indian/Mauritius',
+ 'Indian/Mayotte',
+ 'Indian/Reunion',
+ 'Pacific/Apia',
+ 'Pacific/Auckland',
+ 'Pacific/Chatham',
+ 'Pacific/Chuuk',
+ 'Pacific/Easter',
+ 'Pacific/Efate',
+ 'Pacific/Enderbury',
+ 'Pacific/Fakaofo',
+ 'Pacific/Fiji',
+ 'Pacific/Funafuti',
+ 'Pacific/Galapagos',
+ 'Pacific/Gambier',
+ 'Pacific/Guadalcanal',
+ 'Pacific/Guam',
+ 'Pacific/Honolulu',
+ 'Pacific/Johnston',
+ 'Pacific/Kiritimati',
+ 'Pacific/Kosrae',
+ 'Pacific/Kwajalein',
+ 'Pacific/Majuro',
+ 'Pacific/Marquesas',
+ 'Pacific/Midway',
+ 'Pacific/Nauru',
+ 'Pacific/Niue',
+ 'Pacific/Norfolk',
+ 'Pacific/Noumea',
+ 'Pacific/Pago_Pago',
+ 'Pacific/Palau',
+ 'Pacific/Pitcairn',
+ 'Pacific/Pohnpei',
+ 'Pacific/Port_Moresby',
+ 'Pacific/Rarotonga',
+ 'Pacific/Saipan',
+ 'Pacific/Tahiti',
+ 'Pacific/Tarawa',
+ 'Pacific/Tongatapu',
+ 'Pacific/Wake',
+ 'Pacific/Wallis',
+ 'US/Alaska',
+ 'US/Arizona',
+ 'US/Central',
+ 'US/Eastern',
+ 'US/Hawaii',
+ 'US/Mountain',
+ 'US/Pacific',
+ 'UTC']
+common_timezones = LazyList(
+            tz for tz in common_timezones if tz in all_timezones)
+        
+common_timezones_set = LazySet(common_timezones)

+ 48 - 0
desktop/core/ext-py/pytz-2013.9/pytz/exceptions.py

@@ -0,0 +1,48 @@
+'''
+Custom exceptions raised by pytz.
+'''
+
+__all__ = [
+    'UnknownTimeZoneError', 'InvalidTimeError', 'AmbiguousTimeError',
+    'NonExistentTimeError',
+    ]
+
+
+class UnknownTimeZoneError(KeyError):
+    '''Exception raised when pytz is passed an unknown timezone.
+
+    >>> isinstance(UnknownTimeZoneError(), LookupError)
+    True
+
+    This class is actually a subclass of KeyError to provide backwards
+    compatibility with code relying on the undocumented behavior of earlier
+    pytz releases.
+
+    >>> isinstance(UnknownTimeZoneError(), KeyError)
+    True
+    '''
+    pass
+
+
+class InvalidTimeError(Exception):
+    '''Base class for invalid time exceptions.'''
+
+
+class AmbiguousTimeError(InvalidTimeError):
+    '''Exception raised when attempting to create an ambiguous wallclock time.
+
+    At the end of a DST transition period, a particular wallclock time will
+    occur twice (once before the clocks are set back, once after). Both
+    possibilities may be correct, unless further information is supplied.
+
+    See DstTzInfo.normalize() for more info
+    '''
+
+
+class NonExistentTimeError(InvalidTimeError):
+    '''Exception raised when attempting to create a wallclock time that
+    cannot exist.
+
+    At the start of a DST transition period, the wallclock time jumps forward.
+    The instants jumped over never occur.
+    '''

+ 168 - 0
desktop/core/ext-py/pytz-2013.9/pytz/lazy.py

@@ -0,0 +1,168 @@
+from threading import RLock
+try:
+    from UserDict import DictMixin
+except ImportError:
+    from collections import Mapping as DictMixin
+
+
+# With lazy loading, we might end up with multiple threads triggering
+# it at the same time. We need a lock.
+_fill_lock = RLock()
+
+
+class LazyDict(DictMixin):
+    """Dictionary populated on first use."""
+    data = None
+    def __getitem__(self, key):
+        if self.data is None:
+            _fill_lock.acquire()
+            try:
+                if self.data is None:
+                    self._fill()
+            finally:
+                _fill_lock.release()
+        return self.data[key.upper()]
+
+    def __contains__(self, key):
+        if self.data is None:
+            _fill_lock.acquire()
+            try:
+                if self.data is None:
+                    self._fill()
+            finally:
+                _fill_lock.release()
+        return key in self.data
+
+    def __iter__(self):
+        if self.data is None:
+            _fill_lock.acquire()
+            try:
+                if self.data is None:
+                    self._fill()
+            finally:
+                _fill_lock.release()
+        return iter(self.data)
+
+    def __len__(self):
+        if self.data is None:
+            _fill_lock.acquire()
+            try:
+                if self.data is None:
+                    self._fill()
+            finally:
+                _fill_lock.release()
+        return len(self.data)
+
+    def keys(self):
+        if self.data is None:
+            _fill_lock.acquire()
+            try:
+                if self.data is None:
+                    self._fill()
+            finally:
+                _fill_lock.release()
+        return self.data.keys()
+
+
+class LazyList(list):
+    """List populated on first use."""
+
+    _props = [
+        '__str__', '__repr__', '__unicode__',
+        '__hash__', '__sizeof__', '__cmp__',
+        '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
+        'append', 'count', 'index', 'extend', 'insert', 'pop', 'remove',
+        'reverse', 'sort', '__add__', '__radd__', '__iadd__', '__mul__',
+        '__rmul__', '__imul__', '__contains__', '__len__', '__nonzero__',
+        '__getitem__', '__setitem__', '__delitem__', '__iter__',
+        '__reversed__', '__getslice__', '__setslice__', '__delslice__']
+
+    def __new__(cls, fill_iter=None):
+
+        if fill_iter is None:
+            return list()
+
+        # We need a new class as we will be dynamically messing with its
+        # methods.
+        class LazyList(list):
+            pass
+
+        fill_iter = [fill_iter]
+
+        def lazy(name):
+            def _lazy(self, *args, **kw):
+                _fill_lock.acquire()
+                try:
+                    if len(fill_iter) > 0:
+                        list.extend(self, fill_iter.pop())
+                        for method_name in cls._props:
+                            delattr(LazyList, method_name)
+                finally:
+                    _fill_lock.release()
+                return getattr(list, name)(self, *args, **kw)
+            return _lazy
+
+        for name in cls._props:
+            setattr(LazyList, name, lazy(name))
+
+        new_list = LazyList()
+        return new_list
+
+# Not all versions of Python declare the same magic methods.
+# Filter out properties that don't exist in this version of Python
+# from the list.
+LazyList._props = [prop for prop in LazyList._props if hasattr(list, prop)]
+
+
+class LazySet(set):
+    """Set populated on first use."""
+
+    _props = (
+        '__str__', '__repr__', '__unicode__',
+        '__hash__', '__sizeof__', '__cmp__',
+        '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
+        '__contains__', '__len__', '__nonzero__',
+        '__getitem__', '__setitem__', '__delitem__', '__iter__',
+        '__sub__', '__and__', '__xor__', '__or__',
+        '__rsub__', '__rand__', '__rxor__', '__ror__',
+        '__isub__', '__iand__', '__ixor__', '__ior__',
+        'add', 'clear', 'copy', 'difference', 'difference_update',
+        'discard', 'intersection', 'intersection_update', 'isdisjoint',
+        'issubset', 'issuperset', 'pop', 'remove',
+        'symmetric_difference', 'symmetric_difference_update',
+        'union', 'update')
+
+    def __new__(cls, fill_iter=None):
+
+        if fill_iter is None:
+            return set()
+
+        class LazySet(set):
+            pass
+
+        fill_iter = [fill_iter]
+
+        def lazy(name):
+            def _lazy(self, *args, **kw):
+                _fill_lock.acquire()
+                try:
+                    if len(fill_iter) > 0:
+                        for i in fill_iter.pop():
+                            set.add(self, i)
+                        for method_name in cls._props:
+                            delattr(LazySet, method_name)
+                finally:
+                    _fill_lock.release()
+                return getattr(set, name)(self, *args, **kw)
+            return _lazy
+
+        for name in cls._props:
+            setattr(LazySet, name, lazy(name))
+
+        new_set = LazySet()
+        return new_set
+
+# Not all versions of Python declare the same magic methods.
+# Filter out properties that don't exist in this version of Python
+# from the list.
+LazySet._props = [prop for prop in LazySet._props if hasattr(set, prop)]

+ 127 - 0
desktop/core/ext-py/pytz-2013.9/pytz/reference.py

@@ -0,0 +1,127 @@
+'''
+Reference tzinfo implementations from the Python docs.
+Used for testing against as they are only correct for the years
+1987 to 2006. Do not use these for real code.
+'''
+
+from datetime import tzinfo, timedelta, datetime
+from pytz import utc, UTC, HOUR, ZERO
+
+# A class building tzinfo objects for fixed-offset time zones.
+# Note that FixedOffset(0, "UTC") is a different way to build a
+# UTC tzinfo object.
+
+class FixedOffset(tzinfo):
+    """Fixed offset in minutes east from UTC."""
+
+    def __init__(self, offset, name):
+        self.__offset = timedelta(minutes = offset)
+        self.__name = name
+
+    def utcoffset(self, dt):
+        return self.__offset
+
+    def tzname(self, dt):
+        return self.__name
+
+    def dst(self, dt):
+        return ZERO
+
+# A class capturing the platform's idea of local time.
+
+import time as _time
+
+STDOFFSET = timedelta(seconds = -_time.timezone)
+if _time.daylight:
+    DSTOFFSET = timedelta(seconds = -_time.altzone)
+else:
+    DSTOFFSET = STDOFFSET
+
+DSTDIFF = DSTOFFSET - STDOFFSET
+
+class LocalTimezone(tzinfo):
+
+    def utcoffset(self, dt):
+        if self._isdst(dt):
+            return DSTOFFSET
+        else:
+            return STDOFFSET
+
+    def dst(self, dt):
+        if self._isdst(dt):
+            return DSTDIFF
+        else:
+            return ZERO
+
+    def tzname(self, dt):
+        return _time.tzname[self._isdst(dt)]
+
+    def _isdst(self, dt):
+        tt = (dt.year, dt.month, dt.day,
+              dt.hour, dt.minute, dt.second,
+              dt.weekday(), 0, -1)
+        stamp = _time.mktime(tt)
+        tt = _time.localtime(stamp)
+        return tt.tm_isdst > 0
+
+Local = LocalTimezone()
+
+# A complete implementation of current DST rules for major US time zones.
+
+def first_sunday_on_or_after(dt):
+    days_to_go = 6 - dt.weekday()
+    if days_to_go:
+        dt += timedelta(days_to_go)
+    return dt
+
+# In the US, DST starts at 2am (standard time) on the first Sunday in April.
+DSTSTART = datetime(1, 4, 1, 2)
+# and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct.
+# which is the first Sunday on or after Oct 25.
+DSTEND = datetime(1, 10, 25, 1)
+
+class USTimeZone(tzinfo):
+
+    def __init__(self, hours, reprname, stdname, dstname):
+        self.stdoffset = timedelta(hours=hours)
+        self.reprname = reprname
+        self.stdname = stdname
+        self.dstname = dstname
+
+    def __repr__(self):
+        return self.reprname
+
+    def tzname(self, dt):
+        if self.dst(dt):
+            return self.dstname
+        else:
+            return self.stdname
+
+    def utcoffset(self, dt):
+        return self.stdoffset + self.dst(dt)
+
+    def dst(self, dt):
+        if dt is None or dt.tzinfo is None:
+            # An exception may be sensible here, in one or both cases.
+            # It depends on how you want to treat them.  The default
+            # fromutc() implementation (called by the default astimezone()
+            # implementation) passes a datetime with dt.tzinfo is self.
+            return ZERO
+        assert dt.tzinfo is self
+
+        # Find first Sunday in April & the last in October.
+        start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year))
+        end = first_sunday_on_or_after(DSTEND.replace(year=dt.year))
+
+        # Can't compare naive to aware objects, so strip the timezone from
+        # dt first.
+        if start <= dt.replace(tzinfo=None) < end:
+            return HOUR
+        else:
+            return ZERO
+
+Eastern  = USTimeZone(-5, "Eastern",  "EST", "EDT")
+Central  = USTimeZone(-6, "Central",  "CST", "CDT")
+Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
+Pacific  = USTimeZone(-8, "Pacific",  "PST", "PDT")
+

+ 36 - 0
desktop/core/ext-py/pytz-2013.9/pytz/tests/test_docs.py

@@ -0,0 +1,36 @@
+# -*- coding: ascii -*-
+
+from doctest import DocTestSuite
+import unittest, os, os.path, sys
+import warnings
+
+# We test the documentation this way instead of using DocFileSuite so
+# we can run the tests under Python 2.3
+def test_README():
+    pass
+
+this_dir = os.path.dirname(__file__)
+locs = [
+    os.path.join(this_dir, os.pardir, 'README.txt'),
+    os.path.join(this_dir, os.pardir, os.pardir, 'README.txt'),
+    ]
+for loc in locs:
+    if os.path.exists(loc):
+        test_README.__doc__ = open(loc).read()
+        break
+if test_README.__doc__ is None:
+    raise RuntimeError('README.txt not found')
+
+
+def test_suite():
+    "For the Z3 test runner"
+    return DocTestSuite()
+
+
+if __name__ == '__main__':
+    sys.path.insert(0, os.path.abspath(os.path.join(
+        this_dir, os.pardir, os.pardir
+        )))
+    unittest.main(defaultTest='test_suite')
+
+

+ 313 - 0
desktop/core/ext-py/pytz-2013.9/pytz/tests/test_lazy.py

@@ -0,0 +1,313 @@
+from operator import *
+import os.path
+import sys
+import unittest
+import warnings
+
+
+if __name__ == '__main__':
+    # Only munge path if invoked as a script. Testrunners should have setup
+    # the paths already
+    sys.path.insert(0, os.path.abspath(os.path.join(os.pardir, os.pardir)))
+
+
+from pytz.lazy import LazyList, LazySet
+
+
+class LazyListTestCase(unittest.TestCase):
+    initial_data = [3,2,1]
+
+    def setUp(self):
+        self.base = [3, 2, 1]
+        self.lesser = [2, 1, 0]
+        self.greater = [4, 3, 2]
+
+        self.lazy = LazyList(iter(list(self.base)))
+
+    def test_unary_ops(self):
+        unary_ops = [str, repr, len, bool, not_]
+        try:
+            unary_ops.append(unicode)
+        except NameError:
+            pass  # unicode no longer exists in Python 3.
+
+        for op in unary_ops:
+            self.assertEqual(
+                op(self.lazy),
+                op(self.base), str(op))
+
+    def test_binary_ops(self):
+        binary_ops = [eq, ge, gt, le, lt, ne, add, concat]
+        try:
+            binary_ops.append(cmp)
+        except NameError:
+            pass  # cmp no longer exists in Python 3.
+
+        for op in binary_ops:
+            self.assertEqual(
+                op(self.lazy, self.lazy),
+                op(self.base, self.base), str(op))
+            for other in [self.base, self.lesser, self.greater]:
+                self.assertEqual(
+                    op(self.lazy, other),
+                    op(self.base, other), '%s %s' % (op, other))
+                self.assertEqual(
+                    op(other, self.lazy),
+                    op(other, self.base), '%s %s' % (op, other))
+
+        # Multiplication
+        self.assertEqual(self.lazy * 3, self.base * 3)
+        self.assertEqual(3 * self.lazy, 3 * self.base)
+
+        # Contains
+        self.assertTrue(2 in self.lazy)
+        self.assertFalse(42 in self.lazy)
+
+    def test_iadd(self):
+        self.lazy += [1]
+        self.base += [1]
+        self.assertEqual(self.lazy, self.base)
+
+    def test_bool(self):
+        self.assertTrue(bool(self.lazy))
+        self.assertFalse(bool(LazyList()))
+        self.assertFalse(bool(LazyList(iter([]))))
+
+    def test_hash(self):
+        self.assertRaises(TypeError, hash, self.lazy)
+
+    def test_isinstance(self):
+        self.assertTrue(isinstance(self.lazy, list))
+        self.assertFalse(isinstance(self.lazy, tuple))
+
+    def test_callable(self):
+        try:
+            callable
+        except NameError:
+            return  # No longer exists with Python 3.
+        self.assertFalse(callable(self.lazy))
+
+    def test_append(self):
+        self.base.append('extra')
+        self.lazy.append('extra')
+        self.assertEqual(self.lazy, self.base)
+
+    def test_count(self):
+        self.assertEqual(self.lazy.count(2), 1)
+
+    def test_index(self):
+        self.assertEqual(self.lazy.index(2), 1)
+
+    def test_extend(self):
+        self.base.extend([6, 7])
+        self.lazy.extend([6, 7])
+        self.assertEqual(self.lazy, self.base)
+
+    def test_insert(self):
+        self.base.insert(0, 'ping')
+        self.lazy.insert(0, 'ping')
+        self.assertEqual(self.lazy, self.base)
+
+    def test_pop(self):
+        self.assertEqual(self.lazy.pop(), self.base.pop())
+        self.assertEqual(self.lazy, self.base)
+
+    def test_remove(self):
+        self.base.remove(2)
+        self.lazy.remove(2)
+        self.assertEqual(self.lazy, self.base)
+
+    def test_reverse(self):
+        self.base.reverse()
+        self.lazy.reverse()
+        self.assertEqual(self.lazy, self.base)
+
+    def test_reversed(self):
+        self.assertEqual(list(reversed(self.lazy)), list(reversed(self.base)))
+
+    def test_sort(self):
+        self.base.sort()
+        self.assertNotEqual(self.lazy, self.base, 'Test data already sorted')
+        self.lazy.sort()
+        self.assertEqual(self.lazy, self.base)
+
+    def test_sorted(self):
+        self.assertEqual(sorted(self.lazy), sorted(self.base))
+
+    def test_getitem(self):
+        for idx in range(-len(self.base), len(self.base)):
+            self.assertEqual(self.lazy[idx], self.base[idx])
+
+    def test_setitem(self):
+        for idx in range(-len(self.base), len(self.base)):
+            self.base[idx] = idx + 1000
+            self.assertNotEqual(self.lazy, self.base)
+            self.lazy[idx] = idx + 1000
+            self.assertEqual(self.lazy, self.base)
+
+    def test_delitem(self):
+        del self.base[0]
+        self.assertNotEqual(self.lazy, self.base)
+        del self.lazy[0]
+        self.assertEqual(self.lazy, self.base)
+
+        del self.base[-2]
+        self.assertNotEqual(self.lazy, self.base)
+        del self.lazy[-2]
+        self.assertEqual(self.lazy, self.base)
+
+    def test_iter(self):
+        self.assertEqual(list(iter(self.lazy)), list(iter(self.base)))
+
+    def test_getslice(self):
+        for i in range(-len(self.base), len(self.base)):
+            for j in range(-len(self.base), len(self.base)):
+                for step in [-1, 1]:
+                    self.assertEqual(self.lazy[i:j:step], self.base[i:j:step])
+
+    def test_setslice(self):
+        for i in range(-len(self.base), len(self.base)):
+            for j in range(-len(self.base), len(self.base)):
+                for step in [-1, 1]:
+                    replacement = range(0, len(self.base[i:j:step]))
+                    self.base[i:j:step] = replacement
+                    self.lazy[i:j:step] = replacement
+                    self.assertEqual(self.lazy, self.base)
+
+    def test_delslice(self):
+        del self.base[0:1]
+        del self.lazy[0:1]
+        self.assertEqual(self.lazy, self.base)
+
+        del self.base[-1:1:-1]
+        del self.lazy[-1:1:-1]
+        self.assertEqual(self.lazy, self.base)
+
+
+class LazySetTestCase(unittest.TestCase):
+    initial_data = set([3,2,1])
+
+    def setUp(self):
+        self.base = set([3, 2, 1])
+        self.lazy = LazySet(iter(set(self.base)))
+
+    def test_unary_ops(self):
+        # These ops just need to work.
+        unary_ops = [str, repr]
+        try:
+            unary_ops.append(unicode)
+        except NameError:
+            pass  # unicode no longer exists in Python 3.
+
+        for op in unary_ops:
+            op(self.lazy)  # These ops just need to work.
+
+        # These ops should return identical values as a real set.
+        unary_ops = [len, bool, not_]
+
+        for op in unary_ops:
+            self.assertEqual(
+                op(self.lazy),
+                op(self.base), '%s(lazy) == %r' % (op, op(self.lazy)))
+
+    def test_binary_ops(self):
+        binary_ops = [eq, ge, gt, le, lt, ne, sub, and_, or_, xor]
+        try:
+            binary_ops.append(cmp)
+        except NameError:
+            pass  # cmp no longer exists in Python 3.
+
+        for op in binary_ops:
+            self.assertEqual(
+                op(self.lazy, self.lazy),
+                op(self.base, self.base), str(op))
+            self.assertEqual(
+                op(self.lazy, self.base),
+                op(self.base, self.base), str(op))
+            self.assertEqual(
+                op(self.base, self.lazy),
+                op(self.base, self.base), str(op))
+
+        # Contains
+        self.assertTrue(2 in self.lazy)
+        self.assertFalse(42 in self.lazy)
+
+    def test_iops(self):
+        try:
+            iops = [isub, iand, ior, ixor]
+        except NameError:
+            return  # Don't exist in older Python versions.
+        for op in iops:
+            # Mutating operators, so make fresh copies.
+            lazy = LazySet(self.base)
+            base = self.base.copy()
+            op(lazy, set([1]))
+            op(base, set([1]))
+            self.assertEqual(lazy, base, str(op))
+
+    def test_bool(self):
+        self.assertTrue(bool(self.lazy))
+        self.assertFalse(bool(LazySet()))
+        self.assertFalse(bool(LazySet(iter([]))))
+
+    def test_hash(self):
+        self.assertRaises(TypeError, hash, self.lazy)
+
+    def test_isinstance(self):
+        self.assertTrue(isinstance(self.lazy, set))
+
+    def test_callable(self):
+        try:
+            callable
+        except NameError:
+            return  # No longer exists with Python 3.
+        self.assertFalse(callable(self.lazy))
+
+    def test_add(self):
+        self.base.add('extra')
+        self.lazy.add('extra')
+        self.assertEqual(self.lazy, self.base)
+
+    def test_copy(self):
+        self.assertEqual(self.lazy.copy(), self.base)
+
+    def test_method_ops(self):
+        ops = [
+            'difference', 'intersection', 'isdisjoint',
+            'issubset', 'issuperset', 'symmetric_difference', 'union',
+            'difference_update', 'intersection_update',
+            'symmetric_difference_update', 'update']
+        for op in ops:
+            if not hasattr(set, op):
+                continue  # Not in this version of Python.
+            # Make a copy, as some of the ops are mutating.
+            lazy = LazySet(set(self.base))
+            base = set(self.base)
+            self.assertEqual(
+                getattr(self.lazy, op)(set([1])),
+                getattr(self.base, op)(set([1])), op)
+            self.assertEqual(self.lazy, self.base, op)
+
+    def test_discard(self):
+        self.base.discard(1)
+        self.assertNotEqual(self.lazy, self.base)
+        self.lazy.discard(1)
+        self.assertEqual(self.lazy, self.base)
+
+    def test_pop(self):
+        self.assertEqual(self.lazy.pop(), self.base.pop())
+        self.assertEqual(self.lazy, self.base)
+
+    def test_remove(self):
+        self.base.remove(2)
+        self.lazy.remove(2)
+        self.assertEqual(self.lazy, self.base)
+
+    def test_clear(self):
+        self.lazy.clear()
+        self.assertEqual(self.lazy, set())
+
+
+if __name__ == '__main__':
+    warnings.simplefilter("error") # Warnings should be fatal in tests.
+    unittest.main()

+ 818 - 0
desktop/core/ext-py/pytz-2013.9/pytz/tests/test_tzinfo.py

@@ -0,0 +1,818 @@
+# -*- coding: ascii -*-
+
+import sys, os, os.path
+import unittest, doctest
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+from datetime import datetime, time, timedelta, tzinfo
+import warnings
+
+if __name__ == '__main__':
+    # Only munge path if invoked as a script. Testrunners should have setup
+    # the paths already
+    sys.path.insert(0, os.path.abspath(os.path.join(os.pardir, os.pardir)))
+
+import pytz
+from pytz import reference
+from pytz.tzfile import _byte_string
+from pytz.tzinfo import DstTzInfo, StaticTzInfo
+
+# I test for expected version to ensure the correct version of pytz is
+# actually being tested.
+EXPECTED_VERSION='2013.9'
+EXPECTED_OLSON_VERSION='2013i'
+
+fmt = '%Y-%m-%d %H:%M:%S %Z%z'
+
+NOTIME = timedelta(0)
+
+# GMT is a tzinfo.StaticTzInfo--the class we primarily want to test--while
+# UTC is reference implementation.  They both have the same timezone meaning.
+UTC = pytz.timezone('UTC')
+GMT = pytz.timezone('GMT')
+assert isinstance(GMT, StaticTzInfo), 'GMT is no longer a StaticTzInfo'
+
+def prettydt(dt):
+    """datetime as a string using a known format.
+
+    We don't use strftime as it doesn't handle years earlier than 1900
+    per http://bugs.python.org/issue1777412
+    """
+    if dt.utcoffset() >= timedelta(0):
+        offset = '+%s' % (dt.utcoffset(),)
+    else:
+        offset = '-%s' % (-1 * dt.utcoffset(),)
+    return '%04d-%02d-%02d %02d:%02d:%02d %s %s' % (
+        dt.year, dt.month, dt.day,
+        dt.hour, dt.minute, dt.second,
+        dt.tzname(), offset)
+
+
+try:
+    unicode
+except NameError:
+    # Python 3.x doesn't have unicode(), making writing code
+    # for Python 2.3 and Python 3.x a pain.
+    unicode = str
+
+
+class BasicTest(unittest.TestCase):
+
+    def testVersion(self):
+        # Ensuring the correct version of pytz has been loaded
+        self.assertEqual(EXPECTED_VERSION, pytz.__version__,
+                'Incorrect pytz version loaded. Import path is stuffed '
+                'or this test needs updating. (Wanted %s, got %s)'
+                % (EXPECTED_VERSION, pytz.__version__))
+
+        self.assertEqual(EXPECTED_OLSON_VERSION, pytz.OLSON_VERSION,
+                'Incorrect pytz version loaded. Import path is stuffed '
+                'or this test needs updating. (Wanted %s, got %s)'
+                % (EXPECTED_VERSION, pytz.__version__))
+
+    def testGMT(self):
+        now = datetime.now(tz=GMT)
+        self.assertTrue(now.utcoffset() == NOTIME)
+        self.assertTrue(now.dst() == NOTIME)
+        self.assertTrue(now.timetuple() == now.utctimetuple())
+        self.assertTrue(now==now.replace(tzinfo=UTC))
+
+    def testReferenceUTC(self):
+        now = datetime.now(tz=UTC)
+        self.assertTrue(now.utcoffset() == NOTIME)
+        self.assertTrue(now.dst() == NOTIME)
+        self.assertTrue(now.timetuple() == now.utctimetuple())
+
+    def testUnknownOffsets(self):
+        # This tzinfo behavior is required to make
+        # datetime.time.{utcoffset, dst, tzname} work as documented.
+
+        dst_tz = pytz.timezone('US/Eastern')
+
+        # This information is not known when we don't have a date,
+        # so return None per API.
+        self.assertTrue(dst_tz.utcoffset(None) is None)
+        self.assertTrue(dst_tz.dst(None) is None)
+        # We don't know the abbreviation, but this is still a valid
+        # tzname per the Python documentation.
+        self.assertEqual(dst_tz.tzname(None), 'US/Eastern')
+
+    def clearCache(self):
+        pytz._tzinfo_cache.clear()
+
+    def testUnicodeTimezone(self):
+        # We need to ensure that cold lookups work for both Unicode
+        # and traditional strings, and that the desired singleton is
+        # returned.
+        self.clearCache()
+        eastern = pytz.timezone(unicode('US/Eastern'))
+        self.assertTrue(eastern is pytz.timezone('US/Eastern'))
+
+        self.clearCache()
+        eastern = pytz.timezone('US/Eastern')
+        self.assertTrue(eastern is pytz.timezone(unicode('US/Eastern')))
+
+
+class PicklingTest(unittest.TestCase):
+
+    def _roundtrip_tzinfo(self, tz):
+        p = pickle.dumps(tz)
+        unpickled_tz = pickle.loads(p)
+        self.assertTrue(tz is unpickled_tz, '%s did not roundtrip' % tz.zone)
+
+    def _roundtrip_datetime(self, dt):
+        # Ensure that the tzinfo attached to a datetime instance
+        # is identical to the one returned. This is important for
+        # DST timezones, as some state is stored in the tzinfo.
+        tz = dt.tzinfo
+        p = pickle.dumps(dt)
+        unpickled_dt = pickle.loads(p)
+        unpickled_tz = unpickled_dt.tzinfo
+        self.assertTrue(tz is unpickled_tz, '%s did not roundtrip' % tz.zone)
+
+    def testDst(self):
+        tz = pytz.timezone('Europe/Amsterdam')
+        dt = datetime(2004, 2, 1, 0, 0, 0)
+
+        for localized_tz in tz._tzinfos.values():
+            self._roundtrip_tzinfo(localized_tz)
+            self._roundtrip_datetime(dt.replace(tzinfo=localized_tz))
+
+    def testRoundtrip(self):
+        dt = datetime(2004, 2, 1, 0, 0, 0)
+        for zone in pytz.all_timezones:
+            tz = pytz.timezone(zone)
+            self._roundtrip_tzinfo(tz)
+
+    def testDatabaseFixes(self):
+        # Hack the pickle to make it refer to a timezone abbreviation
+        # that does not match anything. The unpickler should be able
+        # to repair this case
+        tz = pytz.timezone('Australia/Melbourne')
+        p = pickle.dumps(tz)
+        tzname = tz._tzname
+        hacked_p = p.replace(_byte_string(tzname), _byte_string('???'))
+        self.assertNotEqual(p, hacked_p)
+        unpickled_tz = pickle.loads(hacked_p)
+        self.assertTrue(tz is unpickled_tz)
+
+        # Simulate a database correction. In this case, the incorrect
+        # data will continue to be used.
+        p = pickle.dumps(tz)
+        new_utcoffset = tz._utcoffset.seconds + 42
+
+        # Python 3 introduced a new pickle protocol where numbers are stored in
+        # hexadecimal representation. Here we extract the pickle
+        # representation of the number for the current Python version.
+        old_pickle_pattern = pickle.dumps(tz._utcoffset.seconds)[3:-1]
+        new_pickle_pattern = pickle.dumps(new_utcoffset)[3:-1]
+        hacked_p = p.replace(old_pickle_pattern, new_pickle_pattern)
+
+        self.assertNotEqual(p, hacked_p)
+        unpickled_tz = pickle.loads(hacked_p)
+        self.assertEqual(unpickled_tz._utcoffset.seconds, new_utcoffset)
+        self.assertTrue(tz is not unpickled_tz)
+
+    def testOldPickles(self):
+        # Ensure that applications serializing pytz instances as pickles
+        # have no troubles upgrading to a new pytz release. These pickles
+        # where created with pytz2006j
+        east1 = pickle.loads(_byte_string(
+            "cpytz\n_p\np1\n(S'US/Eastern'\np2\nI-18000\n"
+            "I0\nS'EST'\np3\ntRp4\n."
+            ))
+        east2 = pytz.timezone('US/Eastern')
+        self.assertTrue(east1 is east2)
+
+        # Confirm changes in name munging between 2006j and 2007c cause
+        # no problems.
+        pap1 = pickle.loads(_byte_string(
+            "cpytz\n_p\np1\n(S'America/Port_minus_au_minus_Prince'"
+            "\np2\nI-17340\nI0\nS'PPMT'\np3\ntRp4\n."))
+        pap2 = pytz.timezone('America/Port-au-Prince')
+        self.assertTrue(pap1 is pap2)
+
+        gmt1 = pickle.loads(_byte_string(
+            "cpytz\n_p\np1\n(S'Etc/GMT_plus_10'\np2\ntRp3\n."))
+        gmt2 = pytz.timezone('Etc/GMT+10')
+        self.assertTrue(gmt1 is gmt2)
+
+
+class USEasternDSTStartTestCase(unittest.TestCase):
+    tzinfo = pytz.timezone('US/Eastern')
+
+    # 24 hours before DST changeover
+    transition_time = datetime(2002, 4, 7, 7, 0, 0, tzinfo=UTC)
+
+    # Increase for 'flexible' DST transitions due to 1 minute granularity
+    # of Python's datetime library
+    instant = timedelta(seconds=1)
+
+    # before transition
+    before = {
+        'tzname': 'EST',
+        'utcoffset': timedelta(hours = -5),
+        'dst': timedelta(hours = 0),
+        }
+
+    # after transition
+    after = {
+        'tzname': 'EDT',
+        'utcoffset': timedelta(hours = -4),
+        'dst': timedelta(hours = 1),
+        }
+
+    def _test_tzname(self, utc_dt, wanted):
+        tzname = wanted['tzname']
+        dt = utc_dt.astimezone(self.tzinfo)
+        self.assertEqual(dt.tzname(), tzname,
+            'Expected %s as tzname for %s. Got %s' % (
+                tzname, str(utc_dt), dt.tzname()
+                )
+            )
+
+    def _test_utcoffset(self, utc_dt, wanted):
+        utcoffset = wanted['utcoffset']
+        dt = utc_dt.astimezone(self.tzinfo)
+        self.assertEqual(
+                dt.utcoffset(), wanted['utcoffset'],
+                'Expected %s as utcoffset for %s. Got %s' % (
+                    utcoffset, utc_dt, dt.utcoffset()
+                    )
+                )
+
+    def _test_dst(self, utc_dt, wanted):
+        dst = wanted['dst']
+        dt = utc_dt.astimezone(self.tzinfo)
+        self.assertEqual(dt.dst(),dst,
+            'Expected %s as dst for %s. Got %s' % (
+                dst, utc_dt, dt.dst()
+                )
+            )
+
+    def test_arithmetic(self):
+        utc_dt = self.transition_time
+
+        for days in range(-420, 720, 20):
+            delta = timedelta(days=days)
+
+            # Make sure we can get back where we started
+            dt = utc_dt.astimezone(self.tzinfo)
+            dt2 = dt + delta
+            dt2 = dt2 - delta
+            self.assertEqual(dt, dt2)
+
+            # Make sure arithmetic crossing DST boundaries ends
+            # up in the correct timezone after normalization
+            utc_plus_delta = (utc_dt + delta).astimezone(self.tzinfo)
+            local_plus_delta = self.tzinfo.normalize(dt + delta)
+            self.assertEqual(
+                    prettydt(utc_plus_delta),
+                    prettydt(local_plus_delta),
+                    'Incorrect result for delta==%d days.  Wanted %r. Got %r'%(
+                        days,
+                        prettydt(utc_plus_delta),
+                        prettydt(local_plus_delta),
+                        )
+                    )
+
+    def _test_all(self, utc_dt, wanted):
+        self._test_utcoffset(utc_dt, wanted)
+        self._test_tzname(utc_dt, wanted)
+        self._test_dst(utc_dt, wanted)
+
+    def testDayBefore(self):
+        self._test_all(
+                self.transition_time - timedelta(days=1), self.before
+                )
+
+    def testTwoHoursBefore(self):
+        self._test_all(
+                self.transition_time - timedelta(hours=2), self.before
+                )
+
+    def testHourBefore(self):
+        self._test_all(
+                self.transition_time - timedelta(hours=1), self.before
+                )
+
+    def testInstantBefore(self):
+        self._test_all(
+                self.transition_time - self.instant, self.before
+                )
+
+    def testTransition(self):
+        self._test_all(
+                self.transition_time, self.after
+                )
+
+    def testInstantAfter(self):
+        self._test_all(
+                self.transition_time + self.instant, self.after
+                )
+
+    def testHourAfter(self):
+        self._test_all(
+                self.transition_time + timedelta(hours=1), self.after
+                )
+
+    def testTwoHoursAfter(self):
+        self._test_all(
+                self.transition_time + timedelta(hours=1), self.after
+                )
+
+    def testDayAfter(self):
+        self._test_all(
+                self.transition_time + timedelta(days=1), self.after
+                )
+
+
+class USEasternDSTEndTestCase(USEasternDSTStartTestCase):
+    tzinfo = pytz.timezone('US/Eastern')
+    transition_time = datetime(2002, 10, 27, 6, 0, 0, tzinfo=UTC)
+    before = {
+        'tzname': 'EDT',
+        'utcoffset': timedelta(hours = -4),
+        'dst': timedelta(hours = 1),
+        }
+    after = {
+        'tzname': 'EST',
+        'utcoffset': timedelta(hours = -5),
+        'dst': timedelta(hours = 0),
+        }
+
+
+class USEasternEPTStartTestCase(USEasternDSTStartTestCase):
+    transition_time = datetime(1945, 8, 14, 23, 0, 0, tzinfo=UTC)
+    before = {
+        'tzname': 'EWT',
+        'utcoffset': timedelta(hours = -4),
+        'dst': timedelta(hours = 1),
+        }
+    after = {
+        'tzname': 'EPT',
+        'utcoffset': timedelta(hours = -4),
+        'dst': timedelta(hours = 1),
+        }
+
+
+class USEasternEPTEndTestCase(USEasternDSTStartTestCase):
+    transition_time = datetime(1945, 9, 30, 6, 0, 0, tzinfo=UTC)
+    before = {
+        'tzname': 'EPT',
+        'utcoffset': timedelta(hours = -4),
+        'dst': timedelta(hours = 1),
+        }
+    after = {
+        'tzname': 'EST',
+        'utcoffset': timedelta(hours = -5),
+        'dst': timedelta(hours = 0),
+        }
+
+
+class WarsawWMTEndTestCase(USEasternDSTStartTestCase):
+    # In 1915, Warsaw changed from Warsaw to Central European time.
+    # This involved the clocks being set backwards, causing a end-of-DST
+    # like situation without DST being involved.
+    tzinfo = pytz.timezone('Europe/Warsaw')
+    transition_time = datetime(1915, 8, 4, 22, 36, 0, tzinfo=UTC)
+    before = {
+        'tzname': 'WMT',
+        'utcoffset': timedelta(hours=1, minutes=24),
+        'dst': timedelta(0),
+        }
+    after = {
+        'tzname': 'CET',
+        'utcoffset': timedelta(hours=1),
+        'dst': timedelta(0),
+        }
+
+
+class VilniusWMTEndTestCase(USEasternDSTStartTestCase):
+    # At the end of 1916, Vilnius changed timezones putting its clock
+    # forward by 11 minutes 35 seconds. Neither timezone was in DST mode.
+    tzinfo = pytz.timezone('Europe/Vilnius')
+    instant = timedelta(seconds=31)
+    transition_time = datetime(1916, 12, 31, 22, 36, 00, tzinfo=UTC)
+    before = {
+        'tzname': 'WMT',
+        'utcoffset': timedelta(hours=1, minutes=24),
+        'dst': timedelta(0),
+        }
+    after = {
+        'tzname': 'KMT',
+        'utcoffset': timedelta(hours=1, minutes=36), # Really 1:35:36
+        'dst': timedelta(0),
+        }
+
+
+class VilniusCESTStartTestCase(USEasternDSTStartTestCase):
+    # In 1941, Vilnius changed from MSG to CEST, switching to summer
+    # time while simultaneously reducing its UTC offset by two hours,
+    # causing the clocks to go backwards for this summer time
+    # switchover.
+    tzinfo = pytz.timezone('Europe/Vilnius')
+    transition_time = datetime(1941, 6, 23, 21, 00, 00, tzinfo=UTC)
+    before = {
+        'tzname': 'MSK',
+        'utcoffset': timedelta(hours=3),
+        'dst': timedelta(0),
+        }
+    after = {
+        'tzname': 'CEST',
+        'utcoffset': timedelta(hours=2),
+        'dst': timedelta(hours=1),
+        }
+
+
+class LondonHistoryStartTestCase(USEasternDSTStartTestCase):
+    # The first known timezone transition in London was in 1847 when
+    # clocks where synchronized to GMT. However, we currently only
+    # understand v1 format tzfile(5) files which does handle years
+    # this far in the past, so our earliest known transition is in
+    # 1916.
+    tzinfo = pytz.timezone('Europe/London')
+    # transition_time = datetime(1847, 12, 1, 1, 15, 00, tzinfo=UTC)
+    # before = {
+    #     'tzname': 'LMT',
+    #     'utcoffset': timedelta(minutes=-75),
+    #     'dst': timedelta(0),
+    #     }
+    # after = {
+    #     'tzname': 'GMT',
+    #     'utcoffset': timedelta(0),
+    #     'dst': timedelta(0),
+    #     }
+    transition_time = datetime(1916, 5, 21, 2, 00, 00, tzinfo=UTC)
+    before = {
+        'tzname': 'GMT',
+        'utcoffset': timedelta(0),
+        'dst': timedelta(0),
+        }
+    after = {
+        'tzname': 'BST',
+        'utcoffset': timedelta(hours=1),
+        'dst': timedelta(hours=1),
+        }
+
+
+class LondonHistoryEndTestCase(USEasternDSTStartTestCase):
+    # Timezone switchovers are projected into the future, even
+    # though no official statements exist or could be believed even
+    # if they did exist. We currently only check the last known
+    # transition in 2037, as we are still using v1 format tzfile(5)
+    # files.
+    tzinfo = pytz.timezone('Europe/London')
+    # transition_time = datetime(2499, 10, 25, 1, 0, 0, tzinfo=UTC)
+    transition_time = datetime(2037, 10, 25, 1, 0, 0, tzinfo=UTC)
+    before = {
+        'tzname': 'BST',
+        'utcoffset': timedelta(hours=1),
+        'dst': timedelta(hours=1),
+        }
+    after = {
+        'tzname': 'GMT',
+        'utcoffset': timedelta(0),
+        'dst': timedelta(0),
+        }
+
+
+class NoumeaHistoryStartTestCase(USEasternDSTStartTestCase):
+    # Noumea adopted a whole hour offset in 1912. Previously
+    # it was 11 hours, 5 minutes and 48 seconds off UTC. However,
+    # due to limitations of the Python datetime library, we need
+    # to round that to 11 hours 6 minutes.
+    tzinfo = pytz.timezone('Pacific/Noumea')
+    transition_time = datetime(1912, 1, 12, 12, 54, 12, tzinfo=UTC)
+    before = {
+        'tzname': 'LMT',
+        'utcoffset': timedelta(hours=11, minutes=6),
+        'dst': timedelta(0),
+        }
+    after = {
+        'tzname': 'NCT',
+        'utcoffset': timedelta(hours=11),
+        'dst': timedelta(0),
+        }
+
+
+class NoumeaDSTEndTestCase(USEasternDSTStartTestCase):
+    # Noumea dropped DST in 1997.
+    tzinfo = pytz.timezone('Pacific/Noumea')
+    transition_time = datetime(1997, 3, 1, 15, 00, 00, tzinfo=UTC)
+    before = {
+        'tzname': 'NCST',
+        'utcoffset': timedelta(hours=12),
+        'dst': timedelta(hours=1),
+        }
+    after = {
+        'tzname': 'NCT',
+        'utcoffset': timedelta(hours=11),
+        'dst': timedelta(0),
+        }
+
+
+class NoumeaNoMoreDSTTestCase(NoumeaDSTEndTestCase):
+    # Noumea dropped DST in 1997. Here we test that it stops occuring.
+    transition_time = (
+        NoumeaDSTEndTestCase.transition_time + timedelta(days=365*10))
+    before = NoumeaDSTEndTestCase.after
+    after = NoumeaDSTEndTestCase.after
+
+
+class TahitiTestCase(USEasternDSTStartTestCase):
+    # Tahiti has had a single transition in its history.
+    tzinfo = pytz.timezone('Pacific/Tahiti')
+    transition_time = datetime(1912, 10, 1, 9, 58, 16, tzinfo=UTC)
+    before = {
+        'tzname': 'LMT',
+        'utcoffset': timedelta(hours=-9, minutes=-58),
+        'dst': timedelta(0),
+        }
+    after = {
+        'tzname': 'TAHT',
+        'utcoffset': timedelta(hours=-10),
+        'dst': timedelta(0),
+        }
+
+
+class SamoaInternationalDateLineChange(USEasternDSTStartTestCase):
+    # At the end of 2011, Samoa will switch from being east of the
+    # international dateline to the west. There will be no Dec 30th
+    # 2011 and it will switch from UTC-10 to UTC+14.
+    tzinfo = pytz.timezone('Pacific/Apia')
+    transition_time = datetime(2011, 12, 30, 10, 0, 0, tzinfo=UTC)
+    before = {
+        'tzname': 'WSDT',
+        'utcoffset': timedelta(hours=-10),
+        'dst': timedelta(hours=1),
+        }
+    after = {
+        'tzname': 'WSDT',
+        'utcoffset': timedelta(hours=14),
+        'dst': timedelta(hours=1),
+        }
+
+
+class ReferenceUSEasternDSTStartTestCase(USEasternDSTStartTestCase):
+    tzinfo = reference.Eastern
+    def test_arithmetic(self):
+        # Reference implementation cannot handle this
+        pass
+
+
+class ReferenceUSEasternDSTEndTestCase(USEasternDSTEndTestCase):
+    tzinfo = reference.Eastern
+
+    def testHourBefore(self):
+        # Python's datetime library has a bug, where the hour before
+        # a daylight savings transition is one hour out. For example,
+        # at the end of US/Eastern daylight savings time, 01:00 EST
+        # occurs twice (once at 05:00 UTC and once at 06:00 UTC),
+        # whereas the first should actually be 01:00 EDT.
+        # Note that this bug is by design - by accepting this ambiguity
+        # for one hour one hour per year, an is_dst flag on datetime.time
+        # became unnecessary.
+        self._test_all(
+                self.transition_time - timedelta(hours=1), self.after
+                )
+
+    def testInstantBefore(self):
+        self._test_all(
+                self.transition_time - timedelta(seconds=1), self.after
+                )
+
+    def test_arithmetic(self):
+        # Reference implementation cannot handle this
+        pass
+
+
+class LocalTestCase(unittest.TestCase):
+    def testLocalize(self):
+        loc_tz = pytz.timezone('Europe/Amsterdam')
+
+        loc_time = loc_tz.localize(datetime(1930, 5, 10, 0, 0, 0))
+        # Actually +00:19:32, but Python datetime rounds this
+        self.assertEqual(loc_time.strftime('%Z%z'), 'AMT+0020')
+
+        loc_time = loc_tz.localize(datetime(1930, 5, 20, 0, 0, 0))
+        # Actually +00:19:32, but Python datetime rounds this
+        self.assertEqual(loc_time.strftime('%Z%z'), 'NST+0120')
+
+        loc_time = loc_tz.localize(datetime(1940, 5, 10, 0, 0, 0))
+        self.assertEqual(loc_time.strftime('%Z%z'), 'NET+0020')
+
+        loc_time = loc_tz.localize(datetime(1940, 5, 20, 0, 0, 0))
+        self.assertEqual(loc_time.strftime('%Z%z'), 'CEST+0200')
+
+        loc_time = loc_tz.localize(datetime(2004, 2, 1, 0, 0, 0))
+        self.assertEqual(loc_time.strftime('%Z%z'), 'CET+0100')
+
+        loc_time = loc_tz.localize(datetime(2004, 4, 1, 0, 0, 0))
+        self.assertEqual(loc_time.strftime('%Z%z'), 'CEST+0200')
+
+        tz = pytz.timezone('Europe/Amsterdam')
+        loc_time = loc_tz.localize(datetime(1943, 3, 29, 1, 59, 59))
+        self.assertEqual(loc_time.strftime('%Z%z'), 'CET+0100')
+
+
+        # Switch to US
+        loc_tz = pytz.timezone('US/Eastern')
+
+        # End of DST ambiguity check
+        loc_time = loc_tz.localize(datetime(1918, 10, 27, 1, 59, 59), is_dst=1)
+        self.assertEqual(loc_time.strftime('%Z%z'), 'EDT-0400')
+
+        loc_time = loc_tz.localize(datetime(1918, 10, 27, 1, 59, 59), is_dst=0)
+        self.assertEqual(loc_time.strftime('%Z%z'), 'EST-0500')
+
+        self.assertRaises(pytz.AmbiguousTimeError,
+            loc_tz.localize, datetime(1918, 10, 27, 1, 59, 59), is_dst=None
+            )
+
+        # Start of DST non-existent times
+        loc_time = loc_tz.localize(datetime(1918, 3, 31, 2, 0, 0), is_dst=0)
+        self.assertEqual(loc_time.strftime('%Z%z'), 'EST-0500')
+
+        loc_time = loc_tz.localize(datetime(1918, 3, 31, 2, 0, 0), is_dst=1)
+        self.assertEqual(loc_time.strftime('%Z%z'), 'EDT-0400')
+
+        self.assertRaises(pytz.NonExistentTimeError,
+            loc_tz.localize, datetime(1918, 3, 31, 2, 0, 0), is_dst=None
+            )
+
+        # Weird changes - war time and peace time both is_dst==True
+
+        loc_time = loc_tz.localize(datetime(1942, 2, 9, 3, 0, 0))
+        self.assertEqual(loc_time.strftime('%Z%z'), 'EWT-0400')
+
+        loc_time = loc_tz.localize(datetime(1945, 8, 14, 19, 0, 0))
+        self.assertEqual(loc_time.strftime('%Z%z'), 'EPT-0400')
+
+        loc_time = loc_tz.localize(datetime(1945, 9, 30, 1, 0, 0), is_dst=1)
+        self.assertEqual(loc_time.strftime('%Z%z'), 'EPT-0400')
+
+        loc_time = loc_tz.localize(datetime(1945, 9, 30, 1, 0, 0), is_dst=0)
+        self.assertEqual(loc_time.strftime('%Z%z'), 'EST-0500')
+
+    def testNormalize(self):
+        tz = pytz.timezone('US/Eastern')
+        dt = datetime(2004, 4, 4, 7, 0, 0, tzinfo=UTC).astimezone(tz)
+        dt2 = dt - timedelta(minutes=10)
+        self.assertEqual(
+                dt2.strftime('%Y-%m-%d %H:%M:%S %Z%z'),
+                '2004-04-04 02:50:00 EDT-0400'
+                )
+
+        dt2 = tz.normalize(dt2)
+        self.assertEqual(
+                dt2.strftime('%Y-%m-%d %H:%M:%S %Z%z'),
+                '2004-04-04 01:50:00 EST-0500'
+                )
+
+    def testPartialMinuteOffsets(self):
+        # utcoffset in Amsterdam was not a whole minute until 1937
+        # However, we fudge this by rounding them, as the Python
+        # datetime library 
+        tz = pytz.timezone('Europe/Amsterdam')
+        utc_dt = datetime(1914, 1, 1, 13, 40, 28, tzinfo=UTC) # correct
+        utc_dt = utc_dt.replace(second=0) # But we need to fudge it
+        loc_dt = utc_dt.astimezone(tz)
+        self.assertEqual(
+                loc_dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'),
+                '1914-01-01 14:00:00 AMT+0020'
+                )
+
+        # And get back...
+        utc_dt = loc_dt.astimezone(UTC)
+        self.assertEqual(
+                utc_dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'),
+                '1914-01-01 13:40:00 UTC+0000'
+                )
+
+    def no_testCreateLocaltime(self):
+        # It would be nice if this worked, but it doesn't.
+        tz = pytz.timezone('Europe/Amsterdam')
+        dt = datetime(2004, 10, 31, 2, 0, 0, tzinfo=tz)
+        self.assertEqual(
+                dt.strftime(fmt),
+                '2004-10-31 02:00:00 CET+0100'
+                )
+
+
+class CommonTimezonesTestCase(unittest.TestCase):
+    def test_bratislava(self):
+        # Bratislava is the default timezone for Slovakia, but our
+        # heuristics where not adding it to common_timezones. Ideally,
+        # common_timezones should be populated from zone.tab at runtime,
+        # but I'm hesitant to pay the startup cost as loading the list
+        # on demand whilst remaining backwards compatible seems
+        # difficult.
+        self.assertTrue('Europe/Bratislava' in pytz.common_timezones)
+        self.assertTrue('Europe/Bratislava' in pytz.common_timezones_set)
+
+    def test_us_eastern(self):
+        self.assertTrue('US/Eastern' in pytz.common_timezones)
+        self.assertTrue('US/Eastern' in pytz.common_timezones_set)
+
+    def test_belfast(self):
+        # Belfast uses London time.
+        self.assertTrue('Europe/Belfast' in pytz.all_timezones_set)
+        self.assertFalse('Europe/Belfast' in pytz.common_timezones)
+        self.assertFalse('Europe/Belfast' in pytz.common_timezones_set)
+
+
+class BaseTzInfoTestCase:
+    '''Ensure UTC, StaticTzInfo and DstTzInfo work consistently.
+
+    These tests are run for each type of tzinfo.
+    '''
+    tz = None  # override
+    tz_class = None  # override
+
+    def test_expectedclass(self):
+        self.assertTrue(isinstance(self.tz, self.tz_class))
+
+    def test_fromutc(self):
+        # naive datetime.
+        dt1 = datetime(2011, 10, 31)
+
+        # localized datetime, same timezone.
+        dt2 = self.tz.localize(dt1)
+
+        # Both should give the same results. Note that the standard
+        # Python tzinfo.fromutc() only supports the second.
+        for dt in [dt1, dt2]:
+            loc_dt = self.tz.fromutc(dt)
+            loc_dt2 = pytz.utc.localize(dt1).astimezone(self.tz)
+            self.assertEqual(loc_dt, loc_dt2)
+
+        # localized datetime, different timezone.
+        new_tz = pytz.timezone('Europe/Paris')
+        self.assertTrue(self.tz is not new_tz)
+        dt3 = new_tz.localize(dt1)
+        self.assertRaises(ValueError, self.tz.fromutc, dt3)
+
+    def test_normalize(self):
+        other_tz = pytz.timezone('Europe/Paris')
+        self.assertTrue(self.tz is not other_tz)
+
+        dt = datetime(2012, 3, 26, 12, 0)
+        other_dt = other_tz.localize(dt)
+
+        local_dt = self.tz.normalize(other_dt)
+
+        self.assertTrue(local_dt.tzinfo is not other_dt.tzinfo)
+        self.assertNotEqual(
+            local_dt.replace(tzinfo=None), other_dt.replace(tzinfo=None))
+
+    def test_astimezone(self):
+        other_tz = pytz.timezone('Europe/Paris')
+        self.assertTrue(self.tz is not other_tz)
+
+        dt = datetime(2012, 3, 26, 12, 0)
+        other_dt = other_tz.localize(dt)
+
+        local_dt = other_dt.astimezone(self.tz)
+
+        self.assertTrue(local_dt.tzinfo is not other_dt.tzinfo)
+        self.assertNotEqual(
+            local_dt.replace(tzinfo=None), other_dt.replace(tzinfo=None))
+
+
+class OptimizedUTCTestCase(unittest.TestCase, BaseTzInfoTestCase):
+    tz = pytz.utc
+    tz_class = tz.__class__
+
+
+class LegacyUTCTestCase(unittest.TestCase, BaseTzInfoTestCase):
+    # Deprecated timezone, but useful for comparison tests.
+    tz = pytz.timezone('Etc/UTC')
+    tz_class = StaticTzInfo
+
+
+class StaticTzInfoTestCase(unittest.TestCase, BaseTzInfoTestCase):
+    tz = pytz.timezone('GMT')
+    tz_class = StaticTzInfo
+
+
+class DstTzInfoTestCase(unittest.TestCase, BaseTzInfoTestCase):
+    tz = pytz.timezone('Australia/Melbourne')
+    tz_class = DstTzInfo
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(doctest.DocTestSuite('pytz'))
+    suite.addTest(doctest.DocTestSuite('pytz.tzinfo'))
+    import test_tzinfo
+    suite.addTest(unittest.defaultTestLoader.loadTestsFromModule(test_tzinfo))
+    return suite
+
+
+if __name__ == '__main__':
+    warnings.simplefilter("error") # Warnings should be fatal in tests.
+    unittest.main(defaultTest='test_suite')
+

+ 137 - 0
desktop/core/ext-py/pytz-2013.9/pytz/tzfile.py

@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+'''
+$Id: tzfile.py,v 1.8 2004/06/03 00:15:24 zenzen Exp $
+'''
+
+try:
+    from cStringIO import StringIO
+except ImportError:
+    from io import StringIO
+from datetime import datetime, timedelta
+from struct import unpack, calcsize
+
+from pytz.tzinfo import StaticTzInfo, DstTzInfo, memorized_ttinfo
+from pytz.tzinfo import memorized_datetime, memorized_timedelta
+
+def _byte_string(s):
+    """Cast a string or byte string to an ASCII byte string."""
+    return s.encode('US-ASCII')
+
+_NULL = _byte_string('\0')
+
+def _std_string(s):
+    """Cast a string or byte string to an ASCII string."""
+    return str(s.decode('US-ASCII'))
+
+def build_tzinfo(zone, fp):
+    head_fmt = '>4s c 15x 6l'
+    head_size = calcsize(head_fmt)
+    (magic, format, ttisgmtcnt, ttisstdcnt,leapcnt, timecnt,
+        typecnt, charcnt) =  unpack(head_fmt, fp.read(head_size))
+
+    # Make sure it is a tzfile(5) file
+    assert magic == _byte_string('TZif'), 'Got magic %s' % repr(magic)
+
+    # Read out the transition times, localtime indices and ttinfo structures.
+    data_fmt = '>%(timecnt)dl %(timecnt)dB %(ttinfo)s %(charcnt)ds' % dict(
+        timecnt=timecnt, ttinfo='lBB'*typecnt, charcnt=charcnt)
+    data_size = calcsize(data_fmt)
+    data = unpack(data_fmt, fp.read(data_size))
+
+    # make sure we unpacked the right number of values
+    assert len(data) == 2 * timecnt + 3 * typecnt + 1
+    transitions = [memorized_datetime(trans)
+                   for trans in data[:timecnt]]
+    lindexes = list(data[timecnt:2 * timecnt])
+    ttinfo_raw = data[2 * timecnt:-1]
+    tznames_raw = data[-1]
+    del data
+
+    # Process ttinfo into separate structs
+    ttinfo = []
+    tznames = {}
+    i = 0
+    while i < len(ttinfo_raw):
+        # have we looked up this timezone name yet?
+        tzname_offset = ttinfo_raw[i+2]
+        if tzname_offset not in tznames:
+            nul = tznames_raw.find(_NULL, tzname_offset)
+            if nul < 0:
+                nul = len(tznames_raw)
+            tznames[tzname_offset] = _std_string(
+                tznames_raw[tzname_offset:nul])
+        ttinfo.append((ttinfo_raw[i],
+                       bool(ttinfo_raw[i+1]),
+                       tznames[tzname_offset]))
+        i += 3
+
+    # Now build the timezone object
+    if len(transitions) == 0:
+        ttinfo[0][0], ttinfo[0][2]
+        cls = type(zone, (StaticTzInfo,), dict(
+            zone=zone,
+            _utcoffset=memorized_timedelta(ttinfo[0][0]),
+            _tzname=ttinfo[0][2]))
+    else:
+        # Early dates use the first standard time ttinfo
+        i = 0
+        while ttinfo[i][1]:
+            i += 1
+        if ttinfo[i] == ttinfo[lindexes[0]]:
+            transitions[0] = datetime.min
+        else:
+            transitions.insert(0, datetime.min)
+            lindexes.insert(0, i)
+
+        # calculate transition info
+        transition_info = []
+        for i in range(len(transitions)):
+            inf = ttinfo[lindexes[i]]
+            utcoffset = inf[0]
+            if not inf[1]:
+                dst = 0
+            else:
+                for j in range(i-1, -1, -1):
+                    prev_inf = ttinfo[lindexes[j]]
+                    if not prev_inf[1]:
+                        break
+                dst = inf[0] - prev_inf[0] # dst offset
+
+                # Bad dst? Look further. DST > 24 hours happens when
+                # a timzone has moved across the international dateline.
+                if dst <= 0 or dst > 3600*3:
+                    for j in range(i+1, len(transitions)):
+                        stdinf = ttinfo[lindexes[j]]
+                        if not stdinf[1]:
+                            dst = inf[0] - stdinf[0]
+                            if dst > 0:
+                                break # Found a useful std time.
+
+            tzname = inf[2]
+
+            # Round utcoffset and dst to the nearest minute or the
+            # datetime library will complain. Conversions to these timezones
+            # might be up to plus or minus 30 seconds out, but it is
+            # the best we can do.
+            utcoffset = int((utcoffset + 30) // 60) * 60
+            dst = int((dst + 30) // 60) * 60
+            transition_info.append(memorized_ttinfo(utcoffset, dst, tzname))
+
+        cls = type(zone, (DstTzInfo,), dict(
+            zone=zone,
+            _utc_transition_times=transitions,
+            _transition_info=transition_info))
+
+    return cls()
+
+if __name__ == '__main__':
+    import os.path
+    from pprint import pprint
+    base = os.path.join(os.path.dirname(__file__), 'zoneinfo')
+    tz = build_tzinfo('Australia/Melbourne',
+                      open(os.path.join(base,'Australia','Melbourne'), 'rb'))
+    tz = build_tzinfo('US/Eastern',
+                      open(os.path.join(base,'US','Eastern'), 'rb'))
+    pprint(tz._utc_transition_times)
+    #print tz.asPython(4)
+    #print tz.transitions_mapping

+ 563 - 0
desktop/core/ext-py/pytz-2013.9/pytz/tzinfo.py

@@ -0,0 +1,563 @@
+'''Base classes and helpers for building zone specific tzinfo classes'''
+
+from datetime import datetime, timedelta, tzinfo
+from bisect import bisect_right
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+import pytz
+from pytz.exceptions import AmbiguousTimeError, NonExistentTimeError
+
+__all__ = []
+
+_timedelta_cache = {}
+def memorized_timedelta(seconds):
+    '''Create only one instance of each distinct timedelta'''
+    try:
+        return _timedelta_cache[seconds]
+    except KeyError:
+        delta = timedelta(seconds=seconds)
+        _timedelta_cache[seconds] = delta
+        return delta
+
+_epoch = datetime.utcfromtimestamp(0)
+_datetime_cache = {0: _epoch}
+def memorized_datetime(seconds):
+    '''Create only one instance of each distinct datetime'''
+    try:
+        return _datetime_cache[seconds]
+    except KeyError:
+        # NB. We can't just do datetime.utcfromtimestamp(seconds) as this
+        # fails with negative values under Windows (Bug #90096)
+        dt = _epoch + timedelta(seconds=seconds)
+        _datetime_cache[seconds] = dt
+        return dt
+
+_ttinfo_cache = {}
+def memorized_ttinfo(*args):
+    '''Create only one instance of each distinct tuple'''
+    try:
+        return _ttinfo_cache[args]
+    except KeyError:
+        ttinfo = (
+                memorized_timedelta(args[0]),
+                memorized_timedelta(args[1]),
+                args[2]
+                )
+        _ttinfo_cache[args] = ttinfo
+        return ttinfo
+
+_notime = memorized_timedelta(0)
+
+def _to_seconds(td):
+    '''Convert a timedelta to seconds'''
+    return td.seconds + td.days * 24 * 60 * 60
+
+
+class BaseTzInfo(tzinfo):
+    # Overridden in subclass
+    _utcoffset = None
+    _tzname = None
+    zone = None
+
+    def __str__(self):
+        return self.zone
+
+
+class StaticTzInfo(BaseTzInfo):
+    '''A timezone that has a constant offset from UTC
+
+    These timezones are rare, as most locations have changed their
+    offset at some point in their history
+    '''
+    def fromutc(self, dt):
+        '''See datetime.tzinfo.fromutc'''
+        if dt.tzinfo is not None and dt.tzinfo is not self:
+            raise ValueError('fromutc: dt.tzinfo is not self')
+        return (dt + self._utcoffset).replace(tzinfo=self)
+
+    def utcoffset(self, dt, is_dst=None):
+        '''See datetime.tzinfo.utcoffset
+
+        is_dst is ignored for StaticTzInfo, and exists only to
+        retain compatibility with DstTzInfo.
+        '''
+        return self._utcoffset
+
+    def dst(self, dt, is_dst=None):
+        '''See datetime.tzinfo.dst
+
+        is_dst is ignored for StaticTzInfo, and exists only to
+        retain compatibility with DstTzInfo.
+        '''
+        return _notime
+
+    def tzname(self, dt, is_dst=None):
+        '''See datetime.tzinfo.tzname
+
+        is_dst is ignored for StaticTzInfo, and exists only to
+        retain compatibility with DstTzInfo.
+        '''
+        return self._tzname
+
+    def localize(self, dt, is_dst=False):
+        '''Convert naive time to local time'''
+        if dt.tzinfo is not None:
+            raise ValueError('Not naive datetime (tzinfo is already set)')
+        return dt.replace(tzinfo=self)
+
+    def normalize(self, dt, is_dst=False):
+        '''Correct the timezone information on the given datetime.
+
+        This is normally a no-op, as StaticTzInfo timezones never have
+        ambiguous cases to correct:
+
+        >>> from pytz import timezone
+        >>> gmt = timezone('GMT')
+        >>> isinstance(gmt, StaticTzInfo)
+        True
+        >>> dt = datetime(2011, 5, 8, 1, 2, 3, tzinfo=gmt)
+        >>> gmt.normalize(dt) is dt
+        True
+
+        The supported method of converting between timezones is to use
+        datetime.astimezone(). Currently normalize() also works:
+
+        >>> la = timezone('America/Los_Angeles')
+        >>> dt = la.localize(datetime(2011, 5, 7, 1, 2, 3))
+        >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+        >>> gmt.normalize(dt).strftime(fmt)
+        '2011-05-07 08:02:03 GMT (+0000)'
+        '''
+        if dt.tzinfo is self:
+            return dt
+        if dt.tzinfo is None:
+            raise ValueError('Naive time - no tzinfo set')
+        return dt.astimezone(self)
+
+    def __repr__(self):
+        return '<StaticTzInfo %r>' % (self.zone,)
+
+    def __reduce__(self):
+        # Special pickle to zone remains a singleton and to cope with
+        # database changes. 
+        return pytz._p, (self.zone,)
+
+
+class DstTzInfo(BaseTzInfo):
+    '''A timezone that has a variable offset from UTC
+
+    The offset might change if daylight savings time comes into effect,
+    or at a point in history when the region decides to change their
+    timezone definition.
+    '''
+    # Overridden in subclass
+    _utc_transition_times = None # Sorted list of DST transition times in UTC
+    _transition_info = None # [(utcoffset, dstoffset, tzname)] corresponding
+                            # to _utc_transition_times entries
+    zone = None
+
+    # Set in __init__
+    _tzinfos = None
+    _dst = None # DST offset
+
+    def __init__(self, _inf=None, _tzinfos=None):
+        if _inf:
+            self._tzinfos = _tzinfos
+            self._utcoffset, self._dst, self._tzname = _inf
+        else:
+            _tzinfos = {}
+            self._tzinfos = _tzinfos
+            self._utcoffset, self._dst, self._tzname = self._transition_info[0]
+            _tzinfos[self._transition_info[0]] = self
+            for inf in self._transition_info[1:]:
+                if inf not in _tzinfos:
+                    _tzinfos[inf] = self.__class__(inf, _tzinfos)
+
+    def fromutc(self, dt):
+        '''See datetime.tzinfo.fromutc'''
+        if (dt.tzinfo is not None
+            and getattr(dt.tzinfo, '_tzinfos', None) is not self._tzinfos):
+            raise ValueError('fromutc: dt.tzinfo is not self')
+        dt = dt.replace(tzinfo=None)
+        idx = max(0, bisect_right(self._utc_transition_times, dt) - 1)
+        inf = self._transition_info[idx]
+        return (dt + inf[0]).replace(tzinfo=self._tzinfos[inf])
+
+    def normalize(self, dt):
+        '''Correct the timezone information on the given datetime
+
+        If date arithmetic crosses DST boundaries, the tzinfo
+        is not magically adjusted. This method normalizes the
+        tzinfo to the correct one.
+
+        To test, first we need to do some setup
+
+        >>> from pytz import timezone
+        >>> utc = timezone('UTC')
+        >>> eastern = timezone('US/Eastern')
+        >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+
+        We next create a datetime right on an end-of-DST transition point,
+        the instant when the wallclocks are wound back one hour.
+
+        >>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
+        >>> loc_dt = utc_dt.astimezone(eastern)
+        >>> loc_dt.strftime(fmt)
+        '2002-10-27 01:00:00 EST (-0500)'
+
+        Now, if we subtract a few minutes from it, note that the timezone
+        information has not changed.
+
+        >>> before = loc_dt - timedelta(minutes=10)
+        >>> before.strftime(fmt)
+        '2002-10-27 00:50:00 EST (-0500)'
+
+        But we can fix that by calling the normalize method
+
+        >>> before = eastern.normalize(before)
+        >>> before.strftime(fmt)
+        '2002-10-27 01:50:00 EDT (-0400)'
+
+        The supported method of converting between timezones is to use
+        datetime.astimezone(). Currently, normalize() also works:
+
+        >>> th = timezone('Asia/Bangkok')
+        >>> am = timezone('Europe/Amsterdam')
+        >>> dt = th.localize(datetime(2011, 5, 7, 1, 2, 3))
+        >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+        >>> am.normalize(dt).strftime(fmt)
+        '2011-05-06 20:02:03 CEST (+0200)'
+        '''
+        if dt.tzinfo is None:
+            raise ValueError('Naive time - no tzinfo set')
+
+        # Convert dt in localtime to UTC
+        offset = dt.tzinfo._utcoffset
+        dt = dt.replace(tzinfo=None)
+        dt = dt - offset
+        # convert it back, and return it
+        return self.fromutc(dt)
+
+    def localize(self, dt, is_dst=False):
+        '''Convert naive time to local time.
+
+        This method should be used to construct localtimes, rather
+        than passing a tzinfo argument to a datetime constructor.
+
+        is_dst is used to determine the correct timezone in the ambigous
+        period at the end of daylight savings time.
+
+        >>> from pytz import timezone
+        >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
+        >>> amdam = timezone('Europe/Amsterdam')
+        >>> dt  = datetime(2004, 10, 31, 2, 0, 0)
+        >>> loc_dt1 = amdam.localize(dt, is_dst=True)
+        >>> loc_dt2 = amdam.localize(dt, is_dst=False)
+        >>> loc_dt1.strftime(fmt)
+        '2004-10-31 02:00:00 CEST (+0200)'
+        >>> loc_dt2.strftime(fmt)
+        '2004-10-31 02:00:00 CET (+0100)'
+        >>> str(loc_dt2 - loc_dt1)
+        '1:00:00'
+
+        Use is_dst=None to raise an AmbiguousTimeError for ambiguous
+        times at the end of daylight savings
+
+        >>> try:
+        ...     loc_dt1 = amdam.localize(dt, is_dst=None)
+        ... except AmbiguousTimeError:
+        ...     print('Ambiguous')
+        Ambiguous
+
+        is_dst defaults to False
+
+        >>> amdam.localize(dt) == amdam.localize(dt, False)
+        True
+
+        is_dst is also used to determine the correct timezone in the
+        wallclock times jumped over at the start of daylight savings time.
+
+        >>> pacific = timezone('US/Pacific')
+        >>> dt = datetime(2008, 3, 9, 2, 0, 0)
+        >>> ploc_dt1 = pacific.localize(dt, is_dst=True)
+        >>> ploc_dt2 = pacific.localize(dt, is_dst=False)
+        >>> ploc_dt1.strftime(fmt)
+        '2008-03-09 02:00:00 PDT (-0700)'
+        >>> ploc_dt2.strftime(fmt)
+        '2008-03-09 02:00:00 PST (-0800)'
+        >>> str(ploc_dt2 - ploc_dt1)
+        '1:00:00'
+
+        Use is_dst=None to raise a NonExistentTimeError for these skipped
+        times.
+
+        >>> try:
+        ...     loc_dt1 = pacific.localize(dt, is_dst=None)
+        ... except NonExistentTimeError:
+        ...     print('Non-existent')
+        Non-existent
+        '''
+        if dt.tzinfo is not None:
+            raise ValueError('Not naive datetime (tzinfo is already set)')
+
+        # Find the two best possibilities.
+        possible_loc_dt = set()
+        for delta in [timedelta(days=-1), timedelta(days=1)]:
+            loc_dt = dt + delta
+            idx = max(0, bisect_right(
+                self._utc_transition_times, loc_dt) - 1)
+            inf = self._transition_info[idx]
+            tzinfo = self._tzinfos[inf]
+            loc_dt = tzinfo.normalize(dt.replace(tzinfo=tzinfo))
+            if loc_dt.replace(tzinfo=None) == dt:
+                possible_loc_dt.add(loc_dt)
+
+        if len(possible_loc_dt) == 1:
+            return possible_loc_dt.pop()
+
+        # If there are no possibly correct timezones, we are attempting
+        # to convert a time that never happened - the time period jumped
+        # during the start-of-DST transition period.
+        if len(possible_loc_dt) == 0:
+            # If we refuse to guess, raise an exception.
+            if is_dst is None:
+                raise NonExistentTimeError(dt)
+
+            # If we are forcing the pre-DST side of the DST transition, we
+            # obtain the correct timezone by winding the clock forward a few
+            # hours.
+            elif is_dst:
+                return self.localize(
+                    dt + timedelta(hours=6), is_dst=True) - timedelta(hours=6)
+
+            # If we are forcing the post-DST side of the DST transition, we
+            # obtain the correct timezone by winding the clock back.
+            else:
+                return self.localize(
+                    dt - timedelta(hours=6), is_dst=False) + timedelta(hours=6)
+
+
+        # If we get this far, we have multiple possible timezones - this
+        # is an ambiguous case occuring during the end-of-DST transition.
+
+        # If told to be strict, raise an exception since we have an
+        # ambiguous case
+        if is_dst is None:
+            raise AmbiguousTimeError(dt)
+
+        # Filter out the possiblilities that don't match the requested
+        # is_dst
+        filtered_possible_loc_dt = [
+            p for p in possible_loc_dt
+                if bool(p.tzinfo._dst) == is_dst
+            ]
+
+        # Hopefully we only have one possibility left. Return it.
+        if len(filtered_possible_loc_dt) == 1:
+            return filtered_possible_loc_dt[0]
+
+        if len(filtered_possible_loc_dt) == 0:
+            filtered_possible_loc_dt = list(possible_loc_dt)
+
+        # If we get this far, we have in a wierd timezone transition
+        # where the clocks have been wound back but is_dst is the same
+        # in both (eg. Europe/Warsaw 1915 when they switched to CET).
+        # At this point, we just have to guess unless we allow more
+        # hints to be passed in (such as the UTC offset or abbreviation),
+        # but that is just getting silly.
+        #
+        # Choose the earliest (by UTC) applicable timezone.
+        sorting_keys = {}
+        for local_dt in filtered_possible_loc_dt:
+            key = local_dt.replace(tzinfo=None) - local_dt.tzinfo._utcoffset
+            sorting_keys[key] = local_dt
+        first_key = sorted(sorting_keys)[0]
+        return sorting_keys[first_key]
+
+    def utcoffset(self, dt, is_dst=None):
+        '''See datetime.tzinfo.utcoffset
+
+        The is_dst parameter may be used to remove ambiguity during DST
+        transitions.
+
+        >>> from pytz import timezone
+        >>> tz = timezone('America/St_Johns')
+        >>> ambiguous = datetime(2009, 10, 31, 23, 30)
+
+        >>> tz.utcoffset(ambiguous, is_dst=False)
+        datetime.timedelta(-1, 73800)
+
+        >>> tz.utcoffset(ambiguous, is_dst=True)
+        datetime.timedelta(-1, 77400)
+
+        >>> try:
+        ...     tz.utcoffset(ambiguous)
+        ... except AmbiguousTimeError:
+        ...     print('Ambiguous')
+        Ambiguous
+
+        '''
+        if dt is None:
+            return None
+        elif dt.tzinfo is not self:
+            dt = self.localize(dt, is_dst)
+            return dt.tzinfo._utcoffset
+        else:
+            return self._utcoffset
+
+    def dst(self, dt, is_dst=None):
+        '''See datetime.tzinfo.dst
+
+        The is_dst parameter may be used to remove ambiguity during DST
+        transitions.
+
+        >>> from pytz import timezone
+        >>> tz = timezone('America/St_Johns')
+
+        >>> normal = datetime(2009, 9, 1)
+
+        >>> tz.dst(normal)
+        datetime.timedelta(0, 3600)
+        >>> tz.dst(normal, is_dst=False)
+        datetime.timedelta(0, 3600)
+        >>> tz.dst(normal, is_dst=True)
+        datetime.timedelta(0, 3600)
+
+        >>> ambiguous = datetime(2009, 10, 31, 23, 30)
+
+        >>> tz.dst(ambiguous, is_dst=False)
+        datetime.timedelta(0)
+        >>> tz.dst(ambiguous, is_dst=True)
+        datetime.timedelta(0, 3600)
+        >>> try:
+        ...     tz.dst(ambiguous)
+        ... except AmbiguousTimeError:
+        ...     print('Ambiguous')
+        Ambiguous
+
+        '''
+        if dt is None:
+            return None
+        elif dt.tzinfo is not self:
+            dt = self.localize(dt, is_dst)
+            return dt.tzinfo._dst
+        else:
+            return self._dst
+
+    def tzname(self, dt, is_dst=None):
+        '''See datetime.tzinfo.tzname
+
+        The is_dst parameter may be used to remove ambiguity during DST
+        transitions.
+
+        >>> from pytz import timezone
+        >>> tz = timezone('America/St_Johns')
+
+        >>> normal = datetime(2009, 9, 1)
+
+        >>> tz.tzname(normal)
+        'NDT'
+        >>> tz.tzname(normal, is_dst=False)
+        'NDT'
+        >>> tz.tzname(normal, is_dst=True)
+        'NDT'
+
+        >>> ambiguous = datetime(2009, 10, 31, 23, 30)
+
+        >>> tz.tzname(ambiguous, is_dst=False)
+        'NST'
+        >>> tz.tzname(ambiguous, is_dst=True)
+        'NDT'
+        >>> try:
+        ...     tz.tzname(ambiguous)
+        ... except AmbiguousTimeError:
+        ...     print('Ambiguous')
+        Ambiguous
+        '''
+        if dt is None:
+            return self.zone
+        elif dt.tzinfo is not self:
+            dt = self.localize(dt, is_dst)
+            return dt.tzinfo._tzname
+        else:
+            return self._tzname
+
+    def __repr__(self):
+        if self._dst:
+            dst = 'DST'
+        else:
+            dst = 'STD'
+        if self._utcoffset > _notime:
+            return '<DstTzInfo %r %s+%s %s>' % (
+                    self.zone, self._tzname, self._utcoffset, dst
+                )
+        else:
+            return '<DstTzInfo %r %s%s %s>' % (
+                    self.zone, self._tzname, self._utcoffset, dst
+                )
+
+    def __reduce__(self):
+        # Special pickle to zone remains a singleton and to cope with
+        # database changes.
+        return pytz._p, (
+                self.zone,
+                _to_seconds(self._utcoffset),
+                _to_seconds(self._dst),
+                self._tzname
+                )
+
+
+
+def unpickler(zone, utcoffset=None, dstoffset=None, tzname=None):
+    """Factory function for unpickling pytz tzinfo instances.
+
+    This is shared for both StaticTzInfo and DstTzInfo instances, because
+    database changes could cause a zones implementation to switch between
+    these two base classes and we can't break pickles on a pytz version
+    upgrade.
+    """
+    # Raises a KeyError if zone no longer exists, which should never happen
+    # and would be a bug.
+    tz = pytz.timezone(zone)
+
+    # A StaticTzInfo - just return it
+    if utcoffset is None:
+        return tz
+
+    # This pickle was created from a DstTzInfo. We need to
+    # determine which of the list of tzinfo instances for this zone
+    # to use in order to restore the state of any datetime instances using
+    # it correctly.
+    utcoffset = memorized_timedelta(utcoffset)
+    dstoffset = memorized_timedelta(dstoffset)
+    try:
+        return tz._tzinfos[(utcoffset, dstoffset, tzname)]
+    except KeyError:
+        # The particular state requested in this timezone no longer exists.
+        # This indicates a corrupt pickle, or the timezone database has been
+        # corrected violently enough to make this particular
+        # (utcoffset,dstoffset) no longer exist in the zone, or the
+        # abbreviation has been changed.
+        pass
+
+    # See if we can find an entry differing only by tzname. Abbreviations
+    # get changed from the initial guess by the database maintainers to
+    # match reality when this information is discovered.
+    for localized_tz in tz._tzinfos.values():
+        if (localized_tz._utcoffset == utcoffset
+                and localized_tz._dst == dstoffset):
+            return localized_tz
+
+    # This (utcoffset, dstoffset) information has been removed from the
+    # zone. Add it back. This might occur when the database maintainers have
+    # corrected incorrect information. datetime instances using this
+    # incorrect information will continue to do so, exactly as they were
+    # before being pickled. This is purely an overly paranoid safety net - I
+    # doubt this will ever been needed in real life.
+    inf = (utcoffset, dstoffset, tzname)
+    tz._tzinfos[inf] = tz.__class__(inf, tz._tzinfos)
+    return tz._tzinfos[inf]
+

BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Abidjan


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Accra


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Addis_Ababa


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Algiers


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Asmara


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Asmera


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Bamako


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Bangui


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Banjul


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Bissau


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Blantyre


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Brazzaville


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Bujumbura


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Cairo


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Casablanca


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Ceuta


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Conakry


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Dakar


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Dar_es_Salaam


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Djibouti


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Douala


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/El_Aaiun


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Freetown


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Gaborone


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Harare


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Johannesburg


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Juba


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Kampala


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Khartoum


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Kigali


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Kinshasa


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Lagos


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Libreville


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Lome


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Luanda


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Lubumbashi


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Lusaka


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Malabo


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Maputo


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Maseru


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Mbabane


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Mogadishu


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Monrovia


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Nairobi


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Ndjamena


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Niamey


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Nouakchott


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Ouagadougou


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Porto-Novo


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Sao_Tome


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Timbuktu


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Tripoli


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Tunis


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/Africa/Windhoek


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Adak


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Anchorage


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Anguilla


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Antigua


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Araguaina


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Buenos_Aires


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Catamarca


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/ComodRivadavia


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Cordoba


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Jujuy


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/La_Rioja


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Mendoza


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Rio_Gallegos


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Salta


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/San_Juan


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/San_Luis


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Tucuman


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Argentina/Ushuaia


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Aruba


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Asuncion


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Atikokan


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Atka


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Bahia


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Bahia_Banderas


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Barbados


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Belem


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Belize


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Blanc-Sablon


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Boa_Vista


BIN
desktop/core/ext-py/pytz-2013.9/pytz/zoneinfo/America/Bogota


Vissa filer visades inte eftersom för många filer har ändrats