1

I created a dictionary and was trying to dump it as a json file, but had problems due to the type of the key being a datetime.

In my researches I found solutions for the values but not for the keys.

Heres the code I have for now:

import json
from datetime import date, datetime

d = {
    datetime.now(): {
        'name' : 'Foo'
    }
}

def myconverter(o):
    if isinstance(o, datetime):
        return o.isoformat()

print(d)

print(json.dumps(d, default=myconverter, indent=4))

Error message: TypeError: keys must be str, int, float, bool or None, not datetime

By the way, this is an example, the original dictionary really needs to be indexed by the datetime. If it's really impossible I will consider using timestamp, but I prefer to avoid because it is unreadable

luix10
  • 49
  • 8
  • 1
    Please include the actual error message. Can you share a bit more information on your data? I’m particularly curious about the circumstances which lead to using datetime objects as keys in a dictionary. – AMC Dec 24 '19 at 02:42
  • trying to analyze a cryptocurrency exchange data - candles to be more specific – luix10 Dec 24 '19 at 02:49
  • So your data is like a time series? – AMC Dec 24 '19 at 02:50
  • You can say yes. The thing is that i'm trying to store the data I get from the api using the given datetime of the candle as as key because you can get the new version of the same candle multiple times while its not closed – luix10 Dec 24 '19 at 02:55
  • In what format does the API return data? – AMC Dec 24 '19 at 02:56
  • its a json from a rest call, so, a tring like this "timestamp": "2019-01-01T00:15:00.000Z", – luix10 Dec 24 '19 at 03:04
  • 2
    JSON keys *must* be JSON strings. – juanpa.arrivillaga Dec 24 '19 at 03:11
  • @luix10 What does the rest look like? I’m trying to figure out whether or not you’re better off using something like Pandas. – AMC Dec 24 '19 at 03:31
  • Potentially useful (and late) related question: https://stackoverflow.com/q/11875770/11301900. – AMC Jan 02 '20 at 23:59

1 Answers1

1

If you want to keep the original dictionary with datetime objects as keys just create a copy with the datetime serialized just for storing:

d = {
    datetime.now(): {
        'name' : 'Foo'
    }
}

serialized_d = {k.isoformat(): v for k, v in d.items()}

print(json.dumps(serialized_d, indent=4))

>>> {
    "2019-12-23T22:56:15.768500": {
        "name": "Foo"
    }
}

marcos
  • 4,473
  • 1
  • 10
  • 24
  • was trying to avoid change the type for the dictionary due to some ordering and other operations using the datetime to index. The main goal was to change the data type only to store since it looks easy task when storing datetime values for a dictionary – luix10 Dec 24 '19 at 03:07
  • edited @luix10, for storing purposes you can't save it in a `json` as a `datetime` object, it needs to be a `string`. – marcos Dec 24 '19 at 03:28
  • @AMC i'm getting `TypeError` when using his code, so it means that `default` is not running. – marcos Dec 24 '19 at 03:45
  • 1
    `json.dumps(d, default=myconverter, indent=4)` raises `TypeError` because `datetime` object cannot be used as a key in a `json`, it needs to be serialized first, the `default` parameter in `json.dumps` is not doing anything there, the function `myconverter` is not running. @AMC – marcos Dec 24 '19 at 03:48
  • @Marcos Oh yes, I know. My first comment on this answer was in response to the OP writing _The main goal was to change the data type only to store..._ because it looked to me like that’s indeed what your code is doing. – AMC Dec 24 '19 at 04:55
  • for some reason I didn't realize at first, but you give me the right answer! thanks and sorry for the confusion! With that i can still work with my dictionary and store it the way I intended!!! – luix10 Dec 24 '19 at 17:38