user2146933
user2146933

Reputation: 407

Specify which timezone a datetime is in, in python

I have a datetime that i get from a database, this datetime is a UTC datetime. But when i pull it from the DB, it is unaware of the timezone. What i need to do, is convert this datetime to a "seconds from epoch" time for another function. The problem with this, is that the system's time is in PST and i am not able to change it for specific reasons.

So, what i want to do is, take this datetime that i get from the database, and tell python that this datetime is a UTC datetime. Every way that i have done that, results in it losing time or gaining time due to timezone conversions. Again, not trying to convert the time, just trying to specify that it is UTC.

If anyone can help with this that would be great.

Thanks!

Example

Assume database_function() returns a datetime data type that is '2013-06-01 01:06:18'

datetime = database_function()
epoch = datetime.strftime('%s')

pytz.utc.localize(database_function()).datetime.strftime('%s')
datetime.replace(tzinfo=pytz.utc).datetime.strftime('%s')

Both of these return a epoch timestamp of 1370077578 But, it SHOULD return a timestamp of 1370048778 per http://www.epochconverter.com/ Remember, this timestamp is a utc timestamp

Upvotes: 6

Views: 19874

Answers (5)

jfs
jfs

Reputation: 414079

Here's stdlib only solution without 3-party modules.

.., this datetime is a UTC datetime. But when i pull it from the DB, it is unaware of the timezone. What i need to do, is convert this datetime to a "seconds from epoch" time for another function.emphasize is mine

To convert an unaware (naive) datetime object that represents time in UTC to POSIX timestamp:

from datetime import datetime

timestamp = (dt_from_db - datetime(1970, 1, 1)).total_seconds()

Example:

>>> from datetime import datetime
>>> dt = datetime.strptime('2013-06-01 01:06:18', '%Y-%m-%d %H:%M:%S')
>>> (dt - datetime(1970, 1, 1)).total_seconds()
1370048778.0

See Converting datetime.date to UTC timestamp in Python that provides solutions for various Python versions.

To answer the question from the title: In general you need pytz library to handle timezones in Python. In particular, you should use .localize method to convert an unaware datetime object into timezone-aware one.

import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal

tz = get_localzone() # local timezone whatever it is (just an example)
aware_dt = tz.localize(naive_dt_in_local_timezone, is_dst=None)

is_dst=None asserts that naive_dt_in_local_timezone exists and unambiguous.

Though you don't need it for UTC timezone because it always has the same UTC offset (zero) around the year and in all past years:

import pytz

aware_dt = utc_dt.replace(tzinfo=pytz.utc)

See Python - simplest and most coherent way to get timezone-aware current time in UTC? (it provides a stdlib-only solution):

aware_dt = utc_dt.replace(tzinfo=timezone.utc)

Upvotes: 1

sabbahillel
sabbahillel

Reputation: 4425

How about Setting timezone in Python This appears to reset the timezone within your python script. You are changing the time zone that your system sees given the specified time, not changing the specified time into the specified time zone. You probably want to set it to 'UTC'

time.tzset()

Resets the time conversion rules used by the library routines.
The environment variable TZ specifies how this is done.

New in version 2.3.

Availability: Unix.

I do not have this available on my home platform so I could not test it. I had to get this from the previous answer.

The answer marked best on the question is:

>>> import os, time
>>> time.strftime('%X %x %Z')
'12:45:20 08/19/09 CDT'
>>> os.environ['TZ'] = 'Europe/London'
>>> time.tzset()
>>> time.strftime('%X %x %Z')
'18:45:39 08/19/09 BST'

To get the specific values you've listed:

>>> year = time.strftime('%Y')
>>> month = time.strftime('%m')
>>> day = time.strftime('%d')
>>> hour = time.strftime('%H')
>>> minute = time.strftime('%M')

See here for a complete list of directives. Keep in mind that the strftime() function will always return a string, not an integer or other type.

Upvotes: 2

Daniel Stutzbach
Daniel Stutzbach

Reputation: 76647

Here is one way, using the pytz module:

import pytz
utc_datetime = (datetime.datetime(1970, 1, 1, tzinfo=pytz.utc)
                + datetime.timedelta(seconds=seconds_since_epoch)

If you don't want to install the pytz module, you can copy the example UTC class from the datetime documentation (search for "class UTC"):

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

Upvotes: 1

user2623906
user2623906

Reputation:

You can Use pytz, which is a time zone definitions package.

from datetime import datetime
from pytz import timezone

fmt = "%Y-%m-%d %H:%M:%S %Z%z"

# Current time in UTC
now_utc = datetime.now(timezone('UTC'))
print now_utc.strftime(fmt)

# Convert to US/Pacific time zone
now_pacific = now_utc.astimezone(timezone('US/Pacific'))
print now_pacific.strftime(fmt)

# Convert to Europe/Berlin time zone
now_berlin = now_pacific.astimezone(timezone('Europe/Berlin'))
print now_berlin.strftime(fmt)

output:

2014-04-04 21:50:55 UTC+0000
2014-04-04 14:50:55 PDT-0700
2014-04-04 23:50:55 CEST+0200

or may be it helps

>> import pytz
>>> import datetime
>>>
>>> now_utc = datetime.datetime.utcnow() #Our UTC naive time from DB,
   for the time being here I'm taking it as current system UTC time..
>>> now_utc
    datetime.datetime(2011, 5, 9, 6, 36, 39, 883479) # UTC time in Naive
   form.
>>>
>>> local_tz = pytz.timezone('Europe/Paris') #Our Local timezone, to
   which we want to convert the UTC time.
>>>
>>> now_utc = pytz.utc.localize(now_utc) #Add Timezone information to
   UTC time.
>>>
>>> now_utc
datetime.datetime(2011, 5, 9, 6, 36, 39, 883479, tzinfo=<UTC>) # The
   full datetime tuple
>>>
>>> local_time = now_utc.astimezone(local\_tz) # Convert to local
   time.
>>>
>>> local_time #Current local time in Paris
datetime.datetime(2011, 5, 9, 8, 36, 39, 883479, tzinfo=<DstTzInfo
   'Europe/Paris' CEST+2:00:00 DST>)

Upvotes: 1

shx2
shx2

Reputation: 64298

Using the fabolous pytz:

import datetime, pytz
dt = datetime.datetime(...)
utc_dt = pytz.utc.localize(dt)

This creates a tz-aware datetime object, in UTC.

Upvotes: 4

Related Questions