datetime.timestamp not the same as seconds since 1970 - python

I think I'm misunderstanding something regarding datetime timestamps.
The descriptions I've read seem to say that a timestamp represents the Unix time (the number of seconds since 1970)
But when I run the following
import datetime
date = datetime.datetime(2020, 1 , 1, 0, 0, 0)
time1 = datetime.datetime.timestamp(date)
time2 = (date - datetime.datetime(1970,1,1,0,0,0)).total_seconds()
print(time1)
print(time2)
It prints:
1577862000.0
1577836800.0
Shouldn't these be the same? What am I misunderstanding?

Timezones. The unix epoch is Jan 1st 1970 in UTC, but your local zone is not UTC, so when you create a "naive" datetime instance using datetime.datetime(1970,1,1,0,0,0) it's offset from the real unix epoch by several hours.
Attach tzinfo=datetime.timezone.utc to both of the created datetime instances, and you'll see equality.
Alternatively, use datetime.datetime.fromtimestamp(0) instead of datetime.datetime(1970,1,1,0,0,0) to get a "naive" datetime instance coincident with the epoch.

Related

Difference between time.time() and datetime.utcnow()

I want to know about the difference between time.time() and datetime.datetime.utcnow(). Does both returns the current UTC time?
The time.time() function returns the number of seconds since the epoch, as seconds. Note that the "epoch" is defined as the start of January 1st, 1970 in UTC. So the epoch is defined in terms of UTC and establishes a global moment in time. No matter where you are "seconds past epoch" (time.time()) returns the same value at the same moment.
You can read more about time here.
Regarding datetime, datetime.datetime.utcnow() returns the current UTC date and time, with tzinfo None. This is like now(), but returns the current UTC date and time, as a naive datetime object. An aware current UTC datetime can be obtained by calling datetime.now(timezone.utc)
Here is some sample output I ran on my computer, converting it to a string as well:
>>> import time
>>> ts = time.time()
>>> print(ts)
1583748843.6486485
>>> import datetime
>>> st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
>>> print(st)
2020-03-09 12:14:03
Does both returns the current UTC time?
Yes and no.
The thing is how they return it.
Module datetime and classes in it (including datetime as class, which you use here) are for operating on date and time - thus they store the date/time in a structured form (object) and allow operations on it (methods).
>>> import datetime
>>> datetime.datetime.utcnow()
datetime.datetime(2020, 3, 9, 10, 4, 4, 284553)
While time module is more about straight C-like time operations. In this case: just returning timestamp (seconds from epoch) - as float (not a special class object).
>>> import time
>>> time.time()
1583748064.798787

Converting a UTC Time to Epoch format

I'm trying to convert a specific UTC time & date to seconds since the Epoch; however, I have not been able to figure out how to do this since I am not in the UTC time zone.
I tried using the datetime module to convert a date & time to seconds since the epoch, but python has been using my system's local time so the returned value is off by 7 hours. I understand that I could simply subtract 7*60 so that it would work in my time zone; however, I need this to work in multiple time zones without hardcoding the time change into my program.
This works except it uses the system time (MST), but I am looking for a solution that is specifically UTC time. Note the variables defined here represent an example of a time in UTC that I am trying to convert to seconds since the epoch.
import datetime
year=2019
month=5
day=9
hour=21
minute=45
Time=datetime.datetime(year, month, day, hour, minute).timestamp()
print(Time)
Output:
1557463500.0
Desired output (7 hours earlier):
1557438300.0
import datetime
year=2019
month=5
day=9
hour=21
minute=45
e = datetime.datetime(1970, 1, 1, 0, 0)
t = datetime.datetime(year, month, day, hour, minute)
print((t-e).total_seconds())
You can caclulate the timestamp of epoch date using datetime.datetime.utcfromtimestamp(0).timestamp() and then subtract your current timestamp from it
import datetime
year=2019
month=5
day=9
hour=21
minute=45
#Date timestamp
dt_timestamp=datetime.datetime(year, month, day, hour, minute).timestamp()
#Epoch timestamp
epoch = datetime.datetime.utcfromtimestamp(0).timestamp()
#Epoch
print(dt_timestamp-epoch)
The output will be
1557438300.0

how to covert date to milisecond in python

