Kilpatrick
Kilpatrick

Reputation: 177

Python: Convert Dictionary of String Times to Date Times

I have a dictionary alerts[] which includes the key alert_date. All dates/times are stored as strings. I am displaying the date in Django, but templates can't format time stored as a sting. So, I want to convert it in my view as such:

foo = "2014-10-07 00:00:00"
bar = datetime.strptime(foo, "%Y-%m-%d %H:%M:%S")

But, I want to convert all the dictionary time values at once. I'm grabbing the dictionary as JSON through an API call. I want to do something like this (which is obviously invalid code):

alerts = resp_data['alerts']
for v in alerts['alert_date']:
    v = datetime.strptime(v, "%Y-%m-%d %H:%M:%S")

//EDIT: The JSON response is a dictionary which contains alerts, which is a list of dictionaries as follows:

{"alerts": [
    {
      "key1": "value11",
      "key2": "value12",
      "key3": "value13",
      "alert_date": "2014-06-05 01:00:23.633000",
    },
    {
      "key1": "value21",
      "key2": "value22",
      "key3": "value23",
      "alert_date": "2010-12-31 00:00:00",
    }
]}

Upvotes: 7

Views: 19266

Answers (4)

Guilherme
Guilherme

Reputation: 1835

Recently I did something like this

On my case, the dict may have date object, or not

And I don't know the key of the date/datetime field

def convert_date_on_dict(old_dict):
    new_dict = {}
    for k, v in old_dict.items():
        if isinstance(v, (date, datetime)):
            new_dict[k] = v.strftime('%Y-%m-%d')
        else:
            new_dict[k] = v

    return new_dict

So...

for item in myDictList:
    new_item = convert_date_on_dict(item)

Upvotes: 0

dron22
dron22

Reputation: 1233

If I understood you correctly, you wanted to just change the date strings in the alerts list dictionaries and leave the other keys/values untouched. I would suggest the following:

from datetime import datetime

fmt = "%Y-%m-%d %H:%M:%S"
alerts = map(lambda x: dict(x, **{'alert_date': datetime.strptime(x['alert_date'], fmt)}), alerts)

If your date string format is inconsistent, like in your JSON Response example, you could drop the microsecond part by executing split():

from datetime import datetime

def convert(s):
    s = s.split('.')[0]
    return datetime.strptime(s, "%Y-%m-%d %H:%M:%S")

alerts = map(lambda x: dict(x, **{'alert_date': convert(x['alert_date'])}), alerts)

The resulting alerts lists for both examples look like this:

[{'alert_date': datetime.datetime(2014, 6, 5, 1, 0, 23),
  'key1': 'value11',
  'key2': 'value12',
  'key3': 'value13'},
 {'alert_date': datetime.datetime(2010, 12, 31, 0, 0),
  'key1': 'value21',
  'key2': 'value22',
  'key3': 'value23'}]

Upvotes: 0

DevLounge
DevLounge

Reputation: 8447

EDIT: now that you have added some sample json response data, I know that this answer is correct, alerts IS a list of dicts:

From your example, I now assume that:

  • alerts is a list of alert dictionaries
  • alert['alert_date'] is a date string

Therefore I would suggest you to do:

alerts = resp_data['alerts']
for alert in alerts:
    alert['alert_date'] = datetime.strptime(alert['alert_date'], "%Y-%m-%d %H:%M:%S")

Upvotes: 7

Kasravnd
Kasravnd

Reputation: 107347

You can use a dictionary comprehension:

new_dict = {datetime.strptime(key, "%Y-%m-%d %H:%M:%S"): val for key, val in alerts['alert_date'].items()}

Also note that, since you are using datetime.strptime with an specified format it might raise a ValueError. Which in that case the dict-comprehension won't be helpful. So if you are not sure about the fromat of your dates you need to handle the exceptions:

new_dict = {}
for k, v in alerts['alert_date'].items():
    try:
        new_dict[datetime.strptime(k, "%Y-%m-%d %H:%M:%S")] = v 
    except ValueError:
        new_dict[datetime.strptime(k, "%Y-%m-%d %H:%M:%S")] = '' # or what you want

Upvotes: 5

Related Questions