31

I have a datetime64 t that I'd like to represent as a string.

When I call strftime like this t.strftime('%Y.%m.%d') I get this error:

AttributeError: 'numpy.datetime64' object has no attribute 'strftime'

What am I missing? I am using Python 3.4.2 and Numpy 1.9.1

deeb
  • 1,242
  • 4
  • 15
  • 27
  • Are you wanting to use `datetime.datetime.strftime` instead? so `import datetime as dt dt.datetime.strftime(t, '%Y.%m.%d')` I think should work – EdChum Feb 04 '15 at 17:01
  • 1
    I saw examples that looked like datetime64 had a strftime method itself. I tried your solution and got this: `TypeError: descriptor 'strftime' requires a 'datetime.date' object but received a 'numpy.datetime64'` – deeb Feb 04 '15 at 17:04
  • duplicate http://stackoverflow.com/questions/19502506/convert-numpy-datetime64-to-string-object-in-python ? (though `str(dt)` may be all you need?) – Andy Hayden Feb 04 '15 at 17:18
  • Andy, that is the solution I am trying to implement but I can't call the `ts.strftime` part for some reason. – deeb Feb 04 '15 at 17:25

6 Answers6

43

Importing a data structures library like pandas to accomplish type conversion feels like overkill to me. You can achieve the same thing with the standard datetime module:

import numpy as np
import datetime
t = np.datetime64('2017-10-26')
t = t.astype(datetime.datetime)
timestring = t.strftime('%Y.%m.%d')
apteryx
  • 1,005
  • 7
  • 14
  • 16
    This should be the accepted answer. It would be ridiculous to have Pandas as a project dependency just to convert a date. – titusjan May 21 '18 at 12:22
  • It would be even more ridiculous to have Pandas as a project dependency to _print_ a date. – Joooeey Nov 21 '18 at 22:08
  • 2
    It should also be noted that this is actually also a significantly faster method. Using timeit I found `t.astype(datetime.datetime).strftime('%Y.%m.%d')` took 5.86 µs ± 339 ns per loop while `pd.to_datetime(t).strftime('%Y.%m.%d')` took 35.8 µs ± 252 ns per loop. – n8yoder Apr 18 '19 at 17:47
  • 1
    `astype()` was giving me a hassle dealing with a `datetime` I added to a Pandas DF (lots of type conversion here), and `pd.to_datetime()` worked perfectly. – xtian Sep 20 '20 at 20:11
  • 1
    I'd agree with @titusjan, but somehow i was getting int by t.astype(datetime.datetime) in my particular case, where np.datetime64 is comming from part of xarray . In my particular case user-12321 method made more sense. pandas seems to have more thorough handling of datetime related objects – yosukesabai Jan 05 '21 at 20:59
35

Use this code:

import pandas as pd 
t= pd.to_datetime(str(date)) 
timestring = t.strftime('%Y.%m.%d')
user 12321
  • 2,658
  • 1
  • 22
  • 34
  • 2
    I am doing this but strftime is not defined – deeb Feb 04 '15 at 23:45
  • 1
    @deeb before using `strftime` convert your object to pandas datetime using `pd.to_datetime(x)` otherwise it will be considered as an numpy.datetime64 – Ikbel Apr 26 '19 at 12:48
14

This is the simplest way:

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

item() gives you a Python native datetime object, on which all the usual methods are available.

John Zwinck
  • 223,042
  • 33
  • 293
  • 407
  • I think this is an even better solution than explicitly using the built-in `datetime` module. – Fanchen Bao Jan 23 '21 at 00:04
  • 2
    I get this error on my `numpy.datetime64('2021-11-01T00:00:00.000000000')` : `AttributeError: 'int' object has no attribute 'strftime' ` – SCool Nov 09 '21 at 16:02
  • @SCool: Your issue is explained in David Wasserman's answer here, which is that nanosecond-precision timestamps are not supported by the Python standard library, so `item()` on your type (which is sometimes known as `m8[ns]` gives an integer rather than a datetime. If you use 6 or fewer digits after the decimal, it will work. – John Zwinck Nov 11 '21 at 12:50
4

If your goal is only to represent t as a string, the simplest solution is str(t). If you want it in a specific format, you should use one of the solutions above.

One caveat is that np.datetime64 can have different amounts of precision. If t has nanosecond precision, user 12321's solution will still work, but apteryx's and John Zwinck's solutions won't, because t.astype(datetime.datetime) and t.item() return an int:

import numpy as np

print('second precision')
t = np.datetime64('2000-01-01 00:00:00') 
print(t)
print(t.astype(datetime.datetime))
print(t.item())

print('microsecond precision')
t = np.datetime64('2000-01-01 00:00:00.0000') 
print(t)
print(t.astype(datetime.datetime))
print(t.item())

print('nanosecond precision')
t = np.datetime64('2000-01-01 00:00:00.0000000') 
print(t)
print(t.astype(datetime.datetime))
print(t.item())
import pandas as pd 
print(pd.to_datetime(str(t)))


second precision
2000-01-01T00:00:00
2000-01-01 00:00:00
2000-01-01 00:00:00
microsecond precision
2000-01-01T00:00:00.000000
2000-01-01 00:00:00
2000-01-01 00:00:00
nanosecond precision
2000-01-01T00:00:00.000000000
946684800000000000
946684800000000000
2000-01-01 00:00:00
David Wasserman
  • 411
  • 3
  • 9
  • 2
    I have made this [an issue](https://github.com/numpy/numpy/issues/18363) since it should be a bug. Also, another way to get the correct datetime is the (ugly) workaround: `t.astype('datetime64[us]').astype(datetime.datetime)` if you do not want to use pandas – Gevaert Joep Feb 08 '21 at 12:39
  • Thanks a lot for this workaround @GevaertJoep !! (it's rare to find something that useful in a comment of the last answer) I was about to give up and use the slower panda method – jmd Jul 27 '21 at 16:16
4

For those who might stumble upon this: numpy now has a numpy.datetime_as_string function. Only caveat is that it accepts an array rather than just an individual value. I could make however that this is still a better solution than having to use another library just to do the conversion.

adrianp
  • 979
  • 1
  • 7
  • 13
  • 2
    But `numpy.datetime_as_string` does not seem to support formatting of the output string, which makes it less useful than the other methods leveraging the built-in `datetime` object. – Fanchen Bao Jan 23 '21 at 00:07
0

It might help to convert the datetime object to string and use splitting as shown below:

dtObj = 2011-08-01T00:00:00.000000000

dtString = str(dtObj).split('-01T00:00:00.000000000')[0]

print(dtString)

>>> '2011-08-01'

moinabyssinia
  • 127
  • 1
  • 9