-1

I'm actually looking for the opposite of this question: Converting string into datetime

I have a list of datetime objects and I want to create a human-friendly string from them, e.g., "Jan 27 and 30, Feb 4, 2012". Any ideas?

Note that strftime only works on a single datetime object. The problem here is that you have a list of datetimes that might not be evenly spaced, might cross month or year boundaries, but the entire range of dates has to be expressed in a single, concise string.

Community
  • 1
  • 1
Bob Donahue
  • 189
  • 2
  • 9
  • 4
    Have you looked at the `strftime` method? – Mark Ransom May 15 '12 at 21:29
  • That works for a single datetime object. I need to take a list of datetime objects and create a single string, e.g.: [(2012, 05, 23), (2012, 05, 30), (2012, 06, 06)] becomes 'Weds. May 23 - June 6, 2012' Converting a SINGLE datetime object is easy, as you pointed out. Converting a series of datetime objects that cross month or even year boundaries requires something more elegant. Before I spend the time/$$$ writing this, I thought it would be helpful to see if anyone else had come across a solution. – Bob Donahue May 17 '12 at 11:46
  • So you need to get the date range? like "from Jan 27 2011 to Jul 22 2013" ? – jadkik94 May 17 '12 at 11:57
  • 1
    This site is `StackOverflow.com`, not `WriteMyCodeForMe.com`. – Mark Ransom May 17 '12 at 14:02

2 Answers2

7

This.

your_date.isoformat() # -> '2002-03-11'
your_date.strftime("%A %d. %B %Y") # -> Monday 11. March 2002

UPDATE: You need list comprehension to do it in one line.

date_strings = [dt.strftime("%A %d. %B %Y") for dt in your_date_list]

Or, use a for loop:

date_strings = []
for dt in your_date_list:
    date_str.append(dt.strftime("%A %d. %B %Y"))

UPDATE 2: This I believe is closer to what you expect, but still what you want, only you knows it: when do you want to show the year, when not? when to show the month or the day only, etc... But this is basically an idea. You'll have maybe to do some kind of a class to represent the ranges, where you could choose the format there, comparing months and years between the ranges, ... That's what I came up with now. Hope it helps:

import datetime

# sample input
dates = [datetime.date(2012, 5, 21), datetime.date(2012, 5, 23),
        datetime.date(2012, 5, 25), datetime.date(2012, 5, 19),
        datetime.date(2012, 5, 17), datetime.date(2012, 5, 26),
        datetime.date(2012, 5, 18), datetime.date(2012, 5, 20)]

def get_consecutive_ranges(dates):
    dates = sorted(dates)

    delta_1day = datetime.timedelta(days=1)
    ranges = []
    last_d = dates[0]
    tmp_range = [last_d, None]
    for d in dates[1:]:
        if d-last_d <= delta_1day:
            # the difference between the dates is less than a day
            # we can extend the range, update the right-most boundary
            tmp_range[1] = d
        else:
            ranges.append(tmp_range)
            tmp_range = [d, None]
        last_d = d
    else:
        ranges.append(tmp_range)
    return ranges

ranges = get_consecutive_ranges(dates)

fmt = "%d %b %Y"

output = ", ".join([("%s" % (r[0].strftime(fmt),)) if r[1] is None else \
            ("%s-%s" % (r[0].strftime(fmt), r[1].strftime(fmt))) \
            for r in ranges])

print output
Community
  • 1
  • 1
jadkik94
  • 7,000
  • 2
  • 30
  • 39
  • Because I did read the docs, and you answered the wrong question. – Bob Donahue May 17 '12 at 11:45
  • I updated my answer. I'm sorry, you should have made your question clearer... :) You can always edit it if you like. – jadkik94 May 17 '12 at 11:52
  • Thanks. I've amended the question, but the problem is making the single string concise. It's not simply a matter of concatenating the list of converted individual dates. The situation is expressing a series of broadcasts on a site that only allows a very limited space to do so. So, while it's easy to get the list of, say, [(2012, 11, 28),(2012, 12, 5), (2012, 12, 12),(2012, 12, 19)], mangling that to "Nov. 28, Dec. 5-19, 2012" isn't straightforward (and even worse a month later when you have 2012 and 2013, etc." I'd be fine writing it up myself if the budget had time for me to do so. – Bob Donahue May 17 '12 at 11:57
  • I updated my code, but I think you need much more complicated than that :) I don't think you can find something like what you want (so customized) already done and ready anywhere... Anyway, hope it helps. – jadkik94 May 17 '12 at 12:34
  • I think I need something more robust, but your code is VERY HELPFUL in terms of giving me some ideas. Thanks! – Bob Donahue May 24 '12 at 13:20
  • @BobDonahue You're welcome. Actually, I was very interested with the question and I came up with a bit more developed [code](http://pastebin.com/2PY52DCD) than this. But I gave up :D. I hope that helps a little more. – jadkik94 May 24 '12 at 13:36
1
>>> dt=datetime.date(2012,2,4)
>>> dt.strftime('%A %B %d, %Y')
'Saturday February 04, 2012'
the wolf
  • 34,510
  • 13
  • 53
  • 71
  • 1
    Yes, that works for a SINGLE datetime object. The issue is that it's a range of dates (which might or might not be evenly spaced, might cross month boundaries, might cross year boundaries etc. that needs to be encapsulated into a single string. So, strftime isn't helpful. Sorry if I didn't express the issue more clearly. – Bob Donahue May 17 '12 at 11:53