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 Answer 1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

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 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?
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).
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.