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')
SlimJim
  • 2,264
  • 2
  • 22
  • 25
  • 1
    according to the docs datetime64 is not really reliable in [numpy 1.6](http://docs.scipy.org/doc/numpy/reference/arrays.datetime.html#differences-between-1-6-and-1-7-datetimes). 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](http://pandas.pydata.org/pandas-docs/dev/whatsnew.html#potential-porting-issues-for-pandas-0-7-3-users). So not sure, if it is a good choice to use datetime64 on numpy 1.6 at all. – bmu Aug 08 '12 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 ? – SlimJim Aug 08 '12 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. – bmu Aug 09 '12 at 08:47
  • further more `np.datetime64('now') seems to only returns the date with my setup, no time information. – bmu Aug 09 '12 at 08:54
  • I'm actually not using the datetime64('now') at all, so I updated the question by replacing it with a constant time. – SlimJim Aug 09 '12 at 09:15

7 Answers7

20

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.

farenorth
  • 10,165
  • 2
  • 39
  • 45
10

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

uxtechie
  • 724
  • 6
  • 7
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

Slydog
  • 71
  • 1
  • 1
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
jterrace
  • 64,866
  • 22
  • 157
  • 202
  • 1
    I get 1344384000000000, 2 hours later ;-). I'm on a 64 bit machine and tz utc+2. – bmu Aug 08 '12 at 16:36
  • 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.. – jterrace Aug 08 '12 at 21:34
  • @bmu updated answer - it appears to be different on 1.6.1 vs 1.7 – jterrace Aug 08 '12 at 21:43
  • I use series.astype(np.int64) – Martin Tapp Aug 15 '16 at 18:46
  • To get the current seconds since epoch you can do: `np.datetime64('now').astype(uint32)`; no need for the datetime lib – zingi Mar 30 '20 at 13:15
  • @zingi that does seem to work, but is it documented anywhere? I don't see it anywhere [here](https://docs.scipy.org/doc/numpy/reference/arrays.datetime.html). – jterrace Mar 31 '20 at 20:15
  • @jterrace It is true, that it is poorly documented. There are hints in the [code](https://github.com/numpy/numpy/blob/65828136fa42188115691475e8736cae089e2113/numpy/core/src/multiarray/datetime_strings.c#L202) – zingi Apr 01 '20 at 06:55
  • And I saw that I had forgotten a `np` in the original comment. This should work: `np.datetime64('now').astype(np.uint32)` – zingi Apr 01 '20 at 07:01
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
RBF06
  • 2,013
  • 2
  • 21
  • 20
  • it should be noted that since the view doesn't create a copy, here changes to `dtarray` would also be reflected to `unix_time`. – FObersteiner Jan 27 '21 at 07:31
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.

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
-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.

SlimJim
  • 2,264
  • 2
  • 22
  • 25