Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What Time is it Anyway

Greg Back
February 05, 2017

What Time is it Anyway

PyTennessee 2017

Greg Back

February 05, 2017
Tweet

More Decks by Greg Back

Other Decks in Programming

Transcript

  1. Dates and Times in Python Greg Back PyTennessee 2017 2017-02-05

    13:00:00-06:00 What Time is it Anyway? gtback @gtback
  2. Why is telling time important? 1. When did something happen?

    2. How long did something take/last? 3. When will something happen? 4. Which happened (or will happen) first?
  3. Time Zone vs. Time Zone Offset • Time Zone is

    a place (geographical region) • Time Zone Offset is a number (difference from UTC) Timestamps with an offset are about both WHEN and WHERE
  4. There is only one time zone for each time zone

    offset. False America/Chicago in Summer (CDT): UTC-05:00 America/New_York in Winter (EST): UTC-05:00
  5. There is only one time zone offset for each time

    zone. False America/Chicago in Summer (CDT): UTC-05:00 America/Chicago in Winter (CST): UTC-06:00
  6. Each time zone offset differs by a whole number of

    hours. False Asia/Kabul (Afghanistan): UTC+04:30 Asia/Kolkata (India): UTC+05:30 Asia/Pyongyang (North Korea): UTC+08:30
  7. Each time zone offset differs by whole or half hours.

    False Asia/Kathmandu (Nepal): UTC+05:45
  8. Notation: Time-related stdlib modules datetime - Basic date and time

    types time - Time access and conversions calendar - General calendar-related functions module class/type function
  9. Time-related data types datetime.time datetime.date datetime.datetime datetime.timedelta datetime.tzinfo time.struct_time ordinal

    (int) • day of Common Era (CE) • 1 = January 1, year 1 timestamp (float) • seconds since Epoch • 0 = Jan 1, 1970 at 00:00 string (str) • for humans • LOTS of formats!
  10. Date String Formats 2017-02-05T13:00:00-06:00 Sun, 05 Feb 2017 19:00:00 GMT

    February 5, 2017 1:00 PM Sun Feb 5 13:00:00 2017 5 Feb 2017 1900Z
  11. Tip #0: Rename Imports import datetime as dt import time

    as tm import calendar as cal • Distinguish modules from types • NOTE: Personal preference
  12. Conversions struct_time timestamp string tm.ctime(x) tm.strptime(x, FMT) LOCAL: tm.localtime(x) UTC:

    tm.gmtime(x) LOCAL: tm.mktime(x) UTC: cal.timegm(x) tm.asctime(x) tm.strftime(FMT, x) tm.time() LOCAL: tm.localtime() UTC: tm.gmtime() tm.ctime() tm.asctime() tm.strftime(FMT)
  13. * x.ctime() not defined for time Conversions datetime string }

    datetime.strptime(FMT, x) str(x) format(x, FMT) x.isoformat() x.strftime(FMT) x.ctime()* date time datetime(y, m, d, H, M, S, µs, tzinfo) datetime.now([tz]) datetime.utcnow() ...
  14. AWARE and NAIVE datetimes def is_aware(d): return d.tzinfo is not

    None • datetime.now() and datetime.utcnow() both return NAIVE datetimes. • django.utils.now() returns: AWARE if settings.USE_TZ else NAIVE
  15. • NAIVE timestamps could be: ◦ UTC ◦ system time

    ◦ ¯\_(ツ)_/¯ • Most database, network, etc. libraries handle AWARE timestamps correctly Tip #1 - Always be AWARE Naive objects are easy to understand and to work with, at the cost of ignoring some aspects of reality. “ ” https://docs.python.org/3/library/datetime.html
  16. pytz - Timezone Info objects • pytz contains subclasses of

    dt.tzinfo utz = pytz.UTC central = pytz.timezone("America/Chicago") pacific = pytz.timezone("America/Los_Angeles") eastern = pytz.timezone("America/New_York")
  17. Using pytz <datetime>.astimezone(<dt.tzinfo>) • Convert AWARE datetime from one timezone

    to another ◦ May change hour/minute values <pytz BaseTzInfo>.localize(<datetime>) • Add tzinfo to NAIVE datetime ◦ Does not replace hour/minute values
  18. Date String Formats 2017-02-05T13:00:00-06:00 Sun, 05 Feb 2017 19:00:00 GMT

    February 5, 2017 1:00 PM Sun Feb 5 13:00:00 2017 5 Feb 2017 1900Z
  19. Parsing with python-dateutil from dateutil.parser import parse iso = parse("2017-02-05T13:00:00-06:00")

    rfc = parse("Sun, 05 Feb 2017 19:00:00 GMT") us = central.localize(parse("February 5, 2017 1:00 PM")) ctime = central.localize(parse("Sun Feb 5 13:00:00 2017")) military = parse("5 Feb 2017 1900Z") NAIVE NAIVE AWARE AWARE AWARE
  20. Parsing with python-dateutil from dateutil.parser import parse iso = parse("2017-02-05T13:00:00-06:00")

    rfc = parse("Sun, 05 Feb 2017 19:00:00 GMT") us = central.localize(parse("February 5, 2017 1:00 PM")) ctime = central.localize(parse("Sun Feb 5 13:00:00 2017")) military = parse("5 Feb 2017 1900Z") assert iso == rfc == us == ctime == military
  21. Tip #2 - I SO want you to use ISO

    Use ISO format for date strings. >>> now = dt.datetime(...) >>> now.isoformat() "2017-02-05T13:00:00-06:00" >>> str(now) "2017-02-05 13:00:00-06:00"
  22. Tip #3: Sort dates as UTC What order did these

    events occur in? A) 2017-02-05 08:55:42-08:00 B) 2017-02-05 10:29:17-06:00 C) 2017-02-05 11:07:03-05:00
  23. Tip #3: Sort dates as UTC What order did these

    events occur in? A) 2017-02-05 16:55:42+00:00 B) 2017-02-05 16:29:17+00:00 C) 2017-02-05 16:07:03+00:00
  24. Tip #4 - UTC "Sandwich" A. Convert incoming timestamps to

    UTC as soon as possible. B. Localize for user as late as possible. a. (And only if necessary.) C. Store/compare/manipulate times as UTC throughout system.
  25. UTC Sandwich Exceptions #1 If ALL the following are true:

    A. All timestamps are generated in the same time zone. B. Your users are in the same time zone. C. You don't care about daylight saving time. D. There's never a chance A, B, or C will change.
  26. UTC Sandwich Exceptions #1 If ALL the following are true:

    A. All timestamps are generated in the same time zone. B. Your users are in the same time zone. C. You don't care about daylight saving time. D. There's never a chance A-C will change.
  27. UTC Sandwich Exceptions #2 If you want to keep information

    about the time zone where the timestamp was created. PyTN 2017 Keynote: 2017-02-04 09:00:00-06:00 PyCon 2017 Keynote: 2017-05-19 09:00:00-07:00 PyOhio 2017 Keynote: 2017-07-29 09:00:00-04:00
  28. UTC Sandwich Exceptions #2 If you want to keep some

    reference to the time zone where the timestamp was created. PyTN 2017 Keynote: 2017-02-04 09:00:00-06:00 PyCon 2017 Keynote: 2017-05-19 09:00:00-07:00 PyOhio 2017 Keynote: 2017-07-29 09:00:00-04:00 PREFERRED: Keep separate time zone data (e.g. django-timezone-field) OK
  29. UTC Sandwich Exceptions #3 If you want to keep a

    recurring event at the same local time across daylight saving time: >>> startdt = central.localize(dt.datetime(2017, 2, 5, 13)) >>> for week in range(2, 6): ... instance = startdt + dt.timedelta(days=7*week) ... print(instance.astimezone(central)) 2017-02-19 13:00:00-06:00 ✔ 2017-02-26 13:00:00-06:00 ✔ 2017-03-05 13:00:00-06:00 ✔ 2017-03-12 14:00:00-05:00 ✘
  30. UTC Sandwich Exceptions #3 If you want to keep a

    recurring event at the same local time across daylight saving time: >>> start_date, start_time = dt.date(2017, 2, 5), dt.time(13) >>> for week in range(2, 6): ... date = start_date + dt.timedelta(days=7*week) ... instance = dt.datetime.combine(date, start_time) ... print(central.localize(instance)) 2017-02-19 13:00:00-06:00 ✔ 2017-02-26 13:00:00-06:00 ✔ 2017-03-05 13:00:00-06:00 ✔ 2017-03-12 13:00:00-05:00 ✔
  31. But what about….? Other datetime libraries: • Delorean - http://delorean.readthedocs.io/

    • Arrow - http://crsmithdev.com/arrow/ • Pendulum - https://pendulum.eustace.io/ • Maya - https://github.com/kennethreitz/maya
  32. Python Date & Time Tips 1. Always be AWARE 2.

    Use ISO Format for Date Strings 3. Normalize to UTC before sorting date strings 4. UTC Sandwich gtback @gtback Questions?
  33. Image Credits • Sundial: https://commons.wikimedia.org/wiki/File:Sundial_2r.jpg. By liz west (Sundial) [CC

    BY 2.0], via Wikimedia Commons. • Watch: https://commons.wikimedia.org/wiki/File:Naturejournal36londuoft_0523.jpg. By "Nature" ("Nature" journal, September 22, 1887, pp. 485) [Public domain], via Wikimedia Commons. • Train & Clock: https://pixabay.com/en/old-vintage-retro-locomotive-train-952238/. By ArtsyBee [CC0]. • Time Zone Map: https://commons.wikimedia.org/wiki/File:Standard_World_Time_Zones.png. By TimeZonesBoy (Own work) [CC BY-SA 4.0], via Wikimedia Commons. • Atomic Clock: https://commons.wikimedia.org/wiki/File:Atomic_Clock-Louis_Essen.jpg. By National Physical Laboratory [Public domain], via Wikimedia Commons. • Date Time Formats: https://xkcd.com/1179/. By Randall Munroe [CC BY-NC 2.5]. • Iceberg: https://commons.wikimedia.org/wiki/File:Wikisource-logo.svg. By Nicholas Moreau [CC BY-SA 3.0], via Wikimedia Commons.