Convert numpy.datetime64 to string object in python

I am having trouble converting a python datetime64 object into a string. For example:

t = numpy.datetime64('2012-06-30T20:00:00.000000000-0400')

Into:

'2012.07.01' as a  string. (note time difference)

I have already tried to convert the datetime64 object to a datetime long then to a string, but I seem to get this error:

dt = t.astype(datetime.datetime) #1341100800000000000L
time.ctime(dt)
ValueError: unconvertible time
147712 次浏览

Solution was:

import pandas as pd
ts = pd.to_datetime(str(date))
d = ts.strftime('%Y.%m.%d')

There is a route without using pandas; but see caveat below.

Well, the t variable has a resolution of nanoseconds, which can be shown by inspection in python:

>>> numpy.dtype(t)
dtype('<M8[ns]')

This means that the integral value of this value is 10^9 times the UNIX timestamp. The value printed in your question gives that hint. Your best bet is to divide the integral value of t by 1 billion then you can use time.strftime:

>>> import time
>>> time.strftime("%Y.%m.%d", time.gmtime(t.astype(int)/1000000000))
2012.07.01

In using this, be conscious of two assumptions:

1) the datetime64 resolution is nanosecond

2) the time stored in datetime64 is in UTC

Side note 1: Interestingly, the numpy developers decided [1] that datetime64 object that has a resolution greater than microsecond will be cast to a long type, which explains why t.astype(datetime.datetime) yields 1341100800000000000L. The reason is that datetime.datetime object can't accurately represent a nanosecond or finer timescale, because the resolution supported by datetime.datetime is only microsecond.

Side note 2: Beware the different conventions between numpy 1.10 and earlier vs 1.11 and later:

  • in numpy <= 1.10, datetime64 is stored internally as UTC, and printed as local time. Parsing is assuming local time if no TZ is specified, otherwise the timezone offset is accounted for.

  • in numpy >= 1.11, datetime64 is stored internally as timezone-agnostic value (seconds since 1970-01-01 00:00 in unspecified timezone), and printed as such. Time parsing does not assume the timezone, although +NNNN style timezone shift is still permitted and that the value is converted to UTC.

[1]: https://github.com/numpy/numpy/blob/master/numpy/core/src/multiarray/datetime.c see routine convert_datetime_to_pyobject.

If you don't want to do that conversion gobbledygook and are ok with just one date format, this was the best solution for me

str(t)[:10]
Out[11]: '2012-07-01'

As noted this works for pandas too

df['d'].astype(str).str[:10]
df['d'].dt.strftime('%Y-%m-%d') # equivalent

I wanted an ISO 8601 formatted string without needing any extra dependencies. My numpy_array has a single element as a datetime64. With help from @Wirawan-Purwanto, I added just a bit:

from datetime import datetime


ts = numpy_array.values.astype(datetime)/1000000000
return datetime.utcfromtimestamp(ts).isoformat() # "2018-05-24T19:54:48"

You can use Numpy's datetime_as_string function. The unit='D' argument specifies the precision, in this case days.

 >>> t = numpy.datetime64('2012-06-30T20:00:00.000000000-0400')
>>> numpy.datetime_as_string(t, unit='D')
'2012-07-01'

Building on this answer I would do the following:

import numpy
import datetime
t = numpy.datetime64('2012-06-30T20:00:00.000000000')
datetime.datetime.fromtimestamp(t.item() / 10**9).strftime('%Y.%m.%d')

The division by a billion is to convert from nanoseconds to seconds.

Also, if someone want to apply same formula for any series of datetime dataframe then you can follow below steps

import pandas as pd


temp = []
for i in range(len(t["myDate"])):
ts = pd.to_datetime(str(t["myDate"].iloc[i]))
temp.append(ts.strftime('%Y-%m-%d'))
    

t["myDate"] = temp

t.item().strftime('%Y.%m.%d')

.item() will cast numpy.datetime64 to datetime.datetime, no need to import anything.

Here is a one liner (note the padding with extra zero's):

datetime.strptime(str(t),'%Y-%m-%dT%H:%M:%S.%f000').strftime("%Y-%m-%d")

code sample

import numpy
from datetime import datetime


t = numpy.datetime64('2012-06-30T20:00:00.000000000-0400')

method 1:

datetime.strptime(str(t),'%Y-%m-%dT%H:%M:%S.%f000').strftime("%Y-%m-%d")

method 2:

datetime.strptime(str(t)[:10], "%Y-%m-%d").strftime("%Y-%m-%d")

output

'2012-07-01'