1Metadata-Version: 2.1 2Name: pytz 3Version: 2021.3 4Summary: World timezone definitions, modern and historical 5Home-page: http://pythonhosted.org/pytz 6Author: Stuart Bishop 7Author-email: stuart@stuartbishop.net 8Maintainer: Stuart Bishop 9Maintainer-email: stuart@stuartbishop.net 10License: MIT 11Download-URL: https://pypi.org/project/pytz/ 12Keywords: timezone,tzinfo,datetime,olson,time 13Platform: Independent 14Classifier: Development Status :: 6 - Mature 15Classifier: Intended Audience :: Developers 16Classifier: License :: OSI Approved :: MIT License 17Classifier: Natural Language :: English 18Classifier: Operating System :: OS Independent 19Classifier: Programming Language :: Python 20Classifier: Programming Language :: Python :: 2 21Classifier: Programming Language :: Python :: 2.4 22Classifier: Programming Language :: Python :: 2.5 23Classifier: Programming Language :: Python :: 2.6 24Classifier: Programming Language :: Python :: 2.7 25Classifier: Programming Language :: Python :: 3 26Classifier: Programming Language :: Python :: 3.1 27Classifier: Programming Language :: Python :: 3.2 28Classifier: Programming Language :: Python :: 3.3 29Classifier: Programming Language :: Python :: 3.4 30Classifier: Programming Language :: Python :: 3.5 31Classifier: Programming Language :: Python :: 3.6 32Classifier: Programming Language :: Python :: 3.7 33Classifier: Programming Language :: Python :: 3.8 34Classifier: Programming Language :: Python :: 3.9 35Classifier: Topic :: Software Development :: Libraries :: Python Modules 36License-File: LICENSE.txt 37 38pytz - World Timezone Definitions for Python 39============================================ 40 41:Author: Stuart Bishop <stuart@stuartbishop.net> 42 43Introduction 44~~~~~~~~~~~~ 45 46pytz brings the Olson tz database into Python. This library allows 47accurate and cross platform timezone calculations using Python 2.4 48or higher. It also solves the issue of ambiguous times at the end 49of daylight saving time, which you can read more about in the Python 50Library Reference (``datetime.tzinfo``). 51 52Almost all of the Olson timezones are supported. 53 54.. note:: 55 56 This library differs from the documented Python API for 57 tzinfo implementations; if you want to create local wallclock 58 times you need to use the ``localize()`` method documented in this 59 document. In addition, if you perform date arithmetic on local 60 times that cross DST boundaries, the result may be in an incorrect 61 timezone (ie. subtract 1 minute from 2002-10-27 1:00 EST and you get 62 2002-10-27 0:59 EST instead of the correct 2002-10-27 1:59 EDT). A 63 ``normalize()`` method is provided to correct this. Unfortunately these 64 issues cannot be resolved without modifying the Python datetime 65 implementation (see PEP-431). 66 67 68Installation 69~~~~~~~~~~~~ 70 71This package can either be installed using ``pip`` or from a tarball using the 72standard Python distutils. 73 74If you are installing using ``pip``, you don't need to download anything as the 75latest version will be downloaded for you from PyPI:: 76 77 pip install pytz 78 79If you are installing from a tarball, run the following command as an 80administrative user:: 81 82 python setup.py install 83 84 85pytz for Enterprise 86~~~~~~~~~~~~~~~~~~~ 87 88Available as part of the Tidelift Subscription. 89 90The maintainers of pytz and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. `Learn more. <https://tidelift.com/subscription/pkg/pypi-pytz?utm_source=pypi-pytz&utm_medium=referral&utm_campaign=enterprise&utm_term=repo>`_. 91 92 93Example & Usage 94~~~~~~~~~~~~~~~ 95 96Localized times and date arithmetic 97----------------------------------- 98 99>>> from datetime import datetime, timedelta 100>>> from pytz import timezone 101>>> import pytz 102>>> utc = pytz.utc 103>>> utc.zone 104'UTC' 105>>> eastern = timezone('US/Eastern') 106>>> eastern.zone 107'US/Eastern' 108>>> amsterdam = timezone('Europe/Amsterdam') 109>>> fmt = '%Y-%m-%d %H:%M:%S %Z%z' 110 111This library only supports two ways of building a localized time. The 112first is to use the ``localize()`` method provided by the pytz library. 113This is used to localize a naive datetime (datetime with no timezone 114information): 115 116>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0)) 117>>> print(loc_dt.strftime(fmt)) 1182002-10-27 06:00:00 EST-0500 119 120The second way of building a localized time is by converting an existing 121localized time using the standard ``astimezone()`` method: 122 123>>> ams_dt = loc_dt.astimezone(amsterdam) 124>>> ams_dt.strftime(fmt) 125'2002-10-27 12:00:00 CET+0100' 126 127Unfortunately using the tzinfo argument of the standard datetime 128constructors ''does not work'' with pytz for many timezones. 129 130>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt) # /!\ Does not work this way! 131'2002-10-27 12:00:00 LMT+0020' 132 133It is safe for timezones without daylight saving transitions though, such 134as UTC: 135 136>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=pytz.utc).strftime(fmt) # /!\ Not recommended except for UTC 137'2002-10-27 12:00:00 UTC+0000' 138 139The preferred way of dealing with times is to always work in UTC, 140converting to localtime only when generating output to be read 141by humans. 142 143>>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc) 144>>> loc_dt = utc_dt.astimezone(eastern) 145>>> loc_dt.strftime(fmt) 146'2002-10-27 01:00:00 EST-0500' 147 148This library also allows you to do date arithmetic using local 149times, although it is more complicated than working in UTC as you 150need to use the ``normalize()`` method to handle daylight saving time 151and other timezone transitions. In this example, ``loc_dt`` is set 152to the instant when daylight saving time ends in the US/Eastern 153timezone. 154 155>>> before = loc_dt - timedelta(minutes=10) 156>>> before.strftime(fmt) 157'2002-10-27 00:50:00 EST-0500' 158>>> eastern.normalize(before).strftime(fmt) 159'2002-10-27 01:50:00 EDT-0400' 160>>> after = eastern.normalize(before + timedelta(minutes=20)) 161>>> after.strftime(fmt) 162'2002-10-27 01:10:00 EST-0500' 163 164Creating local times is also tricky, and the reason why working with 165local times is not recommended. Unfortunately, you cannot just pass 166a ``tzinfo`` argument when constructing a datetime (see the next 167section for more details) 168 169>>> dt = datetime(2002, 10, 27, 1, 30, 0) 170>>> dt1 = eastern.localize(dt, is_dst=True) 171>>> dt1.strftime(fmt) 172'2002-10-27 01:30:00 EDT-0400' 173>>> dt2 = eastern.localize(dt, is_dst=False) 174>>> dt2.strftime(fmt) 175'2002-10-27 01:30:00 EST-0500' 176 177Converting between timezones is more easily done, using the 178standard astimezone method. 179 180>>> utc_dt = utc.localize(datetime.utcfromtimestamp(1143408899)) 181>>> utc_dt.strftime(fmt) 182'2006-03-26 21:34:59 UTC+0000' 183>>> au_tz = timezone('Australia/Sydney') 184>>> au_dt = utc_dt.astimezone(au_tz) 185>>> au_dt.strftime(fmt) 186'2006-03-27 08:34:59 AEDT+1100' 187>>> utc_dt2 = au_dt.astimezone(utc) 188>>> utc_dt2.strftime(fmt) 189'2006-03-26 21:34:59 UTC+0000' 190>>> utc_dt == utc_dt2 191True 192 193You can take shortcuts when dealing with the UTC side of timezone 194conversions. ``normalize()`` and ``localize()`` are not really 195necessary when there are no daylight saving time transitions to 196deal with. 197 198>>> utc_dt = datetime.utcfromtimestamp(1143408899).replace(tzinfo=utc) 199>>> utc_dt.strftime(fmt) 200'2006-03-26 21:34:59 UTC+0000' 201>>> au_tz = timezone('Australia/Sydney') 202>>> au_dt = au_tz.normalize(utc_dt.astimezone(au_tz)) 203>>> au_dt.strftime(fmt) 204'2006-03-27 08:34:59 AEDT+1100' 205>>> utc_dt2 = au_dt.astimezone(utc) 206>>> utc_dt2.strftime(fmt) 207'2006-03-26 21:34:59 UTC+0000' 208 209 210``tzinfo`` API 211-------------- 212 213The ``tzinfo`` instances returned by the ``timezone()`` function have 214been extended to cope with ambiguous times by adding an ``is_dst`` 215parameter to the ``utcoffset()``, ``dst()`` && ``tzname()`` methods. 216 217>>> tz = timezone('America/St_Johns') 218 219>>> normal = datetime(2009, 9, 1) 220>>> ambiguous = datetime(2009, 10, 31, 23, 30) 221 222The ``is_dst`` parameter is ignored for most timestamps. It is only used 223during DST transition ambiguous periods to resolve that ambiguity. 224 225>>> print(tz.utcoffset(normal, is_dst=True)) 226-1 day, 21:30:00 227>>> print(tz.dst(normal, is_dst=True)) 2281:00:00 229>>> tz.tzname(normal, is_dst=True) 230'NDT' 231 232>>> print(tz.utcoffset(ambiguous, is_dst=True)) 233-1 day, 21:30:00 234>>> print(tz.dst(ambiguous, is_dst=True)) 2351:00:00 236>>> tz.tzname(ambiguous, is_dst=True) 237'NDT' 238 239>>> print(tz.utcoffset(normal, is_dst=False)) 240-1 day, 21:30:00 241>>> tz.dst(normal, is_dst=False).seconds 2423600 243>>> tz.tzname(normal, is_dst=False) 244'NDT' 245 246>>> print(tz.utcoffset(ambiguous, is_dst=False)) 247-1 day, 20:30:00 248>>> tz.dst(ambiguous, is_dst=False) 249datetime.timedelta(0) 250>>> tz.tzname(ambiguous, is_dst=False) 251'NST' 252 253If ``is_dst`` is not specified, ambiguous timestamps will raise 254an ``pytz.exceptions.AmbiguousTimeError`` exception. 255 256>>> print(tz.utcoffset(normal)) 257-1 day, 21:30:00 258>>> print(tz.dst(normal)) 2591:00:00 260>>> tz.tzname(normal) 261'NDT' 262 263>>> import pytz.exceptions 264>>> try: 265... tz.utcoffset(ambiguous) 266... except pytz.exceptions.AmbiguousTimeError: 267... print('pytz.exceptions.AmbiguousTimeError: %s' % ambiguous) 268pytz.exceptions.AmbiguousTimeError: 2009-10-31 23:30:00 269>>> try: 270... tz.dst(ambiguous) 271... except pytz.exceptions.AmbiguousTimeError: 272... print('pytz.exceptions.AmbiguousTimeError: %s' % ambiguous) 273pytz.exceptions.AmbiguousTimeError: 2009-10-31 23:30:00 274>>> try: 275... tz.tzname(ambiguous) 276... except pytz.exceptions.AmbiguousTimeError: 277... print('pytz.exceptions.AmbiguousTimeError: %s' % ambiguous) 278pytz.exceptions.AmbiguousTimeError: 2009-10-31 23:30:00 279 280 281Problems with Localtime 282~~~~~~~~~~~~~~~~~~~~~~~ 283 284The major problem we have to deal with is that certain datetimes 285may occur twice in a year. For example, in the US/Eastern timezone 286on the last Sunday morning in October, the following sequence 287happens: 288 289 - 01:00 EDT occurs 290 - 1 hour later, instead of 2:00am the clock is turned back 1 hour 291 and 01:00 happens again (this time 01:00 EST) 292 293In fact, every instant between 01:00 and 02:00 occurs twice. This means 294that if you try and create a time in the 'US/Eastern' timezone 295the standard datetime syntax, there is no way to specify if you meant 296before of after the end-of-daylight-saving-time transition. Using the 297pytz custom syntax, the best you can do is make an educated guess: 298 299>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 1, 30, 00)) 300>>> loc_dt.strftime(fmt) 301'2002-10-27 01:30:00 EST-0500' 302 303As you can see, the system has chosen one for you and there is a 50% 304chance of it being out by one hour. For some applications, this does 305not matter. However, if you are trying to schedule meetings with people 306in different timezones or analyze log files it is not acceptable. 307 308The best and simplest solution is to stick with using UTC. The pytz 309package encourages using UTC for internal timezone representation by 310including a special UTC implementation based on the standard Python 311reference implementation in the Python documentation. 312 313The UTC timezone unpickles to be the same instance, and pickles to a 314smaller size than other pytz tzinfo instances. The UTC implementation 315can be obtained as pytz.utc, pytz.UTC, or pytz.timezone('UTC'). 316 317>>> import pickle, pytz 318>>> dt = datetime(2005, 3, 1, 14, 13, 21, tzinfo=utc) 319>>> naive = dt.replace(tzinfo=None) 320>>> p = pickle.dumps(dt, 1) 321>>> naive_p = pickle.dumps(naive, 1) 322>>> len(p) - len(naive_p) 32317 324>>> new = pickle.loads(p) 325>>> new == dt 326True 327>>> new is dt 328False 329>>> new.tzinfo is dt.tzinfo 330True 331>>> pytz.utc is pytz.UTC is pytz.timezone('UTC') 332True 333 334Note that some other timezones are commonly thought of as the same (GMT, 335Greenwich, Universal, etc.). The definition of UTC is distinct from these 336other timezones, and they are not equivalent. For this reason, they will 337not compare the same in Python. 338 339>>> utc == pytz.timezone('GMT') 340False 341 342See the section `What is UTC`_, below. 343 344If you insist on working with local times, this library provides a 345facility for constructing them unambiguously: 346 347>>> loc_dt = datetime(2002, 10, 27, 1, 30, 00) 348>>> est_dt = eastern.localize(loc_dt, is_dst=True) 349>>> edt_dt = eastern.localize(loc_dt, is_dst=False) 350>>> print(est_dt.strftime(fmt) + ' / ' + edt_dt.strftime(fmt)) 3512002-10-27 01:30:00 EDT-0400 / 2002-10-27 01:30:00 EST-0500 352 353If you pass None as the is_dst flag to localize(), pytz will refuse to 354guess and raise exceptions if you try to build ambiguous or non-existent 355times. 356 357For example, 1:30am on 27th Oct 2002 happened twice in the US/Eastern 358timezone when the clocks where put back at the end of Daylight Saving 359Time: 360 361>>> dt = datetime(2002, 10, 27, 1, 30, 00) 362>>> try: 363... eastern.localize(dt, is_dst=None) 364... except pytz.exceptions.AmbiguousTimeError: 365... print('pytz.exceptions.AmbiguousTimeError: %s' % dt) 366pytz.exceptions.AmbiguousTimeError: 2002-10-27 01:30:00 367 368Similarly, 2:30am on 7th April 2002 never happened at all in the 369US/Eastern timezone, as the clocks where put forward at 2:00am skipping 370the entire hour: 371 372>>> dt = datetime(2002, 4, 7, 2, 30, 00) 373>>> try: 374... eastern.localize(dt, is_dst=None) 375... except pytz.exceptions.NonExistentTimeError: 376... print('pytz.exceptions.NonExistentTimeError: %s' % dt) 377pytz.exceptions.NonExistentTimeError: 2002-04-07 02:30:00 378 379Both of these exceptions share a common base class to make error handling 380easier: 381 382>>> isinstance(pytz.AmbiguousTimeError(), pytz.InvalidTimeError) 383True 384>>> isinstance(pytz.NonExistentTimeError(), pytz.InvalidTimeError) 385True 386 387 388A special case is where countries change their timezone definitions 389with no daylight savings time switch. For example, in 1915 Warsaw 390switched from Warsaw time to Central European time with no daylight savings 391transition. So at the stroke of midnight on August 5th 1915 the clocks 392were wound back 24 minutes creating an ambiguous time period that cannot 393be specified without referring to the timezone abbreviation or the 394actual UTC offset. In this case midnight happened twice, neither time 395during a daylight saving time period. pytz handles this transition by 396treating the ambiguous period before the switch as daylight savings 397time, and the ambiguous period after as standard time. 398 399 400>>> warsaw = pytz.timezone('Europe/Warsaw') 401>>> amb_dt1 = warsaw.localize(datetime(1915, 8, 4, 23, 59, 59), is_dst=True) 402>>> amb_dt1.strftime(fmt) 403'1915-08-04 23:59:59 WMT+0124' 404>>> amb_dt2 = warsaw.localize(datetime(1915, 8, 4, 23, 59, 59), is_dst=False) 405>>> amb_dt2.strftime(fmt) 406'1915-08-04 23:59:59 CET+0100' 407>>> switch_dt = warsaw.localize(datetime(1915, 8, 5, 00, 00, 00), is_dst=False) 408>>> switch_dt.strftime(fmt) 409'1915-08-05 00:00:00 CET+0100' 410>>> str(switch_dt - amb_dt1) 411'0:24:01' 412>>> str(switch_dt - amb_dt2) 413'0:00:01' 414 415The best way of creating a time during an ambiguous time period is 416by converting from another timezone such as UTC: 417 418>>> utc_dt = datetime(1915, 8, 4, 22, 36, tzinfo=pytz.utc) 419>>> utc_dt.astimezone(warsaw).strftime(fmt) 420'1915-08-04 23:36:00 CET+0100' 421 422The standard Python way of handling all these ambiguities is not to 423handle them, such as demonstrated in this example using the US/Eastern 424timezone definition from the Python documentation (Note that this 425implementation only works for dates between 1987 and 2006 - it is 426included for tests only!): 427 428>>> from pytz.reference import Eastern # pytz.reference only for tests 429>>> dt = datetime(2002, 10, 27, 0, 30, tzinfo=Eastern) 430>>> str(dt) 431'2002-10-27 00:30:00-04:00' 432>>> str(dt + timedelta(hours=1)) 433'2002-10-27 01:30:00-05:00' 434>>> str(dt + timedelta(hours=2)) 435'2002-10-27 02:30:00-05:00' 436>>> str(dt + timedelta(hours=3)) 437'2002-10-27 03:30:00-05:00' 438 439Notice the first two results? At first glance you might think they are 440correct, but taking the UTC offset into account you find that they are 441actually two hours appart instead of the 1 hour we asked for. 442 443>>> from pytz.reference import UTC # pytz.reference only for tests 444>>> str(dt.astimezone(UTC)) 445'2002-10-27 04:30:00+00:00' 446>>> str((dt + timedelta(hours=1)).astimezone(UTC)) 447'2002-10-27 06:30:00+00:00' 448 449 450Country Information 451~~~~~~~~~~~~~~~~~~~ 452 453A mechanism is provided to access the timezones commonly in use 454for a particular country, looked up using the ISO 3166 country code. 455It returns a list of strings that can be used to retrieve the relevant 456tzinfo instance using ``pytz.timezone()``: 457 458>>> print(' '.join(pytz.country_timezones['nz'])) 459Pacific/Auckland Pacific/Chatham 460 461The Olson database comes with a ISO 3166 country code to English country 462name mapping that pytz exposes as a dictionary: 463 464>>> print(pytz.country_names['nz']) 465New Zealand 466 467 468What is UTC 469~~~~~~~~~~~ 470 471'UTC' is `Coordinated Universal Time`_. It is a successor to, but distinct 472from, Greenwich Mean Time (GMT) and the various definitions of Universal 473Time. UTC is now the worldwide standard for regulating clocks and time 474measurement. 475 476All other timezones are defined relative to UTC, and include offsets like 477UTC+0800 - hours to add or subtract from UTC to derive the local time. No 478daylight saving time occurs in UTC, making it a useful timezone to perform 479date arithmetic without worrying about the confusion and ambiguities caused 480by daylight saving time transitions, your country changing its timezone, or 481mobile computers that roam through multiple timezones. 482 483.. _Coordinated Universal Time: https://en.wikipedia.org/wiki/Coordinated_Universal_Time 484 485 486Helpers 487~~~~~~~ 488 489There are two lists of timezones provided. 490 491``all_timezones`` is the exhaustive list of the timezone names that can 492be used. 493 494>>> from pytz import all_timezones 495>>> len(all_timezones) >= 500 496True 497>>> 'Etc/Greenwich' in all_timezones 498True 499 500``common_timezones`` is a list of useful, current timezones. It doesn't 501contain deprecated zones or historical zones, except for a few I've 502deemed in common usage, such as US/Eastern (open a bug report if you 503think other timezones are deserving of being included here). It is also 504a sequence of strings. 505 506>>> from pytz import common_timezones 507>>> len(common_timezones) < len(all_timezones) 508True 509>>> 'Etc/Greenwich' in common_timezones 510False 511>>> 'Australia/Melbourne' in common_timezones 512True 513>>> 'US/Eastern' in common_timezones 514True 515>>> 'Canada/Eastern' in common_timezones 516True 517>>> 'Australia/Yancowinna' in all_timezones 518True 519>>> 'Australia/Yancowinna' in common_timezones 520False 521 522Both ``common_timezones`` and ``all_timezones`` are alphabetically 523sorted: 524 525>>> common_timezones_dupe = common_timezones[:] 526>>> common_timezones_dupe.sort() 527>>> common_timezones == common_timezones_dupe 528True 529>>> all_timezones_dupe = all_timezones[:] 530>>> all_timezones_dupe.sort() 531>>> all_timezones == all_timezones_dupe 532True 533 534``all_timezones`` and ``common_timezones`` are also available as sets. 535 536>>> from pytz import all_timezones_set, common_timezones_set 537>>> 'US/Eastern' in all_timezones_set 538True 539>>> 'US/Eastern' in common_timezones_set 540True 541>>> 'Australia/Victoria' in common_timezones_set 542False 543 544You can also retrieve lists of timezones used by particular countries 545using the ``country_timezones()`` function. It requires an ISO-3166 546two letter country code. 547 548>>> from pytz import country_timezones 549>>> print(' '.join(country_timezones('ch'))) 550Europe/Zurich 551>>> print(' '.join(country_timezones('CH'))) 552Europe/Zurich 553 554 555Internationalization - i18n/l10n 556~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 557 558Pytz is an interface to the IANA database, which uses ASCII names. The `Unicode Consortium's Unicode Locales (CLDR) <http://cldr.unicode.org>`_ 559project provides translations. Thomas Khyn's 560`l18n <https://pypi.org/project/l18n/>`_ package can be used to access 561these translations from Python. 562 563 564License 565~~~~~~~ 566 567MIT license. 568 569This code is also available as part of Zope 3 under the Zope Public 570License, Version 2.1 (ZPL). 571 572I'm happy to relicense this code if necessary for inclusion in other 573open source projects. 574 575 576Latest Versions 577~~~~~~~~~~~~~~~ 578 579This package will be updated after releases of the Olson timezone 580database. The latest version can be downloaded from the `Python Package 581Index <https://pypi.org/project/pytz/>`_. The code that is used 582to generate this distribution is hosted on launchpad.net and available 583using git:: 584 585 git clone https://git.launchpad.net/pytz 586 587A mirror on github is also available at https://github.com/stub42/pytz 588 589Announcements of new releases are made on 590`Launchpad <https://launchpad.net/pytz>`_, and the 591`Atom feed <http://feeds.launchpad.net/pytz/announcements.atom>`_ 592hosted there. 593 594 595Bugs, Feature Requests & Patches 596~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 597 598Bugs can be reported using `Launchpad Bugs <https://bugs.launchpad.net/pytz>`_. 599 600 601Security Issues 602~~~~~~~~~~~~~~~ 603 604Reports about security issues can be made via `Tidelift <https://tidelift.com/security>`_. 605 606 607Issues & Limitations 608~~~~~~~~~~~~~~~~~~~~ 609 610- Offsets from UTC are rounded to the nearest whole minute, so timezones 611 such as Europe/Amsterdam pre 1937 will be up to 30 seconds out. This 612 is a limitation of the Python datetime library. 613 614- If you think a timezone definition is incorrect, I probably can't fix 615 it. pytz is a direct translation of the Olson timezone database, and 616 changes to the timezone definitions need to be made to this source. 617 If you find errors they should be reported to the time zone mailing 618 list, linked from http://www.iana.org/time-zones. 619 620 621Further Reading 622~~~~~~~~~~~~~~~ 623 624More info than you want to know about timezones: 625http://www.twinsun.com/tz/tz-link.htm 626 627 628Contact 629~~~~~~~ 630 631Stuart Bishop <stuart@stuartbishop.net> 632 633 634 635 636