20

Im working on converting epoch timestamps to dates in different timezones with pytz. What I am trying to do is create a DateTime object that accepts an Olson database timezone and an epoch time and returns a localized datetime object. Eventually I need to answer questions like "What hour was it in New York at epoch time 1350663248?"

Something is not working correctly here:

import datetime, pytz, time

class DateTime:
    def __init__(self, timezone, epoch):
        self.timezone = timezone
        self.epoch = epoch
        timezoneobject = pytz.timezone(timezone)
        datetimeobject = datetime.datetime.fromtimestamp( self.epoch )
        self.datetime = timezoneobject.localize(datetimeobject)

    def hour(self):
        return self.datetime.hour

if __name__=='__main__':
    epoch = time.time()
    dt = DateTime('America/Los_Angeles',epoch)
    print dt.datetime.hour
    dt = DateTime('America/New_York',epoch)
    print dt.datetime.hour

This prints the same hour, whereas one should be 3 or so hours ahead. Whats going wrong here? I'm a total Python beginner, any help is appreciated!

mobiusinversion
  • 343
  • 1
  • 6
  • 17
  • You are using the wrong terminology here. The epoch is *always* 1-1-1970, midnight UTC. What you have is a UNIX timestamp, which is an offset from the epoch. See https://en.wikipedia.org/wiki/Unix_epoch – Martijn Pieters Oct 19 '12 at 16:25
  • just a variable name, you could call it `epoch_time` it makes no difference to the problem – mobiusinversion Oct 20 '12 at 15:31

3 Answers3

39

datetime.fromtimestamp(self.epoch) returns localtime that shouldn't be used with an arbitrary timezone.localize(); you need utcfromtimestamp() to get datetime in UTC and then convert it to a desired timezone:

from datetime import datetime
import pytz

# get time in UTC
utc_dt = datetime.utcfromtimestamp(posix_timestamp).replace(tzinfo=pytz.utc)

# convert it to tz
tz = pytz.timezone('America/New_York')
dt = utc_dt.astimezone(tz)

# print it
print(dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'))

Or a simpler alternative is to construct from the timestamp directly:

from datetime import datetime
import pytz

# get time in tz
tz = pytz.timezone('America/New_York')
dt = datetime.fromtimestamp(posix_timestamp, tz)
# print it
print(dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'))

It converts from UTC implicitly in this case.

jfs
  • 399,953
  • 195
  • 994
  • 1,670
6

For creating the datetime object belonging to particular timezone from a unix timestamp, you may pass the pytz object as a tz parameter while creating your datetime. For example:

>>> from datetime import datetime
>>> import pytz

>>> datetime.fromtimestamp(1350663248, tz= pytz.timezone('America/New_York'))
datetime.datetime(2012, 10, 19, 12, 14, 8, tzinfo=<DstTzInfo 'America/New_York' EDT-1 day, 20:00:00 DST>)

You can get the list of all timezones using pytz.all_timezones which returns exhaustive list of the timezone names that can be used.

Also take a look at List of tz database time zones wiki.

Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
-3
epochdt = datetime.datetime.fromtimestamp(epoch)
timezone1 = timezone("Timezone/String")
adjusted_datetime = timezone1.localize(epochdt)

Working from memory, so excuse any syntax errors, but that should get you on the right track.

EDIT: Missed the part about knowing the hour,etc. Python has great Time/Date Formatting. At pretty much the bottom of that link is the table showing how to pull different attributes from the datetime object.

cam
  • 778
  • 6
  • 9
  • Thats pretty similar to the initial approach, but implementing this still prints out the same hour (in the __main__ code above). Basically its 8am where I am right now. What im trying to figure out is how to get the above code to print 8 and 11m ie for America/Los_Angeles and America/New_York respectively. – mobiusinversion Oct 20 '12 at 15:42