26

I am playing with Python's calendar module that's in the standard library. Basically I need a list of all days of a month, like so:

>>> import calendar
>>> calobject = calendar.monthcalendar(2012, 10)
>>> print calobject
[[1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14], [15, 16, 17, 18, 19, 20, 21], [22, 23, 24, 25, 26, 27, 28], [29, 30, 31, 0, 0, 0, 0]]

Now what I also need are the names of the months and days in a specific locale. I didn't find a way to get these from the calobject itself - but I was able to get them like so:

>>> import calendar
>>> calobject = calendar.LocaleTextCalendar(calendar.MONDAY, 'de_DE')
>>> calobject.formatmonth(2012, 10)
'    Oktober 2012\nMo Di Mi Do Fr Sa So\n 1  2  3  4  5  6  7\n 8  9 10 11 12 13 14\n15 16 17 18 19 20 21\n22 23 24 25 26 27 28\n29 30 31\n'

So Oktober is the de_DE name for october. Fine. The information must be there. I'm wondering if I can access that month name somehow on a plain calendar object instead of a calendar.LocaleTextCalendar object. The first example (with the list) is really what I need and I don't like the idea to create two calendar objects to get localized names.

Anyone got a smart idea?

petezurich
  • 9,280
  • 9
  • 43
  • 57
Daniel
  • 1,515
  • 3
  • 17
  • 30

3 Answers3

49

Ha! Found an easy way to get localized day/month names:

>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'de_DE')
'de_DE'
>>> import calendar
>>> calendar.month_name[10]
'Oktober'
>>> calendar.day_name[1]
'Dienstag'
Daniel
  • 1,515
  • 3
  • 17
  • 30
  • 3
    This is just a stripped-down version of my answer. The `TimeEncoding` context is simply a way of temporarily setting the locale. If you want it permanent, calling `setlocale` directly is ok. I'm guessing that the encoding step is only needed if you've got unicode characters in the month/day names, which it seems is not the case in german. – Lauritz V. Thaulow Oct 23 '12 at 19:36
  • Oh, okay. Yeah, we have unicode characters: >>> calendar.month_name[3] 'M\xc3\xa4rz' – Daniel Oct 23 '12 at 19:51
26

This is from the source code of the calendar module:

def formatmonthname(self, theyear, themonth, width, withyear=True):
    with TimeEncoding(self.locale) as encoding:
        s = month_name[themonth]
        if encoding is not None:
            s = s.decode(encoding)
        if withyear:
            s = "%s %r" % (s, theyear)
        return s.center(width)

TimeEncoding and month_name can be imported from the calendar module. This gives the following method:

from calendar import TimeEncoding, month_name

def get_month_name(month_no, locale):
    with TimeEncoding(locale) as encoding:
        s = month_name[month_no]
        if encoding is not None:
            s = s.decode(encoding)
        return s

print get_month_name(3, "nb_NO.UTF-8")

For me the decode step is not needed, simply printing month_name[3] in the TimeEncoding context prints "mars", which is norwegian for "march".

For weekdays there's a similar method using the day_name and day_abbr dicts:

from calendar import TimeEncoding, day_name, day_abbr

def get_day_name(day_no, locale, short=False):
    with TimeEncoding(locale) as encoding:
        if short:
            s = day_abbr[day_no]
        else:
            s = day_name[day_no]
        if encoding is not None:
            s = s.decode(encoding)
        return s
Lauritz V. Thaulow
  • 49,139
  • 12
  • 73
  • 92
  • Thanks lazyr. Well, it works. I was hoping there is an easier way to achieve this. I figured out i can also import `day_name`.I think I'll hardcode the names for months and days (takes two lines of code). We only need it in German and the month/day names are unlikely to change in the next few years. Thanks though. – Daniel Oct 23 '12 at 19:20
  • @Daniel No problem. Even though you didn't need it, now the answer is here for the next person who needs it. – Lauritz V. Thaulow Oct 23 '12 at 19:21
  • Yeah. It's just too complicated. I thought there is an easy way to access this information, like setting up a calendar instance with a specific locale. – Daniel Oct 23 '12 at 19:25
  • 7
    In pyhton3 `TimeEncoding` is renamed to `different_locale`. It also works a little different, the `decode` call is not needed anymore. – jjmurre Jul 20 '17 at 14:31
7

Here's the month part of Lauritz's answer updated for Python 3:

from calendar import month_name, different_locale
def get_month_name(month_no, locale):
    with different_locale(locale):
        return month_name[month_no]
Michel de Ruiter
  • 7,131
  • 5
  • 49
  • 74
Thomas Parslow
  • 5,712
  • 4
  • 26
  • 33
  • 1
    I get the warning `'different_locale' is not declared in __all__`. Additionally, documentation for `different_locale` is nowhere to be found. – Tobias Feil Jun 12 '19 at 08:40