Reputation: 41
I want to convert a precise ordinal time array (see below) to date-time format (YYYY-MM-DD hh:mm:ss.sss) in anaconda/python 3. I cannot find any solutions to this problem that considers the precision of the original data.
The ordinal time array looks like:
[[733414.07083333]
[733414.07430556]
[733414.07777778]
...
[737654.10902778]
[737654.1125 ]
[737654.11597222]]
datetime.fromordinal
only works for integer numbers and the decimals MUST be considered in order to obtain the time component to the decimal second.
Upvotes: 1
Views: 2722
Reputation: 103
I was facing a similar issue and found a faster way to convert from ordinal to datetime, which is done in your first function.
import datetime
def OrdinalToDatetime(ordinal):
plaindate = datetime.date.fromordinal(int(ordinal))
date_time = datetime.datetime.combine(plaindate, datetime.datetime.min.time())
return date_time + datetime.timedelta(days=ordinal-int(ordinal))
The output would be in case of today OrdinalToDatetime(737998.46643556)
Out[1]: datetime.datetime(2021, 7, 27, 11, 11, 40, 32386)
Upvotes: 1
Reputation: 41
Thanks to a tip from a friend, who directed me to another website (https://www.programcreek.com/python/example/100062/datetime.datetime.fromordinal), I have found a solution to this challenge. This is the modified script that I used to convert ordinal time to date-time:
import numpy as _np
import datetime
from datetime import date
def _from_ordinal(x, tz=None) :
ix = int(x)
dt = date.fromordinal(ix)
remainder = float(x) - ix
hour, remainder = divmod(24 * remainder, 1)
minute, remainder = divmod(60 * remainder, 1)
second, remainder = divmod(60 * remainder, 1)
microsecond = int(1e6 * remainder)
# compensate for rounding errors
if microsecond < 10 :
microsecond = 0
elif microsecond > 999990 :
microsecond = _np.subtract(1000000,microsecond)
dt = datetime.datetime(dt.year, dt.month, dt.day, int(hour), int(minute), int(second), microsecond)
dt = dt.isoformat(timespec='microseconds')
if tz is not None:
dt = dt.astimezone(tz)
return dt
arrayDateTime = []
for i in range(0,len(arrayOrdinalTime)) :
dateTime = _from_ordinal(arrayOrdinalTime[i])
dateTime = dateTime.replace('T', ' ')
arrayDateTime = _np.append(arrayDateTime, dateTime)
Please note, because of the for-loop in this script, processing can take a long time if teh data set is large. I tried to make this work directly with an array, but it failed.
Any tips to make this work directly with an array, therefore to save time, would be appreciated.
Upvotes: 1