0

I have an large 2D array contains seconds from year 2000, I want to convert to an array of datetime. I could not find a good way to do it. I used a loop. But it did not work and it produced an error as: TypeError: float() argument must be a string or a number, not 'datetime.datetime'

I give the example code as below. Would you please give me any suggestions? Thank you.

import numpy as np
import datetime as dt
secs_from_2000 = np.array([[6.833232e+08, 6.833233e+08, 6.833235e+08],   [6.833239e+08, 6.833242e+08, 6.833244e+08]])
dt_from_1970 = np.empty_like(secs_from_2000)
for i in range(secs_from_2000.shape[0]):
    for j in range(secs_from_2000.shape[1]):
         dt_from_1970[i,j] = dt.datetime.utcfromtimestamp((dt.datetime(2000,1,1)- dt.datetime(1970,1,1)).total_seconds() + secs_from_2000[i,j])

1 Answers1

1

There are three parts of this problem:

  1. Convert "seconds from 2000" to standard Unix timestamps (seconds after 1970)
  2. Convert Unix timestamp to datetime
  3. Do this for every element of the array

For 1, if we call the "seconds from 2000" figure t', and the standard Unix time is t, you can see that t - t' = x where x is a constant adjustment factor, such that t = t' + x (t' is what you have, t is what you want). Moreover, x is equal to the number of seconds between 1970 and 2000. Thus you can calculate it with:

>>> from datetime import datetime
>>> datetime(year=2000, month=1, day=1).timestamp()
946710000.0

Now you just have to add this to your t':

def unix_time(secs_from_2000: float) -> float:
    return secs_from_2000 + 946710000

For 3, I believe this is covered in Apply function to all elements in NumPy matrix so I won't duplicate it here.

Dommondke
  • 307
  • 1
  • 8
  • Thanks for answering my question. I calculated the difference between 2000 to 1970 with total_seconds() method. But when I try your code, I found that it gives me different timestamp for 2000: >>> from datetime import datetime >>> datetime(year=2000,month=1,day=1).timestamp() 946702800.0 Do you have any idea about this? – user13963660 Oct 19 '22 at 13:16
  • @user13963660 Ah, well I figured instantiating a `timedelta` is unnecessary in this case, so I cut that corner. But I didn't test it thoroughly (sorry) there might be some boundary conditions related to how exactly you define the "beginning of year 2000". So just tweak the params of that `datetime`. Is it off by a lot? If it's just a few seconds, could you just ignore the difference? – Dommondke Oct 19 '22 at 21:34
  • Oh actually I see now that the difference is `25200` sec, so exactly 7 hours. I think it's the timezone (Hello, Utah! :) ). IIRC Unix time is defined as "seconds after Jan 1, 1970 in **UTC**". So I guess you can consider that a hidden bug/side-effect in your implementation (if I'm not mistaken, my implementation conforms to accepted conventions w.r.t. Unix time). – Dommondke Oct 19 '22 at 21:39
  • You mean your datetime(year=2000, month=1, day=1).timestamp() gives the Utah time of 0 seconds at Jan 1, 2000? Since your code gives 7 hours more seconds than my code, it means when Utah enters Jan 1, 2000, the UTC time is already 7 hours past the start of Jan 1, 2000. So, my code gives the UTC time, which is what I need. This is a brain teaser for me. – user13963660 Oct 20 '22 at 01:47