Convert numpy.datetime64 to string object in python
Asked Answered
L

11

86

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
Lyophilize answered 21/10, 2013 at 18:58 Comment(3)
Does #13704220 help your specific problem?Tracytrade
thanks, solution was: import pandas as pd ts = pd.to_datetime(str(date)) d = ts.strftime('%Y.%m.%d')Lyophilize
there is a simpler way, take a look at my answer belowGubernatorial
L
96

Solution was:

import pandas as pd 
ts = pd.to_datetime(str(date)) 
d = ts.strftime('%Y.%m.%d')
Lyophilize answered 21/10, 2013 at 19:32 Comment(3)
This doesn't work for some reason. numpy.datetime64' object has no attribute 'strftime'Paroxysm
@Paroxysm you need to run pd.to_datetime on the numpy.datetime64 object before doing .strftimeMonetmoneta
downvoted as it does not work with all values of datetime64 (for example, pd.to_datetime(np.datetime64('0000-01-01T00:00:00.000', 'ms')) returns Timestamp('1969-12-31 06:43:52.780800') , i.e. casts the type to datetime64[ns] silently). np.datetime_as_string (see jgrant's answer) works with all cases, and the name makes more sense to boot, I swear the pd.to_datetime is named for maximum confusion. Mind you, it will work in most common cases...Paramaribo
C
57

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
Condyloma answered 3/8, 2017 at 20:32 Comment(2)
That is madness! What a creative solution!Bind
This works on a pandas.Timestamp object as well, which is good for keeping nanosecond, or smaller, precision, as strftime does not support this level of precision.Chadwick
P
56

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'
Petrozavodsk answered 3/10, 2019 at 20:50 Comment(3)
numpy instead of numpyp. Or with import numpy as np just np.datetime....Lukasz
This is a great way to do it!Meraz
The real answer. No pandas needed, full support for time units other than 'ns' (meaning it has no problem with times way before BC in 'ms' resolution, like pandas.Timestamp), and overall "clearly the intended way"Paramaribo
G
9

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

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

Gubernatorial answered 2/11, 2021 at 1:45 Comment(2)
This is a bit confusing because datetime64[ns] item returns an integer in nanoseconds since 1970. One fix is t.astype('datetime64[s]').item().strftime()Kiddy
No. datetime64.item() will convert into int seconds.Overfeed
C
5

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.

Cursive answered 24/6, 2016 at 23:2 Comment(0)
Q
4

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.

Quartet answered 24/3, 2020 at 3:50 Comment(0)
B
3

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"
Bind answered 31/5, 2018 at 13:29 Comment(0)
C
1

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'
Cahoot answered 21/3, 2022 at 12:17 Comment(0)
G
0

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
Geek answered 19/10, 2021 at 11:53 Comment(0)
D
0
  • datetime objects can be converted to strings using the str() method
t.__str__()
Downcast answered 22/2, 2023 at 15:54 Comment(0)
E
0

The following will handle np.datetime64 objects of any units:

dt = np.datetime64('2002-06-08T00:00:00.000000000')
format_str = "%a, %d %b %Y"

formatted_str = dt.astype('datetime64[us]').item().strftime(format_str)

.astype('datetime64[us]') is required because if the resolution is datetime64[ns] (nanoseconds - the default for Pandas in many cases) or smaller, then .astype(datetime) returns an int. 'us' (microseconds) is the smallest unit that gets converted to a Python datetime.

.item() returns "a standard Python scalar", usually this means a float or int, but with dates it returns a Python datetime (depending on the unit), so you can get the right object without importing anything. .astype('O') also works.

Reference, this GitHub issue: https://github.com/numpy/numpy/issues/19782#issuecomment-908318335

Extranuclear answered 12/10, 2023 at 4:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.