Converting datetime.date to UTC timestamp in Python - python

I am dealing with dates in Python and I need to convert them to UTC timestamps to be used
inside Javascript. The following code does not work:
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(time.mktime(d.timetuple()))
datetime.datetime(2010, 12, 31, 23, 0)
Converting the date object first to datetime also does not help. I tried the example at this link from, but:
from pytz import utc, timezone
from datetime import datetime
from time import mktime
input_date = datetime(year=2011, month=1, day=15)
and now either:
mktime(utc.localize(input_date).utctimetuple())
or
mktime(timezone('US/Eastern').localize(input_date).utctimetuple())
does work.
So general question: how can I get a date converted to seconds since epoch according to UTC?

If d = date(2011, 1, 1) is in UTC:
>>> from datetime import datetime, date
>>> import calendar
>>> timestamp1 = calendar.timegm(d.timetuple())
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2011, 1, 1, 0, 0)
If d is in local timezone:
>>> import time
>>> timestamp2 = time.mktime(d.timetuple()) # DO NOT USE IT WITH UTC DATE
>>> datetime.fromtimestamp(timestamp2)
datetime.datetime(2011, 1, 1, 0, 0)
timestamp1 and timestamp2 may differ if midnight in the local timezone is not the same time instance as midnight in UTC.
mktime() may return a wrong result if d corresponds to an ambiguous local time (e.g., during DST transition) or if d is a past(future) date when the utc offset might have been different and the C mktime() has no access to the tz database on the given platform. You could use pytz module (e.g., via tzlocal.get_localzone()) to get access to the tz database on all platforms. Also, utcfromtimestamp() may fail and mktime() may return non-POSIX timestamp if "right" timezone is used.
To convert datetime.date object that represents date in UTC without calendar.timegm():
DAY = 24*60*60 # POSIX day in seconds (exact value)
timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * DAY
timestamp = (utc_date - date(1970, 1, 1)).days * DAY
How can I get a date converted to seconds since epoch according to UTC?
To convert datetime.datetime (not datetime.date) object that already represents time in UTC to the corresponding POSIX timestamp (a float).
Python 3.3+
datetime.timestamp():
from datetime import timezone
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
Note: It is necessary to supply timezone.utc explicitly otherwise .timestamp() assume that your naive datetime object is in local timezone.
Python 3 (< 3.3)
From the docs for datetime.utcfromtimestamp():
There is no method to obtain the timestamp from a datetime instance,
but POSIX timestamp corresponding to a datetime instance dt can be
easily calculated as follows. For a naive dt:
timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
And for an aware dt:
timestamp = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)
Interesting read: Epoch time vs. time of day on the difference between What time is it? and How many seconds have elapsed?
See also: datetime needs an "epoch" method
Python 2
To adapt the above code for Python 2:
timestamp = (dt - datetime(1970, 1, 1)).total_seconds()
where timedelta.total_seconds() is equivalent to (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 computed with true division enabled.
Example
from __future__ import division
from datetime import datetime, timedelta
def totimestamp(dt, epoch=datetime(1970,1,1)):
td = dt - epoch
# return td.total_seconds()
return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6
now = datetime.utcnow()
print now
print totimestamp(now)
Beware of floating-point issues.
Output
2012-01-08 15:34:10.022403
1326036850.02
How to convert an aware datetime object to POSIX timestamp
assert dt.tzinfo is not None and dt.utcoffset() is not None
timestamp = dt.timestamp() # Python 3.3+
On Python 3:
from datetime import datetime, timedelta, timezone
epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
timestamp = (dt - epoch) / timedelta(seconds=1)
integer_timestamp = (dt - epoch) // timedelta(seconds=1)
On Python 2:
# utc time = local time - utc offset
utc_naive = dt.replace(tzinfo=None) - dt.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()

For unix systems only:
>>> import datetime
>>> d = datetime.date(2011, 1, 1)
>>> d.strftime("%s") # <-- THIS IS THE CODE YOU WANT
'1293832800'
Note 1: dizzyf observed that this applies localized timezones. Don't use in production.
Note 2: Jakub Narębski noted that this ignores timezone information even for offset-aware datetime (tested for Python 2.7).

Assumption 1: You're attempting to convert a date to a timestamp, however since a date covers a 24 hour period, there isn't a single timestamp that represents that date. I'll assume that you want to represent the timestamp of that date at midnight (00:00:00.000).
Assumption 2: The date you present is not associated with a particular time zone, however you want to determine the offset from a particular time zone (UTC). Without knowing the time zone the date is in, it isn't possible to calculate a timestamp for a specific time zone. I'll assume that you want to treat the date as if it is in the local system time zone.
First, you can convert the date instance into a tuple representing the various time components using the timetuple() member:
dtt = d.timetuple() # time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1)
You can then convert that into a timestamp using time.mktime:
ts = time.mktime(dtt) # 1293868800.0
You can verify this method by testing it with the epoch time itself (1970-01-01), in which case the function should return the timezone offset for the local time zone on that date:
d = datetime.date(1970,1,1)
dtt = d.timetuple() # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=-1)
ts = time.mktime(dtt) # 28800.0
28800.0 is 8 hours, which would be correct for the Pacific time zone (where I'm at).

I defined my own two functions
utc_time2datetime(utc_time, tz=None)
datetime2utc_time(datetime)
here:
import time
import datetime
from pytz import timezone
import calendar
import pytz
def utc_time2datetime(utc_time, tz=None):
# convert utc time to utc datetime
utc_datetime = datetime.datetime.fromtimestamp(utc_time)
# add time zone to utc datetime
if tz is None:
tz_datetime = utc_datetime.astimezone(timezone('utc'))
else:
tz_datetime = utc_datetime.astimezone(tz)
return tz_datetime
def datetime2utc_time(datetime):
# add utc time zone if no time zone is set
if datetime.tzinfo is None:
datetime = datetime.replace(tzinfo=timezone('utc'))
# convert to utc time zone from whatever time zone the datetime is set to
utc_datetime = datetime.astimezone(timezone('utc')).replace(tzinfo=None)
# create a time tuple from datetime
utc_timetuple = utc_datetime.timetuple()
# create a time element from the tuple an add microseconds
utc_time = calendar.timegm(utc_timetuple) + datetime.microsecond / 1E6
return utc_time

follow the python2.7 document, you have to use calendar.timegm() instead of time.mktime()
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(calendar.timegm(d.timetuple()))
datetime.datetime(2011, 1, 1, 0, 0)

A complete time-string contains:
date
time
utcoffset [+HHMM or -HHMM]
For example:
1970-01-01 06:00:00 +0500 == 1970-01-01 01:00:00 +0000 == UNIX timestamp:3600
$ python3
>>> from datetime import datetime
>>> from calendar import timegm
>>> tm = '1970-01-01 06:00:00 +0500'
>>> fmt = '%Y-%m-%d %H:%M:%S %z'
>>> timegm(datetime.strptime(tm, fmt).utctimetuple())
3600
Note:
UNIX timestamp is a floating point number expressed in seconds since the epoch, in UTC.
Edit:
$ python3
>>> from datetime import datetime, timezone, timedelta
>>> from calendar import timegm
>>> dt = datetime(1970, 1, 1, 6, 0)
>>> tz = timezone(timedelta(hours=5))
>>> timegm(dt.replace(tzinfo=tz).utctimetuple())
3600

Using the arrow package:
>>> import arrow
>>> arrow.get(2010, 12, 31).timestamp
1293753600
>>> time.gmtime(1293753600)
time.struct_time(tm_year=2010, tm_mon=12, tm_mday=31,
tm_hour=0, tm_min=0, tm_sec=0,
tm_wday=4, tm_yday=365, tm_isdst=0)

the question is a little confused. timestamps are not UTC - they're a Unix thing. the date might be UTC? assuming it is, and if you're using Python 3.2+, simple-date makes this trivial:
>>> SimpleDate(date(2011,1,1), tz='utc').timestamp
1293840000.0
if you actually have the year, month and day you don't need to create the date:
>>> SimpleDate(2011,1,1, tz='utc').timestamp
1293840000.0
and if the date is in some other timezone (this matters because we're assuming midnight without an associated time):
>>> SimpleDate(date(2011,1,1), tz='America/New_York').timestamp
1293858000.0
[the idea behind simple-date is to collect all python's date and time stuff in one consistent class, so you can do any conversion. so, for example, it will also go the other way:
>>> SimpleDate(1293858000, tz='utc').date
datetime.date(2011, 1, 1)
]

Considering you have a datetime object called d,
use the following to get the timestamp in UTC:
d.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
And for the opposite direction, use following :
d = datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")

This works for me, pass through a function.
from datetime import timezone, datetime, timedelta
import datetime
def utc_converter(dt):
dt = datetime.datetime.now(timezone.utc)
utc_time = dt.replace(tzinfo=timezone.utc)
utc_timestamp = utc_time.timestamp()
return utc_timestamp
# create start and end timestamps
_now = datetime.datetime.now()
str_start = str(utc_converter(_now))
_end = _now + timedelta(seconds=10)
str_end = str(utc_converter(_end))

i'm impressed of the deep discussion.
my 2 cents:
from datetime import datetime
import time
the timestamp in utc is:
timestamp = \
(datetime.utcnow() - datetime(1970,1,1)).total_seconds()
or,
timestamp = time.time()
if now results from datetime.now(), in the same DST
utcoffset = (datetime.now() - datetime.utcnow()).total_seconds()
timestamp = \
(now - datetime(1970,1,1)).total_seconds() - utcoffset

Related

Python - Add time zone to timestamp

I use chrome timestamp and convert it do readable date but time isn't right
timestamp_formated = str(datetime.datetime(1601, 1, 1) + datetime.timedelta(microseconds=last_visit_time))
Seems to be timezone need to be added
example for last_visit_time : 13292010189305268
Assuming that Chrome timestamps denote microseconds since 1601 UTC, you'll want to make your datetime aware:
from datetime import datetime, timezone, timedelta
epoch = datetime(1601, 1, 1, tzinfo=timezone.utc)
timestamp = epoch + timedelta(microseconds=last_visit_time)
print(timestamp)
If you want to format it for a non-UTC timezone, add a conversion step:
local_timestamp = timestamp.astimezone(the_timezone)
if you'd like to localize(use timezone specific dates and time) you can use pytz for that
t = datetime(
2013, 5, 11, hour=11, minute=0,
tzinfo=pytz.timezone('Europe/Warsaw')
)

How to convert a datetime ('2019-06-05T10:37:29.353+0100') to UTC timestamp using Python3?

I want to convert datetime, i.e. 2019-06-05T10:37:29.353+0100, to UTC timestamp in Python3.
I understand that +0100 represents the timezone. Why do +0100, +0200, and +0300 all convert to the same timestamp?
How can I convert a datetime containing a timezone to a UTC timestamp?
>>> d=datetime.datetime.strptime('2019-06-05T10:37:29.353+0100', '%Y-%m-%dT%H:%M:%S.%f%z')
>>> unixtime = time.mktime(d.timetuple())
>>> unixtime
1559723849.0
>>> d=datetime.datetime.strptime('2019-06-05T10:37:29.353+0200', '%Y-%m-%dT%H:%M:%S.%f%z')
>>> unixtime = time.mktime(d.timetuple())
>>> unixtime
1559723849.0
>>> d=datetime.datetime.strptime('2019-06-05T10:37:29.353+0300', '%Y-%m-%dT%H:%M:%S.%f%z')
>>> unixtime = time.mktime(d.timetuple())
>>> unixtime
1559723849.0
here's some more explanations (see comments) how to convert back and forth between timestamps as strings with UTC offset and POSIX timestamps.
from datetime import datetime, timezone
s = '2019-06-05T10:37:29.353+0100'
# to datetime object
dt = datetime.strptime('2019-06-05T10:37:29.353+0100', '%Y-%m-%dT%H:%M:%S.%f%z')
# note that the object has tzinfo set to a specific timedelta:
print(repr(dt))
>>> datetime.datetime(2019, 6, 5, 10, 37, 29, 353000, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600)))
# you could store this info
dt_UTCoffset = dt.utcoffset() # datetime.timedelta(seconds=3600)
# to get POSIX seconds since the epoch:
ts = dt.timestamp()
# and back to datetime:
dt_from_ts = datetime.fromtimestamp(ts, tz=timezone.utc)
# note that this is a UTC timestamp; the UTC offset is zero:
print(dt_from_ts.isoformat())
>>> 2019-06-05T09:37:29.353000+00:00
# instead of UTC, you could also set a UTC offset:
dt_from_ts = datetime.fromtimestamp(ts, tz=timezone(dt_UTCoffset))
print(dt_from_ts.isoformat())
>>> 2019-06-05T10:37:29.353000+01:00
...And a note on a pitfall when working with datetime in Python: if you convert from timestamp to datetime and don't set the tz property, local time is returned (same applies the other way 'round!):
print(datetime.fromtimestamp(ts)) # I'm on CEST at the moment, so UTC+2
>>> 2019-06-05 11:37:29.353000

