is there any elegant way to make Python JSON encoder support datetime? some 3rd party module or easy hack?
I am using tornado\'s database wrapper to fetch some rows
Convert the datetime type into a unix timestamp, then encode the contents into a json.
e.g. : http://codepad.org/k3qF09Kr
Create a custom decoder/encoder:
class CustomJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return http_date(obj)
if isinstance(obj, uuid.UUID):
return str(obj)
return json.JSONEncoder.default(self, obj)
class CustomJSONDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
json.JSONDecoder.__init__(self, object_hook=self.object_hook, *args, **kwargs)
def object_hook(self, source):
for k, v in source.items():
if isinstance(v, str):
try:
source[k] = datetime.datetime.strptime(str(v), '%a, %d %b %Y %H:%M:%S %Z')
except:
pass
return source
Just create a custom encoder
(the small but important addition to Cole's answer is the handling of pd.NaT (or null/empty timestamp values), since without the addition you will get very weird timestamp conversions for NaT/missing timestamp data)
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if pd.isnull(obj):
return None
elif isinstance(obj, datetime):
return obj.isoformat()
elif isinstance(obj, date):
return obj.isoformat()
elif isinstance(obj, timedelta):
return (datetime.min + obj).time().isoformat()
else:
return super(CustomEncoder, self).default(obj)
Then use it to encode a dataframe:
df_as_dict = df.to_dict(outtype = 'records') # transform to dict
df_as_json = CustomEncoder().encode(df_as_dict) #transform to json
Since the encoder standardized the data, the regular decoder will act fine in transforming it back to a dataframe:
result_as_dict = json.JSONDecoder().decode(df_as_json) # decode back to dict
result_df = pd.DataFrame(result) # transform dict back to dataframe
Of course this will also work if you put the dataframe into a larger dict before encoding, e.g
input_dict = {'key_1':val_1,'key_2':val_2,...,'df_as_dict':df_as_dict}
input_json = CustomEncoder().encode(input_dict)
input_json_back_as_dict = json.JSONDecoder().decode(input_json)
input_df_back_as_dict = input_json_back_as_dict['df_as_dict']
input_df_back_as_df = pd.DataFrame(input_df_back_as_dict)