I have a date in this format 04-07-2018
the following Javascript produces
const date1 = new Date("04-07-2018").getTime();
date1; // 1523084400000
how do I parse the date and convert them to milliseconds in python
We can perform this in three steps:
first we convert the string to a datetime object;
next we calculate the difference between that datetime object and the first of January, 1970;
we calculate this difference in seconds, and then multiply it with 1000.
For example:
from datetime import datetime
def total_millis(text):
dt = datetime.strptime(text, '%m-%d-%Y')
return 1000 * (dt - datetime(1970, 1, 1)).total_seconds()
This implementation however is timezone independent, whereas the JavaScript version depends on the timezone.
The JavaScript getTime() method returns the number of milliseconds since January 1, 1970 00:00:00.
You can use datetime but you should compute it with a deltatime object since according to this Python doesn't guarantee any particular epoch time
import datetime
delta = datetime.datetime(2018, 4, 7) - datetime.datetime(1970, 1, 1)
milliseconds = delta.total_seconds()*1000 # 1523059200000.0

Determine date and time from a fixed date given seconds elapsed since fixed date in python

I need to determine a date given the seconds elapsed since said date.
I have the date in the format of YYYY-MM-DD hh:mm:ss and I am aware that it can be converted to a datetime.datetime() object as a good starting point but how can I use a date time object as a reference point and accurately derive the date by extrapolating a given number of seconds?
You can use the method timedelta of the datetime module like this:
import datetime
start_date = datetime.datetime(2017, 10, 19, 15, 0, 0)
new_date = start_date + datetime.timedelta(seconds=5*86400)
## adds 5 days = 5*86400 seconds
print(new_date)
Give the output
2017-10-24 15:00:00

Convert to UTC Timestamp

# parses some string into that format.
datetime1 = datetime.strptime(somestring, "%Y-%m-%dT%H:%M:%S")
# gets the seconds from the above date.
timestamp1 = time.mktime(datetime1.timetuple())
# adds milliseconds to the above seconds.
timeInMillis = int(timestamp1) * 1000
How do I (at any point in that code) turn the date into UTC format? I've been ploughing through the API for what seems like a century and cannot find anything that I can get working. Can anyone help? It's currently turning it into Eastern time i believe (however I'm in GMT but want UTC).
EDIT: I gave the answer to the guy with the closest to what I finally found out.
datetime1 = datetime.strptime(somestring, someformat)
timeInSeconds = calendar.timegm(datetime1.utctimetuple())
timeInMillis = timeInSeconds * 1000
:)
datetime.utcfromtimestamp is probably what you're looking for:
>>> timestamp1 = time.mktime(datetime.now().timetuple())
>>> timestamp1
1256049553.0
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2009, 10, 20, 14, 39, 13)
I think you can use the utcoffset() method:
utc_time = datetime1 - datetime1.utcoffset()
The docs give an example of this using the astimezone() method here.
Additionally, if you're going to be dealing with timezones, you might want to look into the PyTZ library which has lots of helpful tools for converting datetime's into various timezones (including between EST and UTC)
With PyTZ:
from datetime import datetime
import pytz
utc = pytz.utc
eastern = pytz.timezone('US/Eastern')
# Using datetime1 from the question
datetime1 = datetime.strptime(somestring, "%Y-%m-%dT%H:%M:%S")
# First, tell Python what timezone that string was in (you said Eastern)
eastern_time = eastern.localize(datetime1)
# Then convert it from Eastern to UTC
utc_time = eastern_time.astimezone(utc)
def getDateAndTime(seconds=None):
"""
Converts seconds since the Epoch to a time tuple expressing UTC.
When 'seconds' is not passed in, convert the current time instead.
:Parameters:
- `seconds`: time in seconds from the epoch.
:Return:
Time in UTC format.
"""
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(seconds))`
This converts local time to UTC
time.mktime(time.localtime(calendar.timegm(utc_time)))
http://feihonghsu.blogspot.com/2008/02/converting-from-local-time-to-utc.html
If converting a struct_time to seconds-since-the-epoch is done using mktime, this
conversion is in local timezone. There's no way to tell it to use any specific timezone, not even just UTC. The standard 'time' package always assumes that a time is in your local timezone.
You probably want one of these two:
import time
import datetime
from email.Utils import formatdate
rightnow = time.time()
utc = datetime.datetime.utcfromtimestamp(rightnow)
print utc
print formatdate(rightnow)
The two outputs look like this
2009-10-20 14:46:52.725000
Tue, 20 Oct 2009 14:46:52 -0000

Categories

Resources