Why is converting this datetime to Epoch off by 30 minutes?

I have the following string representing a UTC timestamp: 2017-12-03T20:38:00.971261Z
I would like to convert it into Posix timestamp (IE: seconds since the epoch)
Using this online converter (https://www.epochconverter.com/) I know the answer is 1512333480
But when I do the following code, the result is off by 1800 seconds -- 30 minutes:
>>> temp_time1 = datetime.datetime.strptime('2017-12-03T20:38:00.971261Z', '%Y-%m-%dT%H:%M:%S.%fZ')
>>> ctime = int(datetime.datetime(temp_time1.year,
temp_time1.month,
temp_time1.day,
temp_time1.hour,
temp_time1.minute,
temp_time1.second,
temp_time1.microsecond,
pytz.timezone('Europe/London')).strftime('%s'))
>>> print ctime
1512351480
Anyone know what I'm missing here??
You created a new timestamp and put it in the Europe/London timezone. That is not the same thing as UTC. The Europe/London timezone from the PyTZ database includes historical offsets, and those affect how datetime.datetime() interprets the timezone.
Just use the datetime.timestamp() method on the datetime object you already parsed from the string:
>>> import datetime
>>> temp_time1 = datetime.datetime.strptime('2017-12-03T20:38:00.971261Z', '%Y-%m-%dT%H:%M:%S.%fZ')
>>> temp_time1.timestamp()
1512333480.971261
Your original temp_time1 datetime object is timezone agnostic, so the timestamp() object already assumes no timezone conversion has to take place.
If you must apply the Europe/London timezone first for whatever reason, then at least use the timezone.localize() method to get the right offset applied:
>>> import pytz
>>> pytz.timezone('Europe/London').localize(temp_time1)
datetime.datetime(2017, 12, 3, 20, 38, 0, 971261, tzinfo=<DstTzInfo 'Europe/London' GMT0:00:00 STD>)
>>> pytz.timezone('Europe/London').localize(temp_time1).timestamp()
1512333480.971261
See How to make an unaware datetime timezone aware in python
For Python 2 and Python 3.0, 3.1 or 3.2, where datetime.timestamp() is not available, subtract the epoch date:
>>> (temp_time1 - datetime.datetime(1970, 1, 1)).total_seconds()
1512333480.971261
Add in the UTC timezone when dealing with timezone-aware datetime instances:
>>> (pytz.timezone('Europe/London').localize(temp_time1) - datetime.datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
1512333480.971261
Combined into a function:
def datetime_to_timestamp(dt, epoch=datetime.datetime(1970, 1, 1)):
if dt.tzinfo is not None:
epoch = pytz.utc.localize(epoch)
return (dt - epoch).total_seconds()

Write a python script to generate a timestamp ( unix epoch value) each day at a give time

I want to write a small python which needs to generate a simple precise timestamp each day ( the script will be run each day) at a particular hour say 1pm. I wrote something like this:
from datetime import datetime
now = datetime.utcnow() # Current time
then = datetime(1970,1,1) # 0 epoch time
ts = now - then
ts = ts.days * 24 * 3600 + ts.seconds
print ts
This is good, but i want to pass now for the time_field that i on daily basis. How do I do this?
You can use the time.mktime function:
>>> import datetime
>>> import time
>>> dt = datetime.datetime.today().replace(hour=13, minute=0, second=0, microsecond=0)
>>> print(dt)
2016-04-06 13:00:00
>>> time.mktime(dt.timetuple())
1459944000.0
If you need to be timezone-aware, use a timezone-aware datetime's utctimetuple method and the time.gmtime function.
(edited to show how to create datetime.datetime for a specific time)
date command in shell gives us epoch time also.
date +%s
So write your python script as
import subprocess
p = subprocess.Popen(['date', '+%s'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out, err = p.communicate()
print out
and then call it daily with the same logic you are using now.
To generate a POSIX timestamp that corresponds to 1pm:
#!/usr/bin/env python3
from datetime import datetime
import tzlocal # $ pip install tzlocal
local_timezone = tzlocal.get_localzone()
now = datetime.now(local_timezone)
one_pm = local_timezone.localize(datetime(now.year, now.month, now.day, 13), # 1pm
is_dst=None) # assert that there is no DST transition at 1pm
posix_time = one_pm.timestamp()
If there is no datetime.timestamp() method on your Python version then it is easy to implement it for a timezone-aware datetime object such as one_pm:
def posix_timestamp(aware, epoch=datetime(1970, 1, 1)):
utc = aware.replace(tzinfo=None) - aware.utcoffset() # convert to utc
return (utc - epoch).total_seconds()
If there is no DST transition at 1pm and mktime() uses a correct timezone definition on a given platform then to get Unix time that corresponds to 1pm:
#!/usr/bin/env python
import time
unix_time = time.mktime(time.localtime()[:3] + (13, 0, 0) + (-1,)*3)

Why am I gaining an hour when converting to/from epoch timestamp? [duplicate]

I am dealing with dates in Python and I need to convert them to UTC timestamps to be used
inside Javascript. The following code does not work:
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(time.mktime(d.timetuple()))
datetime.datetime(2010, 12, 31, 23, 0)
Converting the date object first to datetime also does not help. I tried the example at this link from, but:
from pytz import utc, timezone
from datetime import datetime
from time import mktime
input_date = datetime(year=2011, month=1, day=15)
and now either:
mktime(utc.localize(input_date).utctimetuple())
or
mktime(timezone('US/Eastern').localize(input_date).utctimetuple())
does work.
So general question: how can I get a date converted to seconds since epoch according to UTC?
If d = date(2011, 1, 1) is in UTC:
>>> from datetime import datetime, date
>>> import calendar
>>> timestamp1 = calendar.timegm(d.timetuple())
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2011, 1, 1, 0, 0)
If d is in local timezone:
>>> import time
>>> timestamp2 = time.mktime(d.timetuple()) # DO NOT USE IT WITH UTC DATE
>>> datetime.fromtimestamp(timestamp2)
datetime.datetime(2011, 1, 1, 0, 0)
timestamp1 and timestamp2 may differ if midnight in the local timezone is not the same time instance as midnight in UTC.
mktime() may return a wrong result if d corresponds to an ambiguous local time (e.g., during DST transition) or if d is a past(future) date when the utc offset might have been different and the C mktime() has no access to the tz database on the given platform. You could use pytz module (e.g., via tzlocal.get_localzone()) to get access to the tz database on all platforms. Also, utcfromtimestamp() may fail and mktime() may return non-POSIX timestamp if "right" timezone is used.
To convert datetime.date object that represents date in UTC without calendar.timegm():
DAY = 24*60*60 # POSIX day in seconds (exact value)
timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * DAY
timestamp = (utc_date - date(1970, 1, 1)).days * DAY
How can I get a date converted to seconds since epoch according to UTC?
To convert datetime.datetime (not datetime.date) object that already represents time in UTC to the corresponding POSIX timestamp (a float).
Python 3.3+
datetime.timestamp():
from datetime import timezone
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
Note: It is necessary to supply timezone.utc explicitly otherwise .timestamp() assume that your naive datetime object is in local timezone.
Python 3 (< 3.3)
From the docs for datetime.utcfromtimestamp():
There is no method to obtain the timestamp from a datetime instance,
but POSIX timestamp corresponding to a datetime instance dt can be
easily calculated as follows. For a naive dt:
timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
And for an aware dt:
timestamp = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)
Interesting read: Epoch time vs. time of day on the difference between What time is it? and How many seconds have elapsed?
See also: datetime needs an "epoch" method
Python 2
To adapt the above code for Python 2:
timestamp = (dt - datetime(1970, 1, 1)).total_seconds()
where timedelta.total_seconds() is equivalent to (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 computed with true division enabled.
Example
from __future__ import division
from datetime import datetime, timedelta
def totimestamp(dt, epoch=datetime(1970,1,1)):
td = dt - epoch
# return td.total_seconds()
return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6
now = datetime.utcnow()
print now
print totimestamp(now)
Beware of floating-point issues.
Output
2012-01-08 15:34:10.022403
1326036850.02
How to convert an aware datetime object to POSIX timestamp
assert dt.tzinfo is not None and dt.utcoffset() is not None
timestamp = dt.timestamp() # Python 3.3+
On Python 3:
from datetime import datetime, timedelta, timezone
epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
timestamp = (dt - epoch) / timedelta(seconds=1)
integer_timestamp = (dt - epoch) // timedelta(seconds=1)
On Python 2:
# utc time = local time - utc offset
utc_naive = dt.replace(tzinfo=None) - dt.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()
For unix systems only:
>>> import datetime
>>> d = datetime.date(2011, 1, 1)
>>> d.strftime("%s") # <-- THIS IS THE CODE YOU WANT
'1293832800'
Note 1: dizzyf observed that this applies localized timezones. Don't use in production.
Note 2: Jakub Narębski noted that this ignores timezone information even for offset-aware datetime (tested for Python 2.7).
Assumption 1: You're attempting to convert a date to a timestamp, however since a date covers a 24 hour period, there isn't a single timestamp that represents that date. I'll assume that you want to represent the timestamp of that date at midnight (00:00:00.000).
Assumption 2: The date you present is not associated with a particular time zone, however you want to determine the offset from a particular time zone (UTC). Without knowing the time zone the date is in, it isn't possible to calculate a timestamp for a specific time zone. I'll assume that you want to treat the date as if it is in the local system time zone.
First, you can convert the date instance into a tuple representing the various time components using the timetuple() member:
dtt = d.timetuple() # time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1)
You can then convert that into a timestamp using time.mktime:
ts = time.mktime(dtt) # 1293868800.0
You can verify this method by testing it with the epoch time itself (1970-01-01), in which case the function should return the timezone offset for the local time zone on that date:
d = datetime.date(1970,1,1)
dtt = d.timetuple() # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=-1)
ts = time.mktime(dtt) # 28800.0
28800.0 is 8 hours, which would be correct for the Pacific time zone (where I'm at).
I defined my own two functions
utc_time2datetime(utc_time, tz=None)
datetime2utc_time(datetime)
here:
import time
import datetime
from pytz import timezone
import calendar
import pytz
def utc_time2datetime(utc_time, tz=None):
# convert utc time to utc datetime
utc_datetime = datetime.datetime.fromtimestamp(utc_time)
# add time zone to utc datetime
if tz is None:
tz_datetime = utc_datetime.astimezone(timezone('utc'))
else:
tz_datetime = utc_datetime.astimezone(tz)
return tz_datetime
def datetime2utc_time(datetime):
# add utc time zone if no time zone is set
if datetime.tzinfo is None:
datetime = datetime.replace(tzinfo=timezone('utc'))
# convert to utc time zone from whatever time zone the datetime is set to
utc_datetime = datetime.astimezone(timezone('utc')).replace(tzinfo=None)
# create a time tuple from datetime
utc_timetuple = utc_datetime.timetuple()
# create a time element from the tuple an add microseconds
utc_time = calendar.timegm(utc_timetuple) + datetime.microsecond / 1E6
return utc_time
follow the python2.7 document, you have to use calendar.timegm() instead of time.mktime()
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(calendar.timegm(d.timetuple()))
datetime.datetime(2011, 1, 1, 0, 0)
A complete time-string contains:
date
time
utcoffset [+HHMM or -HHMM]
For example:
1970-01-01 06:00:00 +0500 == 1970-01-01 01:00:00 +0000 == UNIX timestamp:3600
$ python3
>>> from datetime import datetime
>>> from calendar import timegm
>>> tm = '1970-01-01 06:00:00 +0500'
>>> fmt = '%Y-%m-%d %H:%M:%S %z'
>>> timegm(datetime.strptime(tm, fmt).utctimetuple())
3600
Note:
UNIX timestamp is a floating point number expressed in seconds since the epoch, in UTC.
Edit:
$ python3
>>> from datetime import datetime, timezone, timedelta
>>> from calendar import timegm
>>> dt = datetime(1970, 1, 1, 6, 0)
>>> tz = timezone(timedelta(hours=5))
>>> timegm(dt.replace(tzinfo=tz).utctimetuple())
3600
Using the arrow package:
>>> import arrow
>>> arrow.get(2010, 12, 31).timestamp
1293753600
>>> time.gmtime(1293753600)
time.struct_time(tm_year=2010, tm_mon=12, tm_mday=31,
tm_hour=0, tm_min=0, tm_sec=0,
tm_wday=4, tm_yday=365, tm_isdst=0)
the question is a little confused. timestamps are not UTC - they're a Unix thing. the date might be UTC? assuming it is, and if you're using Python 3.2+, simple-date makes this trivial:
>>> SimpleDate(date(2011,1,1), tz='utc').timestamp
1293840000.0
if you actually have the year, month and day you don't need to create the date:
>>> SimpleDate(2011,1,1, tz='utc').timestamp
1293840000.0
and if the date is in some other timezone (this matters because we're assuming midnight without an associated time):
>>> SimpleDate(date(2011,1,1), tz='America/New_York').timestamp
1293858000.0
[the idea behind simple-date is to collect all python's date and time stuff in one consistent class, so you can do any conversion. so, for example, it will also go the other way:
>>> SimpleDate(1293858000, tz='utc').date
datetime.date(2011, 1, 1)
]
Considering you have a datetime object called d,
use the following to get the timestamp in UTC:
d.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
And for the opposite direction, use following :
d = datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")
This works for me, pass through a function.
from datetime import timezone, datetime, timedelta
import datetime
def utc_converter(dt):
dt = datetime.datetime.now(timezone.utc)
utc_time = dt.replace(tzinfo=timezone.utc)
utc_timestamp = utc_time.timestamp()
return utc_timestamp
# create start and end timestamps
_now = datetime.datetime.now()
str_start = str(utc_converter(_now))
_end = _now + timedelta(seconds=10)
str_end = str(utc_converter(_end))
i'm impressed of the deep discussion.
my 2 cents:
from datetime import datetime
import time
the timestamp in utc is:
timestamp = \
(datetime.utcnow() - datetime(1970,1,1)).total_seconds()
or,
timestamp = time.time()
if now results from datetime.now(), in the same DST
utcoffset = (datetime.now() - datetime.utcnow()).total_seconds()
timestamp = \
(now - datetime(1970,1,1)).total_seconds() - utcoffset

Categories

Resources