Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

freeze_time could accept a timezone argument #87

Closed
charlax opened this issue Mar 5, 2015 · 19 comments
Closed

freeze_time could accept a timezone argument #87

charlax opened this issue Mar 5, 2015 · 19 comments

Comments

@charlax
Copy link

charlax commented Mar 5, 2015

What do you think of having freeze_time accept a timezone argument:

@freeze_time('2015-03-09 09:00:00', timezone='US/Pacific')

That would require adding pytz to the requirements, which should be fine since most Python projects have it.

Thoughts? I might develop it.

@spulec
Copy link
Owner

spulec commented Mar 5, 2015

Not sure if you know this, but freeze_time already accepts a tz_offset argument.

If your suggestion was just to make it cleaner so that we could pass in 'nice' timezone names, then I could get behind that.

@charlax
Copy link
Author

charlax commented Mar 5, 2015

Yes, I've seen tz_offset. The problem is that (1) it requires explicit knowledge about the offset (2) the offset changes depending on the datetime.

@spulec
Copy link
Owner

spulec commented Mar 5, 2015

Ah, right. I had forgotten about your second point. PR welcome.

@adamchainz
Copy link
Contributor

You don't need to put pytz in the requirements, it can be optional (try: import; except ImportError: pytz = None pattern) and then only used if timezone is passed.

@shreevatsar
Copy link

Just FYI: one can already pass freeze_time a timezone-aware datetime object:

d = datetime(2015, 8, 18, 8, 51, 50, tzinfo=pytz.timezone('America/Los_Angeles'))
with freeze_time(d):
    print datetime.now()

(prints 2015-08-18 08:51:50-08:00)

@agriffis
Copy link
Contributor

agriffis commented Jan 4, 2016

AFAIK you can also pass a timezone in the string, right?

with freeze_time("2015-03-09 09:00:00 PST")

@agriffis
Copy link
Contributor

agriffis commented Jan 5, 2016

Regarding my previous comment, it turns out that dateutil's parser returns an aware datetime IFF the timezone in the string matches the default timezone of the host. In all other cases, dateutil's parser ignores the given timezone and returns a naive (and unadjusted) datetime.

>>> parse("12:00 EST")
datetime.datetime(2016, 1, 4, 12, 0, tzinfo=tzlocal())
>>> parse("12:00 CST")
datetime.datetime(2016, 1, 4, 12, 0)
>>> parse("12:00 MST")
datetime.datetime(2016, 1, 4, 12, 0)

Definitely fails the principle of least surprise for me, but there you have it.

@spulec
Copy link
Owner

spulec commented Jan 17, 2016

Going to close this with support for @shreevatsar 's solution

@spulec spulec closed this as completed Jan 17, 2016
@vitawasalreadytaken
Copy link

@spulec That's a shame. While it works, it's a bit clumsy for an extremely common use case. (I, at least, have zero Python projects that can afford to ignore time zones.)

@spulec
Copy link
Owner

spulec commented Jan 18, 2016

Happy to accept a PR for it, but don't want to leave the issue open forever.

@jose-lpa
Copy link

jose-lpa commented Apr 1, 2019

@shreevatsar solution does not work for me.

I might be doing something wrong, but definitely this is not very straightforward.

Screenshot from 2019-04-01 10-59-04

@fish-face
Copy link

I am also not getting the described behaviour:

In [4]: dt = datetime(2018,1,1,tzinfo=pytz.timezone('America/Los_Angeles'))
In [6]: with freeze_time(dt): 
   ...:     print(datetime.now()) 
   ...:                                                                                    
2018-01-01 07:53:00

Ignoring the whacky time (this is caused by most timezones not being suitable for use as the tzinfo parameter) this is not even an aware datetime as @shreevatsar said (maybe this is a regression?)

@spumer
Copy link

spumer commented May 3, 2019

I got same problem with freezing time in Django tests =/

@IaroslavR
Copy link

i can confirm problem mentioned by @spumer @fish-face and @jose-lpa
my workaround:

from datetime import datetime

import arrow
from freezegun import freeze_time

d = datetime(2015, 8, 18, 8, 51, 50, tzinfo=arrow.now("America/Los_Angeles").tzinfo)
with freeze_time(d):
    print datetime.now()

2015-08-18 15:51:50

@pngnviko
Copy link

@spulec for me @shreevatsar 's solution doesn't work as well

@robertpro
Copy link

robertpro commented Sep 3, 2020

This worked for me (I already had a helper function for tests) on Django + pytest + freezegun

from datetime import datetime

from django.utils.timezone import get_current_timezone


def to_datetime(str_date: str, time: bool = False) -> datetime:
    str_format = "%Y-%m-%d"
    if time:
        str_format += "-%H:%M:%S"

    return datetime.strptime(str_date, str_format).astimezone(get_current_timezone())

On the tests:

with freeze_time(to_datetime("2020-01-12")):
    ...

@spumer
Copy link

spumer commented Sep 3, 2020

Be ware when work with aware datetimes: #348

@realmhamdy
Copy link

Is there any technical reason why you're convert_to_timezone_naive() before setting the time? Is this absolutely needed?

@benthorner
Copy link

@spumer @realmhamdy thanks for pointing to that issue - very helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests