How to handle time.time() in Python? - python

I'm trying to collect real-time data with hdf5, but it doesn't support datetime for now, so I thought np.float64(timestamp) would be a better option than simple strings, from the standpoint of storage efficiency(8bits vs more than 8 bits). I want to record event times with microsecond precision.
From these web pages(https://docs.python.org/3/library/time.html, https://pymotw.com/2/time/index.html), I read that timestamps that I get by time.time() is calculated in UTC, but now I think something's different from what I read.
from datetime import datetime
import time
print( datetime.utcnow() )
print( datetime.fromtimestamp( time.time() ) )
>>> (executing file "<tmp 2>")
2018-03-16 21:28:34.716853
2018-03-17 06:28:34.716854
I don't understand why they are different. If timestamps are calculated in UTC, I think they should be the same.
I have another question. I'd like to know how to add some amount of time to timestamps. For example, I want to know how to do this with timestamps.
datetime.utcnow() + timedelta(hours=3)

datetime.utcnow() is the utc time, datetime.fromtimestamp() is the local time, which depends on your time zone.
To add to timestamp, you just need to convert the timedelta to seconds:
time.time() + timedelta(hours=3).total_seconds()

Related

What time format is this? I don't think it's unix timestamp

Hello I'm coding a script to fetch creation dates of specific profiles on a platform what time format is this?
1396752197709867
If it's microseconds then you can convert them to seconds, and use fromtimestamp() to convert seconds since the UNIX epoch to a datetime object.
This is explained in this answer to the question How to convert microsecond timestamp to readable date?
import datetime
timestamp_microseconds = 1396752197709867
timestamp_seconds = timestamp_microseconds/1000000
dobj = datetime.datetime.fromtimestamp(timestamp_seconds)
print(dobj.isoformat()) # -> 2014-04-05T19:43:17.709867

How to convert from Unix epoch time and account for daylight saving time in Python?

I have a large database with thousands of records. Each record contains a Unix epoch time.
The database was created in a single time zone, but that time zone has "daylight saving time" during which the local time is adjusted by an hour for several months.
In Python, I want to convert all those epoch times to the correct local time in that time zone, taking into account "daylight saving time". I am new to Python.
Important: Some of the dates were recorded during "daylight saving time" and some of the dates were recorded during "standard time".
Currently, my code is:
import time
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time_from_database))
(where time_from_database is the Unix epoch time obtained from the database)
How can this be achieved in Python?
The operating system has support for time zone conversions, and Python can use that. You don't need to handle it in your Python code.
You get to it using the pytz module. It is also preferred to use the datetime object.
import pytz
from datetime import datetime
MYTZ = "America/Los_Angeles"
TS = 1631491515.6691816
tzinfo = pytz.timezone(MYTZ)
t = datetime.fromtimestamp(TS, tzinfo)
print(t)
2021-09-12 17:05:15.669182-07:00

python: utcfromtimestamp vs fromtimestamp, when the timestamp is based on utcnow()

Pretty sure it's an easy one but I don't get it.
My local TZ is currently GMT+3, and when I take timestamp from datetime.utcnow().timestamp() it is indeed giving me 3 hours less than datetime.now().timestamp()
During another process in my flow, I take that utc timestamp and need to turn it into datetime.
When I'm doing fromtimestamp I get the right utc hour, but when I'm using utcfromtimestamp I get another 3 hours offset.
The documentation, though, asks me to use fromtimestamp for local timezone, and utcfromtimestamp for utc usages.
What am I missing ? is the initial assumption for both funcs is that the timestamp is given in local timezone ?
Thank you :)
The key thing to notice when working with datetime objects and their POSIX timestamps (Unix time) at the same time is that naive datetime objects (the ones without time zone information) are assumed by Python to refer to local time (OS setting). In contrast, a POSIX timestamp (should) always refer to seconds since the epoch UTC. You can unambiguously obtain that e.g. from time.time(). In your example, not-so-obvious things happen:
datetime.now().timestamp() - now() gives you a naive datetime object that resembles local time. If you call for the timestamp(), Python converts the datetime to UTC and calculates the timestamp for that.
datetime.utcnow().timestamp() - utcnow() gives you a naive datetime object that resembles UTC. However, if you call timestamp(), Python assumes (since naive) that the datetime is local time - and converts to UTC again before calculating the timestamp! The resulting timestamp is therefore off from UTC by twice your local time's UTC offset.
A code example. Let's make some timestamps. Note that I'm on UTC+2 (CEST), so offset is -7200 s.
import time
from datetime import datetime, timezone
ts_ref = time.time() # reference POSIX timestamp
ts_utcnow = datetime.utcnow().timestamp() # dt obj UTC but naive - so also assumed local
ts_now = datetime.now().timestamp() # dt obj naive, assumed local
ts_loc_utc = datetime.now(tz=timezone.utc).timestamp() # dt obj localized to UTC
print(int(ts_utcnow - ts_ref))
# -7200 # -> ts_utcnow doesn't refer to UTC!
print(int(ts_now - ts_ref))
# 0 # -> correct
print(int(ts_loc_utc - ts_ref))
# 0 # -> correct
I hope this clarifies that if you call datetime.utcfromtimestamp(ts_utcnow), you get double the local time's UTC offset. Python assumes (which I think is pretty sane) that the timestamp refers to UTC - which in fact, it does not.
My suggestion would be to use timezone-aware datetime objects; like datetime.now(tz=timezone.utc). If you're working with time zones, the dateutil library or Python 3.9's zoneinfo module are very helpful. And if you want to dig deep, have a look at the datetime src code.

