question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

tz_offset and datetime.now(utc) don't interact correctly

See original GitHub issue

When debugging logging timestamps inside freezegun, noticed odd behaviour around calling datetime.now(timezone.utc) when freeze_time is active with a tz_offset set:

import datetime
import freezegun
import logging
import sys
import time

def log_times(name):
    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)
    handler=logging.StreamHandler(stream=sys.stdout)
    handler.setFormatter(
        logging.Formatter(
            fmt=f"%(name)s %(asctime)s - %(message)s",
            datefmt="%Y-%m-%dT%H:%M:%S%z",
        )
    )
    logger.addHandler(handler)

    logger.info("now(): %s", datetime.datetime.now().isoformat(timespec='seconds'))
    logger.info("utcnow(): %s", datetime.datetime.utcnow().isoformat(timespec='seconds'))
    logger.info("now(utc): %s", datetime.datetime.now(datetime.timezone.utc).isoformat(timespec='seconds'))
    logger.info("now(local): %s", datetime.datetime.now().astimezone().isoformat(timespec='seconds'))
    logger.info("time.time(): %s", time.strftime("%Y-%m-%dT%H:%M:%S%z", time.localtime(time.time())))


print(sys.version)
print(freezegun.__version__)

log_times("native")

with freezegun.freeze_time(datetime.datetime.now(tz=datetime.timezone.utc).replace(microsecond=0), tz_offset=0):
    log_times("offset0")


with freezegun.freeze_time(datetime.datetime.now(tz=datetime.timezone.utc).replace(microsecond=0), tz_offset=1):
    log_times("offset1")

Output:

3.7.7 (default, Mar 10 2020, 15:43:33)
[Clang 11.0.0 (clang-1100.0.33.17)]
0.3.15
native 2020-05-01T15:59:53+0100 - now(): 2020-05-01T15:59:53
native 2020-05-01T15:59:53+0100 - utcnow(): 2020-05-01T14:59:53
native 2020-05-01T15:59:53+0100 - now(utc): 2020-05-01T14:59:53+00:00
native 2020-05-01T15:59:53+0100 - now(local): 2020-05-01T15:59:53+01:00
native 2020-05-01T15:59:53+0100 - time.time(): 2020-05-01T15:59:53+0100
offset0 2020-05-01T15:59:53+0100 - now(): 2020-05-01T14:59:53
offset0 2020-05-01T15:59:53+0100 - utcnow(): 2020-05-01T14:59:53
offset0 2020-05-01T15:59:53+0100 - now(utc): 2020-05-01T14:59:53+00:00
offset0 2020-05-01T15:59:53+0100 - now(local): 2020-05-01T14:59:53+01:00
offset0 2020-05-01T15:59:53+0100 - time.time(): 2020-05-01T15:59:53+0100
offset1 2020-05-01T15:59:53+0100 - now(): 2020-05-01T15:59:53
offset1 2020-05-01T15:59:53+0100 - utcnow(): 2020-05-01T14:59:53
offset1 2020-05-01T15:59:53+0100 - now(utc): 2020-05-01T15:59:53+00:00
offset1 2020-05-01T15:59:53+0100 - now(local): 2020-05-01T15:59:53+01:00
offset1 2020-05-01T15:59:53+0100 - time.time(): 2020-05-01T15:59:53+0100

Because of https://github.com/spulec/freezegun/issues/204, the logtimes are always localtime, which is currently +0100, correctly reflected in ‘native’.

My understanding is that ‘offset0’ (tz_offset=0) should be reflecting a frozen time on the UTC timezone, barring existing bugs that attempt to load system timezone, reflected in the time.time() line.

I believe ‘offset1’(tz_offset=1) then should be a frozen time on a timezone with the same delta from UTC (+0100), which is correct except for the now(utc) line? Which should just be the same line as utcnow() but with a +0000 timezone attached, as seen on ‘native’.

Not sure if this is the same as other bugs reflecting that the system timezone leaks into the freeze if unspecified, but I’m specifying an explicit timezone during the freeze, which doesn’t seem exactly the same.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:7
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
orsiniumcommented, Aug 18, 2020

My final workaround for .astimezone():

This patch works for me! This is the test case:

@pytest.mark.parametrize("tz_offset", [
    timedelta(hours=1),
    timedelta(hours=0),
    timedelta(hours=-2),
    # ... and so on. Must work for any offset, actually
])
def test_freezegun_offset(tz_offset):
    with freezegun.freeze_time("2015-10-21 07:28", tz_offset=tz_offset):
        now = datetime.now()
        delta = now.replace(tzinfo=timezone.utc) - now.astimezone(timezone.utc)
        assert delta == tz_offset
0reactions
spumercommented, Aug 11, 2021

Nope. I saw your last activity in commits and offer fix this issue cause here (in this issue) have problematic code example (test suite) and fix (my workaround)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why does datetime.datetime.utcnow() not contain timezone ...
So, datetime.utcnow() doesn't set tzinfo to indicate that it is UTC, but datetime.now(datetime.timezone.utc) does return UTC time with tzinfo set.
Read more >
Demystifying DateTime Manipulation in JavaScript - Toptal
It's not possible to change just the time zone of an existing date object, so our target is now to create a new...
Read more >
Time zone offset from UTC - MATLAB tzoffset - MathWorks
This MATLAB function returns an array of durations equal to the time zone offset from UTC of each datetime value in t.
Read more >
Parse "Z" timezone suffix in datetime - Ideas
The timezone offset in my example is +00:00 , i.e. UTC. ... As of today, if you are not parsing the output of...
Read more >
Timezone Offset/daylighttime saving - ServiceNow Community
var time = new GlideDateTime(); //utc. time.setTZ(tz); //set time based on tz variable. var timeZoneOffSet = time.getTZOffset(); ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found