Giter Site home page Giter Site logo

suretime's Introduction

suretime

Version status License Python version compatibility Version on GitHub Version on PyPi Build (GitHub Actions) Test coverage (coveralls) Maintainability (Code Climate) Code Quality (Scrutinizer) Created with Tyrannosaurus

Map nonstandard timezones to IANA zones on all platforms. Record timestamps and intervals that behave correctly, even if the timezone changes in the middle of a calculation. pip install suretime tzdata.

Timezone mapping

To get the local zone in IANA:

import suretime
from datetime import datetime

datetime.now().tzname()  # "Pacific Standard Time"
suretime.zone.first_local()  # ZoneInfo[America/Los_Angeles])

To map a nonstandard zone from elsewhere:

import suretime

suretime.zone.only("Europe/Tiraspol")  # ZoneInfo[Europe/Tiraspol]
suretime.zone.first("Central Pacific Standard Time")  # ZoneInfo[Pacific/Guadalcanal]
suretime.zone.first(
    "Central Pacific Standard Time", territory="AQ"
)  # ZoneInfo[Antarctica/Casey]

Note that there is no 1-1 mapping between Windows and IANA timezones, so suretime can fail despite its name.

"Tagged" datetimes and intervals

suretime also has models to represent timestamps and intervals as accurately as the system permits. For example, a TaggedInterval contains the wall time, IANA zone, original (unmapped) timezone info from the system, monotonic (typically boottime) clock time, and the clock used.

Timezone-resolved datetimes and intervals know both real and calendar times, correctly representing the ground truth even if a timezone shift occurs between events – such as from a daylight savings change or the user boarding a flight.

import suretime

tagged = suretime.tag.now()
tagged.to_utc  # TaggedDateTime[...]
tagged.clock.name  # "boottime" on most systems
tagged == tagged  # same point in time
tagged.iso_with_zone  # "2021-01-20T22:24:13.219253-07:00 [America/Los_Angeles]"

Comparison to tzlocal

tzlocal is a bit different. It:

  • ... only handles your current system’s timezone
  • ... is highly OS-specific
  • ... requires many system calls, making it typically much slower
  • ... is compatible with Windows 2000, XP, and 7 and below
  • ... is compatible with Python 3.6, 3.7, and 3.8
  • ... very rarely, can access timezones on incorrectly configured POSIX systems

You can combine both packages, falling back to tzlocal if suretime fails. (See the example below).

Full example

from datetime import datetime
import suretime

# Get your local system, non-IANA timezone
system_time = datetime.now().astimezone()
system_timezone = system_time.tzname()  # e.g. Pacific Standard Time

# Get an IANA timezone instead:
suretime.zone.only_local()  # ZoneInfo[America/Los_Angeles]
# Or for an arbitrary system timezone name:
suretime.zone.first(system_timezone)  # ZoneInfo[America/Los_Angeles]
# Of course, it maps IANA zones to themselves:
suretime.zone.only("America/Los_Angeles")  # ZoneInfo[America/Los_Angeles]

# Get all IANA timezones that could match a zone
# The first uses the primary/null territory
# The second uses the territory "AQ"
suretime.zone.all("Central Pacific Standard Time")  # {ZoneInfo[Pacific/Guadalcanal]}
suretime.zone.all("Central Pacific Standard Time", "AQ")  # {ZoneInfo[Antarctica/Casey]}

# Get 1 matching IANA zone; "get" means optional
suretime.zone.first("Central Pacific Standard Time", "AQ")  # ZoneInfo[Pacific/Casey]
suretime.zone.first("nonexistent zone")  # None
suretime.zone.only("nonexistent zone")  # errors
suretime.zone.only(
    "Central Pacific Standard Time", "any"
)  # fails (multiple possible IANA zones)

