25

How do I get the UNIX time from a numpy.datetime64 or numpy.datetime_?

As in for example:

np.datetime_('2012-08-08 13:37:00')
5
  • 1
    according to the docs datetime64 is not really reliable in numpy 1.6. Even for 1.7 the api is experimental. So I'm not sure, if you will get consistent results on different platforms and architectures (64bit?). Some more information is given in the pandas 0.8 release notes. So not sure, if it is a good choice to use datetime64 on numpy 1.6 at all. Commented Aug 8, 2012 at 16:49
  • Yeah okey, since the code is going to be experimental in itself and only reside in one machine it can be considered to work if it works once right ? Commented Aug 8, 2012 at 21:22
  • ok, but then you should specify numpy version, platform and architecture (maybe python version, same results on 2 and 3?) in your question. otherwise it could be misleading for somebody who reads it. Commented Aug 9, 2012 at 8:47
  • further more `np.datetime64('now') seems to only returns the date with my setup, no time information. Commented Aug 9, 2012 at 8:54
  • I'm actually not using the datetime64('now') at all, so I updated the question by replacing it with a constant time. Commented Aug 9, 2012 at 9:15

7 Answers 7

22

In order to account for the units, I think you need to do something like:

def get_unixtime(dt64):
    return dt64.astype('datetime64[s]').astype('int')

Note that this converts to 'seconds' (the [s]) prior to converting to integers. This works on NumPy 1.12.1.

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

Comments

11

numpy datetime64 has variable units:

Extracted from official doc:

The unit for internal storage is automatically selected from the form of the string, and can be either a date unit or a time unit. The date units are years (‘Y’), months (‘M’), weeks (‘W’), and days (‘D’), while the time units are hours (‘h’), minutes (‘m’), seconds (‘s’), milliseconds (‘ms’), and some additional SI-prefix seconds-based units.

So, first we need to check the current unit using dtype, for example:

>>> now = np.datetime64(datetime.datetime.now())
>>> now.dtype

# for ns unit, use:
dtype('<M8[ns]')
now.astype('int64')/1e9, dtype='int32'

# for us unit, use:
dtype('<M8[us]')
now.astype('int64')/1e6, dtype='int32'

# for ms unit, use:
dtype('<M8[ms]')
now.astype('int64')/1e3, dtype='int32'

and so on....

Comments

7

I wanted to post the solution I had found that I think might be a bit better than doing a conversion to uint as I feel there might be issues in that conversion of types.

>>> import numpy as np
>>> now = np.datetime64('now')
>>> ux_time = now.astype(np.timedelta64) / np.timedelta64(1, 'ms')

I feel this solution is a bit better since it allows you to choose your unix time units. For the project I'm working on we use 'ms' but you could specify a different unit if needed.

Additionally this allows intake of an array of datetime64 to convert to timedelta64 using numpy:

>>> date_time_array.astype(np.timedelta64) / np.timedelta64(1, 'ms')

I use this to translate np.datetime64 columns taken from pandas into unixtime arrays

Comments

6

I get inconsistent results for the value of np.datetime64('now') on numpy 1.6.1 vs. 1.7.

This works on both:

>>> import datetime
>>> import numpy as np
>>> now = np.datetime64(datetime.datetime.now())
>>> (now.astype('uint64') / 1e6).astype('uint32')
1344447810

8 Comments

I get 1344384000000000, 2 hours later ;-). I'm on a 64 bit machine and tz utc+2.
in 1.6.1 + Ubuntu, I get the 64-bit number, but on my mac with 1.7.0-dev, I get the 32-bit value..
@bmu updated answer - it appears to be different on 1.6.1 vs 1.7
I use series.astype(np.int64)
To get the current seconds since epoch you can do: np.datetime64('now').astype(uint32); no need for the datetime lib
|
1

First you have to know the storage units of the array. Then you view the array as a 64 bit integer and divide by the appropriate scaling factor to get back to seconds. For example if your datetime array is stored with storage units of microseconds (dtype=<M8[us]) you would do this:

unix_time = dtarray.view("i8") / 1e6

1 Comment

it should be noted that since the view doesn't create a copy, here changes to dtarray would also be reflected to unix_time.
0

Here's an extended and modified version of @farenorth 's answer, which allows to specify the precision of the output:

from datetime import datetime, timezone

import numpy as np
# np.__version__: '1.21.5'

def get_unixtime(dt64, unit='s'):
    return dt64.astype(f'datetime64[{unit}]').astype(np.int64)

print(datetime(2022,3,2,tzinfo=timezone.utc).timestamp())
# 1646179200.0 # unix time in seconds

dt = np.datetime64(datetime(2022,3,2)) # tz naive in numpy!

for unit in 's', 'ms', 'us', 'ns':
    print(f"precision: {unit}, -> {get_unixtime(dt, unit)}")

# precision: s, -> 1646179200
# precision: ms, -> 1646179200000
# precision: us, -> 1646179200000000
# precision: ns, -> 1646179200000000000

As a side-note, we cannot use int or 'int' (native Python type) here as that gives incorrect results. Related: Error when converting numpy.datetime64 to int.

Comments

-1
def get_unixtime(time):    
    return (time.astype(np.int64)/1e6).astype(np.int64)
get_unixtime(np.datetime64('now'))

Does seem to return the UNIX timestamp, I have only checked with a few dates.

4 Comments

Did you actually test this? I get 1344
I get 1344384000, 2 hours later ;-). I'm on a 64 bit machine and tz utc+2.
@jterrace, yes I tested, I'm running latest numpy on a 64bit Ubuntu also tested it on 64bit Vista. I get 1344384000
I get your value for 1.6.1, but I get a 32-bit value for 1.7.0

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.