[python] month name to month number and vice versa in python

I am trying to create a function that can convert a month number to an abbreviated month name or an abbreviated month name to a month number. I thought this might be a common question but I could not find it online.

I was thinking about the calendar module. I see that to convert from month number to abbreviated month name you can just do calendar.month_abbr[num]. I do not see a way to go the other direction though. Would creating a dictionary for converting the other direction be the best way to handle this? Or is there a better way to go from month name to month number and vice versa?

This question is related to python

The answer is


You can use below as an alternative.

  1. Month to month number:

from time import strptime

strptime('Feb','%b').tm_mon

  1. Month number to month:

import calendar

calendar.month_abbr[2] or calendar.month[2]


One more:

def month_converter(month):
    months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    return months.index(month) + 1

Building on ideas expressed above, This is effective for changing a month name to its appropriate month number:

from time import strptime
monthWord = 'september'

newWord = monthWord [0].upper() + monthWord [1:3].lower() 
# converted to "Sep"

print(strptime(newWord,'%b').tm_mon) 
# "Sep" converted to "9" by strptime

To get the full calendar name from the month number, you can use calendar.month_name. Please see the documentation for more details: https://docs.python.org/2/library/calendar.html

month_no = 1
month = calendar.month_name[month_no]

# month provides "January":
print(month)



Here's yet another way to do it.

monthToNum(shortMonth):

    return {
            'jan' : 1,
            'feb' : 2,
            'mar' : 3,
            'apr' : 4,
            'may' : 5,
            'jun' : 6,
            'jul' : 7,
            'aug' : 8,
            'sep' : 9, 
            'oct' : 10,
            'nov' : 11,
            'dec' : 12
    }[shortMonth]

Using calendar module:

Number-to-Abbr calendar.month_abbr[month_number]

Abbr-to-Number list(calendar.month_abbr).index(month_abbr)


Here is a more comprehensive method that can also accept full month names

def month_string_to_number(string):
    m = {
        'jan': 1,
        'feb': 2,
        'mar': 3,
        'apr':4,
         'may':5,
         'jun':6,
         'jul':7,
         'aug':8,
         'sep':9,
         'oct':10,
         'nov':11,
         'dec':12
        }
    s = string.strip()[:3].lower()

    try:
        out = m[s]
        return out
    except:
        raise ValueError('Not a month')

example:

>>> month_string_to_number("October")
10 
>>> month_string_to_number("oct")
10

Information source: Python Docs

To get month number from month name use datetime module

import datetime
month_number = datetime.datetime.strptime(month_name, '%b').month

# To  get month name
In [2]: datetime.datetime.strftime(datetime.datetime.now(), '%a %b %d, %Y')
Out [2]: 'Thu Aug 10, 2017'

# To get just the month name, %b gives abbrevated form, %B gives full month name
# %b => Jan
# %B => January
dateteime.datetime.strftime(datetime_object, '%b')

Just for fun:

from time import strptime

strptime('Feb','%b').tm_mon

def month_num2abbr(month):
    month = int(month)
    import calendar
    months_abbr = {month: index for index, month in enumerate(calendar.month_abbr) if month}
    for abbr, month_num in months_abbr.items():
        if month_num==month:
            return abbr
    return False

print(month_num2abbr(7))

If you don't want to import the calendar library, and need something that is a bit more robust -- you can make your code a little bit more dynamic to inconsistent text input than some of the other solutions provided. You can:

  1. Create a month_to_number dictionary
  2. loop through the .items() of that dictionary and check if the lowercase of a string s is in a lowercase key k.

month_to_number = {
'January' : 1,         
'February' : 2,         
'March' : 3,           
'April' : 4,              
'May' : 5, 
'June' : 6,
'July' : 7, 
'August' : 8, 
'September' : 9, 
'October' : 10, 
'November' : 11, 
'December' : 12}

s = 'jun'
[v for k, v in month_to_number.items() if s.lower() in k.lower()][0]

Out[1]: 6

Likewise, if you have a list l instead of a string, you can add another for to loop through the list. The list I have created has inconsistent values, but the output is still what would be desired for the correct month number:

l = ['January', 'february', 'mar', 'Apr', 'MAY', 'JUne', 'july']
[v for k, v in month_to_number.items() for m in l if m.lower() in k.lower()]

Out[2]: [1, 2, 3, 4, 5, 6, 7]

The use case for me here is that I am using Selenium to scrape data from a website by automatically selecting a dropdown value based off of some conditions. Anyway, this requires me relying on some data that I believe our vendor is manually entering to title each month, and I don't want to come back to my code if they format something slightly differently than they have done historically.


form month name to number
d=['JAN','FEB','MAR','April','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']
N=input()
for i in range(len(d)):
    if d[i] == N:
        month=(i+1)
print(month)