Convert Cocoa timestamp in Python

I have a Cocoa timestamp (zero time of January 1st, 2001 00:00:00 UTC) that I need to convert in Python. When I use the following code it assumes a Unix timestamp input. Besides adding 31 years in seconds (Just under a billion seconds...) what's the best way to convert the time?
import datetime
print(datetime.datetime.fromtimestamp(int("495759456")).strftime('%Y-%m-%d %H:%M:%S'))
The output for this line of code is '1985-09-16 16:12:03'
Would something like this work for you:
from datetime import datetime
unix = datetime(1970, 1, 1) # UTC
cocoa = datetime(2001, 1, 1) # UTC
delta = cocoa - unix # timedelta instance
timestamp = datetime.fromtimestamp(int("495759456")) + delta
print(timestamp.strftime('%Y-%m-%d %H:%M:%S'))
I didn't specify timezone information for the two starts of time as they're in the same zone so I assume it shouldn't matter which is used when computing the difference. For converting the timestamp string, you may need to adjust for your timezone if it's different than the one in which the string was generated.
The above code produces 2016-09-16 15:57:36
One thing to be careful on when doing the conversion with the above solution, is to make sure that the Cocoa timestamp's unit is the same as the one you'd want in the unix timestamp. I've noticed that at many instance the cocoa timestamp is stored in nano seconds.
Unless you want your Unix timestamp to also be represented as nano seconds, make sure to do divide the cocoa timestamp by the appropriate number before conversion. e.g. Divide by 1000000000 to convert nano seconds to seconds etc...
Source

Python / Mongoengine - Timezone missing when saved to database?

I'm having some trouble saving a date object to Mongo using MongoEngine. Here is my code:
print isodate
>>> 2014-07-01T20:00:00.000Z
import pytz
from dateutil import parser
tz = pytz.timezone('Europe/London')
start = parser.parse(isodate).replace(tzinfo=None)
start = tz.localize(start)
print start
>>> 2014-07-01 20:00:00+01:00
Localizing the date seems to work fine, but when saving to Mongo:
f = Fixture(
start=start
)
The following strangeness is happening when I look at the Mongo document created:
{
_id: ObjectId("53b1dfbde20b47102c824a8f"),
start: ISODate("2014-07-01T19:00:00Z")
}
Is there any reason why the time is off by two hours, and the timezone is no longer present?
I feel you misunderstood date time format. Refer to W3C Date and Time Formats:
Times are expressed in UTC (Coordinated Universal Time), with a special UTC designator ("Z").
Times are expressed in local time, together with a time zone offset in hours and minutes. A time zone offset of "+hh:mm" indicates that the date/time uses a local time zone which is "hh" hours and "mm" minutes ahead of UTC. A time zone offset of "-hh:mm" indicates that the date/time uses a local time zone which is "hh" hours and "mm" minutes behind UTC.
"2014-07-01T20:00:00.000Z" should equal to "2014-07-01 21:00:00+01:00". So it went wrong in localizing datetime, not in saving to Mongo.
If you want to convert "....T....Z" to local time, you can try this:
print isodate
>>> 2014-07-01T20:00:00.000Z
import pytz
from dateutil import parser
local_tz = pytz.timezone('Europe/London')
local_time = parser.parse(isodate).astimezone(local_tz)
print local_time
>>> 2014-07-01 21:00:00+01:00
If you need to perform date arithmetic on local times, do one more step (refer: pytz doc):
local_tz.normalize(local_time)
Actually you can directly save "....T....Z" ISODate into Mongo without converting to local time. Since it already contains timezone info, converting is unnecessary.

Categories