1

Somewhat related to this question

I have a dictionary that looks something like

times = {
 'on': 
    {'start': datetime.time(6, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>), 
     'end': datetime.time(8, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>)}
 'off':
    {'start': datetime.time(10, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>), 
     'end': datetime.time(13, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>)}
}

calling str(times) gives

In[34]: str(f)
Out[34]: "{'on': {'start': datetime.time(6, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>), 'end': datetime.time(8, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>)}, 'off': {'start': datetime.time(10, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>), 'end': datetime.time(13, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>)}}"

when I would like the datetimes to output as

In[37]: str(times['on']['start'])
Out[37]: '06:00:00'

AKA:

"{'on': {'start': '06:00:00, 'end': '08:00:00'}, 'off': {'start': '10:00:00', 'end': '13:00:00'}}"

Is there a way to do this without creating a custom function?

4 Answers 4

2

This will do it:

str({k: {k1: str(v1) for k1, v1 in v.items()} for k, v in times.items()})

Output looks something like this:

"{'on': {'start': '10:01:00', 'end': '10:01:00'}, 'off': {'start': '10:01:00', 'end': '10:01:00'}}"

It's a little gross since you essentially have to un-pack and then re-pack a nested dictionary, but it works. For arbitrarily nested data, you would need a custom function.

Sign up to request clarification or add additional context in comments.

Comments

2

This is much easier and works for any arbitrary dictionary:

import json

times = { ... }
s = json.dumps(times, default=str)
print(s)

1 Comment

huh, I never knew about dumps(default=)
1

You need to use datetime.strftime() with format string as: "%H:%M:%S"

Hence, in order to update your dict, do:

for key, nested_dict in times.items():
    for k in nested_dict:
        nested_dict[k] = nested_dict[k].strftime("%H:%M:%S")

OR, use dict comprehension as:

{key: {k: v.strftime("%H:%M:%S") for k, v in nested_dict.items()} 
      for key, nested_dict in times.items()}

Comments

0

This is a great case for a subclass to control the string output of the time object:

You can do:

class MyTime(datetime.time):   
    def __repr__(self):
        return datetime.time.strftime(self, "%H:%M:%S")    


times = {
     'on': 
        {'start': MyTime(6, 0), 
         'end': MyTime(8, 0)},
     'off':
        {'start': MyTime(10, 0), 
         'end': MyTime(13, 0)}
    }

Then the formatting is automatic:

>>> times
{'on': {'start': 06:00:00, 'end': 08:00:00}, 'off': {'start': 10:00:00, 'end': 13:00:00}}

Yet the elements of your nested dict remain time objects:

>>> times['on']['start'].hour
6

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.