# Get a fully resolved "tagged datetime"
# It contains:
# - The zoned datetime
# - The primary IANA ZoneInfo
# - The original system timezone
# - A system wall time (`time.monotonic_ns`)
tagged = suretime.tag.now_local_sys()  # TaggedDatetime[ ... ]
print(tagged.clock.name)  # e.g. "boottime"
# or NTP:
tagged = suretime.tag.now_local_ntp(
    server="north-america", kind="server-received"
)  # TaggedDatetime[ ... ]
# or fully reliable but not keeping the local zone:
tagged = suretime.tag.now_utc_ntp()  # TaggedDatetime[ ... ]
# or NTP:
tagged = suretime.tag.now_local_sys()  # TaggedDatetime[ ... ]
print(tagged.clock.name)  # "ntp:..."
print(tagged.clock.info.resolution)  # e.g. -7

# 2021-01-20T22:24:13.219253-07:00 [America/Los_Angeles]
print(tagged.iso_with_zone)  # <datetime> [zone]
print(tagged.source.territory)  # "primary"

# if you only need the real time:
suretime.clock.sys()
# or:
suretime.clock.ntp()
# or for all of the NTP clock times:
ntp_data = suretime.clock.ntp_raw()
print(ntp_data.root_dispersion)
print(ntp_data.server_sent, ntp_data.client_received)
print(ntp_data.round_trip.total_seconds())

# Adjust a tagged time to a new real time
tagged = suretime.tag.now_utc_sys()  # TaggedDatetime[ ... ]
sys_now = suretime.clock.sys()
tagged.at(sys_now)
# now the datetime is adjusted to where it should be at the new real time

# Compare tagged datetimes
print(tagged < tagged)  # False
print(tagged == tagged)  # True: They're the same point in time
print(tagged == system_time)  # True: They're the same point in time
print(tagged.is_identical_to(tagged))  # True: They're exactly the same

# Get a "tagged duration" with the start and end, and monotonic real time in nanoseconds
then = suretime.tag.now()  # TaggedDatetime [ ... ]
for i in list(range(10000)):
    i += 1  # Just waiting a little
now = suretime.tag.now()  # TaggedInterval [ ... ]
interval = suretime.tag.interval(then, now)  # TaggedInterval [ ... ]
print(interval.real_delta)  # Actual time passed
print(interval.wall_delta)  # Simple end - start
print(interval.iso)  # start--end in ISO 8601 format
print(interval.real_str)  # days:HH:mm:ss.millis.micros.nanos
print(interval.duration.iso)  # e.g. P0Y3M5DT14H22M35.223051S

# use suretime, fall back to tzlocal
import tzlocal


def get_local() -> suretime.Types.TaggedDatetime:
    try:
        return suretime.tag.now()
    except suretime.Errors.CannotMapTzError:
        zone = tzlocal.get_localzone()
        return suretime.tag.exact(datetime.now(zone))

🍁 Contributing

Licensed under the terms of the Apache License 2.0. New issues and pull requests are welcome. Please refer to the contributing guide and security policy.

Generated with Tyrannosaurus.

suretime's People

Contributors

dmyersturnbull avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

suretime's Issues

cannot import suretime, tivial fix

On Windows, I get this error on importing it: ValueError: ZoneInfo keys must be normalized relative paths, got:

It can be trivially fixed here: https://github.com/dmyersturnbull/suretime/blob/8c8324e449e30b06be5ebbf66f470321208a6d53/suretime/_cache.py#LL130C89-L130C89

iana_zones = [ZoneInfo(iana) for iana in node.attrib["type"].split(" ")]
should be
iana_zones = [ZoneInfo(iana) for iana in node.attrib["type"].split(" ") if iana]

  • Project version: 0.2.2
  • OS/platform: Windows

Support for Windows Display Names

In a database I have timezones with Windows Display Names such as "(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna". Seems like those are not currently supported

in general: thanks for this library, it solves a real problem for me, timezones are a mess and everything that helps is more than welcome :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.