3

The time is 15:0x in Stockholm (Europe). But I'm getting the localized time 1 hour wrong:

>>> datetime.datetime.now()
datetime.datetime(2015, 12, 17, 15, 2, 42, 633000)
>>> babel.dates.format_datetime(datetime.datetime.now(), 'full', tzinfo=pytz.timezone('Europe/Stockholm'),locale='en')
u'Thursday, December 17, 2015 at 4:02:49 PM Central European Standard Time'
>>>

What is the mistake?

desertnaut
  • 57,590
  • 26
  • 140
  • 166
Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • Why the downvote? I really tried to get the time right. – Niklas Rosencrantz Dec 17 '15 at 14:06
  • 2
    timezone, obviously... pretty much anytime you get an expected date off by exactly 1 hour (or multiple thereof), it's going to be timezone related. – Marc B Dec 17 '15 at 14:06
  • @MarcB Yes and how? I was explicitly setting the timezone to `Europe/ Stockholm`. – Niklas Rosencrantz Dec 17 '15 at 14:07
  • 2
    I am pretty sure `datetime.now()` already includes local time. try `datetime.utcnow()` which defaults to a timezone of `None` https://docs.python.org/2/library/datetime.html#datetime.datetime.now – Busturdust Dec 17 '15 at 14:07
  • 1
    but you didn't tell the system what timezone your input date is in, so it's assuming something "wrong". you specified a TZ for the output only. – Marc B Dec 17 '15 at 14:08
  • @Busturdust that's it! This works: `babel.dates.format_datetime(datetime.datetime.utcnow(), 'full', tzinfo=pytz.timezone('Europe/Stockholm'),locale='en')` – Niklas Rosencrantz Dec 17 '15 at 14:08
  • 2
    Alternatively, you can specify timezone in your datetime.now: `datetime.datetime.now(tz=pytz.timezone('Europe/Stockholm'))` – DainDwarf Dec 17 '15 at 14:09
  • 1
    another solution could have been to pass an explicit timezoe to the dateime.now() call – Busturdust Dec 17 '15 at 14:09

2 Answers2

5

Explicit is better than implicit. Set the timezone for now:

now = datetime.datetime.now(tz=pytz.timezone('Europe/Stockholm'))
Mike Müller
  • 82,630
  • 20
  • 166
  • 161
  • Thank you! It's good that we can accomplish it. The output is pretty neat. – Niklas Rosencrantz Dec 17 '15 at 14:13
  • @Programmer400: the advantage is that `.now(tz)` works even during DST transitions when the local time may be ambiguous. If you need to make timezone-aware an existing naive datetime object then use `tz.localize(dt, is_dst=None)`. – jfs Dec 17 '15 at 14:36
  • 1
    [`.now(tz)` always works](http://stackoverflow.com/q/31886808/4279). `datetime(tzinfo=tz)` is WRONG unless `tz` is a fixed-offset timezone. – jfs Dec 17 '15 at 14:49
  • 1
    @J.F.Sebastion: Thanks for the info. – unutbu Dec 17 '15 at 14:51
3

The problem appears to have been the baked in local time of the datetime.datetime.now() call. As mentioned in the comments, use datetime.datetime.utcnow() for a timezone agnostic coordinated universal time, or input the desired timezone info into the datetime call datetime.datetime.now(tz=pytz.timezone('Europe/Stockholm'))

Busturdust
  • 2,447
  • 24
  • 41