41

I have a date that I build:

from datetime import datetime
from datetime import tzinfo
test = '2013-03-27 23:05'
test2 = datetime.strptime(test,'%Y-%m-%d %H:%M')
>>> test2
datetime.datetime(2013, 3, 27, 23, 5)

>>> test2.replace(tzinfo=EST)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'EST' is not defined

>> test2.replace(tzinfo=UTC)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'UTC' is not defined

I can't find documentation on the list of time zone names that I can assign to tzinfo in the replace.tzinfo= call.

I have read through the following and there is nothing:

http://docs.python.org/2/library/datetime.html#tzinfo-objects

I have also searched in google.

Edit: I followed the solution provided by unutbu but I get the following:

>>> test = '2013-03-27 00:05'
>>> test
'2013-03-27 00:05'

>>> test2 = dt.datetime.strp(test, '%Y-%m-%d %H:%M')
>>> test2
datetime.datetime(2013, 3, 27, 0, 5)

>>> est = pytz.timezone('US/Eastern')
>>> utc = pytz.utc
>>> print(est.localize(test2))
2013-03-27 00:05:00-04:00
>>> print(utc.localize(test2))
2013-03-27 00:05:00+00:00

>>> print(est.localize(test2,is_dst=False))
2013-03-27 00:05:00-04:00
>>> print(est.localize(test2,is_dst=True))
2013-03-27 00:05:00-04:00
>>>

As you can see even when I provide the is_dst= flag the offset is still '-04:00', which is EDT and not EST. I appreciate the help. Thank you.

The documentation shows the following:

If you insist on working with local times, this library provides a facility for constructing them unambiguously: http://pytz.sourceforge.net/#problems-with-localtime

>>> loc_dt = datetime(2002, 10, 27, 1, 30, 00)
>>> est_dt = eastern.localize(loc_dt, is_dst=True)
>>> edt_dt = eastern.localize(loc_dt, is_dst=False)
>>> print(est_dt.strftime(fmt) + ' / ' + edt_dt.strftime(fmt))
2002-10-27 01:30:00 EDT-0400 / 2002-10-27 01:30:00 EST-0500

eastern was defined earlier in the documentation as eastern = timezone('US/Eastern')

This seems to indicate that the is_dst= flag should further specify whether day light savings is specified or not. I would appreciate help on why this isn't working in my case.

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
codingknob
  • 11,108
  • 25
  • 89
  • 126
  • I got an error when I tried running this: `AttributeError: 'module' object has no attribute 'strptime'`. Are you sure you copied the code correctly? – Moshe Mar 28 '13 at 22:02
  • oops. Did you import datetime and tzinfo? I will edit my original post to include that. – codingknob Mar 28 '13 at 22:13
  • My bad, I had imported `datetime`, not `datetime.datetime`. Thanks! – Moshe Mar 28 '13 at 22:51

4 Answers4

61

The standard library does not define any timezones -- at least not well (the toy example given in the documentation does not handle subtle problems like the ones mentioned here). For predefined timezones, use the third-party pytz module.

import pytz
import datetime as DT

eastern = pytz.timezone('US/Eastern')
utc = pytz.utc
test = '2013-03-27 23:05'

This is a "naive" datetime:

test2 = DT.datetime.strptime(test, '%Y-%m-%d %H:%M')   
print(test2)
# 2013-03-27 23:05:00

This makes a timezone-aware datetime by interpreting test2 as if it were in the EST timezone:

print(eastern.localize(test2))
# 2013-03-27 23:05:00-04:00

This makes a timezone-aware datetime by interpreting test2 as if it were in the UTC timezone:

print(utc.localize(test2))
# 2013-03-27 23:05:00+00:00

Alternatively, you can convert one timezone-aware datetime to another timezone using the astimezone method:

test2_eastern = eastern.localize(test2)
print(test2_eastern.astimezone(utc))
# 2013-03-28 03:05:00+00:00
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • @unutbu - thank you. Question: why is the time offset '-04:00'? Shouldn't this be treated as EST and NOT EDT? – codingknob Mar 28 '13 at 23:32
  • @algotr8der: Daylight Saving Time began 2013-03-10 at 2am. So it is EDT in the 'US/Eastern' timezone. – unutbu Mar 28 '13 at 23:43
  • If you really do want EST no matter what day it is, use `pytz.timezone('EST')`. – unutbu Mar 28 '13 at 23:45
  • If I do that it shows a -05:00 offset as expected. That said, why doesn't setting is_dat= flag work when the pytz.timezone='US/Eastern' and when pytz.timezone='EST'. When I set timezone='EST' and include is_dst=True I should see a -05:00 offset and when I set timezone='US/Eastern' and include is_dst=False I should see a -04:00 offset. The documentation seems to indicate this here: http://pytz.sourceforge.net/#problems-with-localtime. – codingknob Mar 28 '13 at 23:55
  • 1
    @algotr8der: The `is_dst` parameter only affects how `localize` interprets **ambiguous** dates. (In the fall, you "fall back", creating two hours which go by the same "name"). – unutbu Mar 29 '13 at 00:00
28

since the release of Python 3.9, the standard lib does define time zones, and you can get them via

import zoneinfo
print(zoneinfo.available_timezones())

# {'America/Belem', 'Asia/Tel_Aviv', 'Australia/North', 'Asia/Omsk', 
#  'Europe/Isle_of_Man', 'America/New_York', 'Europe/Nicosia', 
#  'Pacific/Funafuti', 'America/Ensenada', 'Europe/Mariehamn', 
#  'America/Maceio', 'America/Guatemala', 'America/Guadeloupe', ...
FObersteiner
  • 22,500
  • 8
  • 42
  • 72
  • 1
    `zoneinfo` gets its time zone information from the operating system, or from [`tzdate`](https://pypi.org/project/tzdata/) if on Windows. – Flimm Mar 21 '23 at 14:50
9

As mentioned by @FObersteiner, starting from python 3.9 you don't need to install 3rd party pytz but use natively zoneinfo.

from datetime import datetime
from zoneinfo import ZoneInfo

test = '2013-03-27 23:05'
test2 = datetime.strptime(test,'%Y-%m-%d %H:%M')
date_string = test2.replace(tzinfo=ZoneInfo('US/Eastern'))
print(datestring)
2013-03-27 23:05:00-04:00
FObersteiner
  • 22,500
  • 8
  • 42
  • 72
Mike K
  • 389
  • 3
  • 3
2
 import pytz
 timezones=pytz.all_timezones

This gives all timezones

Three-pth
  • 49
  • 1
  • 6
  • 1
    you should mention this is a separate dependency, and discuss why to use it etc. extra important now that python 3.9 has `zoneinfo` – LudvigH Mar 10 '21 at 09:16
  • This is still the best answer for my problem in May 2022, as 3.9 is net yet very common in distributions (and I was already importing pytz anyway). – tsbertalan May 13 '22 at 16:21