6

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

shx2
  • 61,779
  • 13
  • 130
  • 153
user2146933
  • 409
  • 5
  • 8
  • 16
  • 1
    Possible duplicate: http://stackoverflow.com/questions/7065164/how-to-make-an-unaware-datetime-timezone-aware-in-python – alan Apr 04 '14 at 21:42
  • I tried doing what was suggested in there and it ended up CONVERTING the datetime making it 8 hours later than it was (thinking that the time i gave it was a PST time that was being converted to UTC) Again, not trying to COVERT a datetime, trying to specify what the datetime is, so i get the correct "seconds from epoch" time when using it. – user2146933 Apr 04 '14 at 21:45
  • Then did you look at this: http://stackoverflow.com/questions/4548684/getting-the-time-since-the-epoch – alan Apr 04 '14 at 21:49
  • That website seems wrong - when converting `2013-06-01 01:06:18`, I get `1370045178` – Eric Apr 04 '14 at 21:56
  • For others reading this: `datetime == datetime.datetime(2013, 6, 1, 1, 6, 18)`. @OP: Don't name your variable after the module! – Eric Apr 04 '14 at 21:58
  • You need to tell it which timezone "2013-06-01 01:06:18 UTC" – user2146933 Apr 04 '14 at 21:58
  • My answer in this question works without having to apply a timezone at all: http://stackoverflow.com/questions/7852855/how-to-convert-a-python-datetime-object-to-seconds – Mark Ransom Apr 04 '14 at 22:01
  • possible duplicate of [python - datetime with timezone to epoch](http://stackoverflow.com/questions/12165691/python-datetime-with-timezone-to-epoch) – Eric Apr 04 '14 at 22:02
  • When using http://stackoverflow.com/questions/4548684/getting-the-time-since-the-epoch, i get errors stating i can't compare timzone offset unaware and offset aware datetimes. – user2146933 Apr 04 '14 at 22:05

5 Answers5

4

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.

shx2
  • 61,779
  • 13
  • 130
  • 153
  • This returns an error: ValueError: astimezone() cannot be applied to a naive datetime – user2146933 Apr 04 '14 at 21:53
  • @user2146933: note: it produces incorrect result if `dt` is not already in UTC. On the other hand if `dt` *is* in UTC already then you don't need `pytz` here, you could use [stdlib-only solution](http://stackoverflow.com/a/22330133/4279): `utc_dt_aware = utc_dt_naive.replace(tzinfo=timezone.utc)`. – jfs Apr 08 '14 at 12:41
2

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.

Community
  • 1
  • 1
sabbahillel
  • 4,357
  • 1
  • 19
  • 36
  • 1
    for anyone interested, this also sets the timezone for the `datetime` module as well. that makes this the best answer in my opinion – Matt Nov 25 '22 at 16:36
1

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>)
  • 1
    Again, i DO NOT want to CONVERT a datetime, i HAVE a datetime that is timezone UNAWARE but i know it is a UTC datetime, how do i tell pythonthat it is a UTC datetime. – user2146933 Apr 04 '14 at 21:54
1

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

Daniel Stutzbach
  • 74,198
  • 17
  • 88
  • 77
1

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)
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • `utc_dt` and `timezone` are not defined. It is unclear where they come from. – sebix Sep 08 '15 at 08:05
  • @sebix: `utc_dt`: is a naive datetime object that represents UTC time (read the 1st sentence in the question). The formula is from another answer (it demonstrates stdlib-only solution -- look at the links immediately before it). [Follow the links, to see `timezone` definition.](http://stackoverflow.com/a/22330133/4279) – jfs Sep 08 '15 at 09:10