FakeDatetime timestamps don't match those generated from real datetime in some instances.
See original GitHub issueCame across a strange bug while writing tests where there is an 8 hours (likely from PST - UTC) offset between timestamps generated by FakeDatetime objects vs real Datetime objects.
I found a case where these objects compare equally, have every time variable equal, yet don’t generate matching timestamps.
from datetime import datetime
from freezegun import freeze_time
def timestamp_since(in_time):
print(f"got {in_time!r} and {in_time.timestamp()}")
print(f"currently {datetime.now()!r} and {datetime.now().timestamp()}")
print(f"tzinfo equal: {in_time.tzinfo == datetime.now().tzinfo}")
print(f"time equal: {in_time == datetime.now()}")
print(f"timestamps equal: {in_time.timestamp() == datetime.now().timestamp()}")
return datetime.now().timestamp() - in_time.timestamp()
initial_time = datetime.fromtimestamp(0)
with freeze_time(initial_time) as frozen_datetime:
print(timestamp_since(initial_time))
Running this on my python3.8 timezone PST system yields this
got datetime.datetime(1969, 12, 31, 16, 0) and 0.0
currently FakeDatetime(1969, 12, 31, 16, 0) and -28800.0
tzinfo equal: True
time equal: True
timestamps equal: False
-28800.0
So the two objects compare equally yet generate very different timestamps. I had a failing test in an interview due to this. If it’s useful to see this bug in the context of a real unit test I can provide that.
In the docs for this library you suggest making real datetimes and passing them into freeze_time(), but then if you compare the timestamps the passed-in datetime generate, they don’t match the datetimes as seen by the calling function. I found this counterintuitive.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (1 by maintainers)
I’d be happy to contribute a patch for this issue, if/when I figure out what the right fix is.
I think this is running into the same issue as here: https://github.com/spulec/freezegun/pull/136
My best suggestion is probably to not pass in an actual datetime to freeze_time(), but pass in a string representation.
We can talk about whether or not we think there is a bigger issue to fix, though it would be backwards-incompatible as mentioned in the PR.