Search code examples
pythondatetimetimetimezonepytz

Parse a date in a specific timezone with Python


How can I take this date string:

"2015-01-01"

and, assuming it is in a specific timezone (say, "US-Mountain"), convert it to a POSIX timestamp?

Like so:

magic_parse_function("2015-01-01", pytz.timezone("US-Mountain")) -> 1420095600

I've spent quite some time scouring the docs and this site, playing with aware/unaware datetime objects, and am hoping for a not-too-crazy solution. The following does not work, the last two lines of output are identical, and they should be 3600 seconds apart:

import datetime
import time
import pytz
timestring = "2015-01-01"
pacific = pytz.timezone("US/Pacific")
mountain = pytz.timezone("US/Mountain")
(year, month, day) = timestring.split('-')
year = int(year)
month = int(month)
day = int(day)
unaware = datetime.datetime(year, month, day, 0, 0, 0, 0)
# aware_pacific = pacific.localize(unaware)
# aware_mountain = mountain.localize(unaware)
aware_mountain = unaware.replace(tzinfo=mountain)
aware_pacific = unaware.replace(tzinfo=pacific)
print time.mktime(aware_pacific.timetuple())
print time.mktime(aware_mountain.timetuple())

Solution

  • There are three steps:

    1. Convert the date string into a naive datetime object:

      from datetime import datetime 
      
      dt = datetime(*map(int ,'2015-01-01'.split('-')))
      
    2. Get a timezone-aware datetime object:

      import pytz # $ pip install pytz
      
      aware = pytz.timezone("US/Mountain").localize(dt, is_dst=None)
      

      is_dst=None raises an exception for ambiguous or non-existing times. Here're more details about what is is_dst flag and why do you need it, see "Can I just always set is_dst=True?" section

    3. Get POSIX timestamp:

      timestamp = aware.timestamp()
      

      .timestamp() is available since Python 3.3+. See multiple solutions for older Python versions.