質問

Currently I'm working on a command line program and there I print out dates.

I do this with datetime.datetime.strftime:

import datetime

d = datetime.datetime(2012,12,12)
date_str = d.strftime(config.output_str)

Where config.output_str is a format string that can be set by the user.

Is there a way to tell how long the string date_str will be at maximum?

Especially if a format string like u'%d %B %Y' is used, where the length of the month (%B) depends on the language of the user?

役に立ちましたか?

解決

If you are not setting the locale with the locale module, then Python uses the C locale and you can predict the maximum length produced. All strings will be in English and the maximum length per format character is known.

Parse the string yourself, count the non-format characters and map format characters to the maximum length for that field.

If you were to use locale, you'll need to calculate the max length per language. You can automate the locale-dependent fields by looping over the months, weekdays, and AM/PM and measuring the max length for the %a, %A, %b, %B, %c, %p, %x and %X formats. I'd do that on the fly as needed.

The rest of the formats do not vary by locale and have a documented maximum length (the examples in the strptime table are typical, you can rely on those documenting the field length).

他のヒント

Here the solution I wrote to solve this, for those who are interested.

I use the given format string format_str to figure out how long it could get. Therefore I assume that only the month and the day can very in length. The function loop over the months to see which has the longest form and then I loop over the days with the previously found month.

import datetime

def max_date_len(format_str):

    def date_len(date):
        return len(date.strftime(format_str))

    def find_max_index(lst):
        return max(range(len(lst)), key=lst.__getitem__)

    # run through all month and add 1 to the index since we need a month
    # between 1 and 12
    max_month = 1 + find_max_index([date_len(datetime.datetime(2012, month, 12, 12, 12)) for month in range(1, 13)])

    # run throw all days of the week from day 10 to 16 since
    # this covers all weekdays and double digit days
    return max([date_len(datetime.datetime(2012, max_month, day, 12, 12)) for day in range(10, 17)])
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top