如何将月份名称映射到月份数字,反之亦然?

145

我正在尝试创建一个函数,可以将月份数字转换为缩写的月份名称或将缩写的月份名称转换为月份数字。我认为这可能是一个常见的问题,但我在网上找不到相关内容。

我想使用 calendar 模块。我发现将月份数字转换为缩写的月份名称很简单,只需使用 calendar.month_abbr[num] 即可。但我没有看到相应的逆向转换方式。是否创建一个字典来进行双向转换是处理此问题的最佳方式?或者有更好的方法来实现从月份名称到月份数字的转换吗?

16个回答

131
使用calendar模块(就像任何模块一样,您需要导入它)创建一个反向字典:
{month: index for index, month in enumerate(calendar.month_abbr) if month}

在Python 2.7之前的版本中,由于语言不支持字典推导式的语法,你需要这样做:

dict((month, index) for index, month in enumerate(calendar.month_abbr) if month)

1
太棒了,@David Z。 - Asif Mehmood
月份 = 日历.月名[月号] - afshin
1
@afshin 不是的。那回答了一个与所问问题不同的问题。 - David Z

93

只是为了好玩:

from time import strptime

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

3
这是否取决于您的地区? - Janus Troelsen
Python 2.7 | ValueError: time data 'Fev' does not match format '%b'Python 2.7 | ValueError:时间数据“Fev”与格式“%b”不匹配。 - Diego Vinícius
@DiegoVinícius,我很确定那里应该是“Feb”,而不是“Fev”。 - Fawwaz Yusran
@FawwazYusran Diego尝试了本地化语言,但该命令仅适用于英语月份名称。 - PythoNic
1
如果在循环中使用,这将非常低效。 - Mr. Lance E Sloan
运行得非常好。 - GLP

81

使用 calendar 模块:

数字到缩写: calendar.month_abbr[month_number]

缩写到数字: list(calendar.month_abbr).index(month_abbr)


例子:list(calendar.month_abbr).index('Feb') 结果:2 - kibitzforu
7
使用完整的月份名称,请使用以下代码:list(calendar.month_name).index('January') - Paul
1
还不错,但如果在循环中用于查找许多月份名称,则效率不是很高。 - Mr. Lance E Sloan
3
@Mr.LanceESloan,你有进行基准测试/验证吗?当然,每次重新加载列表都是浪费的,但可以在循环之前将其存储,这样就与其他答案相当了。我不确定索引与使用字典的成本/收益如何?如果要避免额外的模块开销,可以只导入此函数吗?您支持哪个答案更有效率?就目前而言,您的评论对像我这样寻找高效(但相对简单)解决方案的新手用户并不是很有帮助...所以也许您可以帮助我们指出一些方向?!! - JeopardyTempest

29

这是另一种实现它的方法。

def 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]

1
你可以用以下方式实现同样的功能:month_cal = dict((v,k) for v,k in zip(calendar.month_abbr[1:], range(1, 13))),然后使用 month_cal[shortMonth] - Matt W.
7
这是一个好方法。我建议的方法不需要导入语句,只是个人喜好。 - Gi0rgi0s
calendar.month_name 只返回一个月份名称列表。 - Ivan Calderon

25

信息来源:Python 文档

要从月份名称获取月份数字,请使用 datetime 模块。

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')

17

这里有一种更全面的方法,可以接受完整的月份名称

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')

例子:

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

这个比我上面的更好。 - Gi0rgi0s

10

再来一个:

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

10

将完整月份名称转换为月份数字(例如一月二月等):

import datetime

month_name = 'January'
month_num = datetime.datetime.strptime(month_name, '%B').month

print(month_num, type(month_num))

>> 1 <class 'int'>

将部分月份名称转换为月份数字(例如,JanFeb等):

import datetime

month_name = 'Feb'
month_num = datetime.datetime.strptime(month_name, '%b').month

print(month_num, type(month_num))

>> 2 <class 'int'>

你还可以将其格式化为双位数表示:
month_num = 3
formatted = f"{month_num:02}"

print(formatted, type(formatted))

>> 03 <class 'str'>

将月份数字转换为完整的月份名称(无论是双位数表示还是非双位数表示,无论是字符串还是整数)(例如:'01'1等):

import datetime

month_num = '04'  # month_num = 4 will work too
month_name = datetime.datetime(1, int(month_num), 1).strftime("%B")

print(month_name)

>> April

将月份数字转换为部分月份名称(可以是双位数表示或非双位数表示,可以是字符串或整数)(例如:'01'1等):

import datetime

month_num = 5  # month_num = '05' will work too
month_name = datetime.datetime(1, int(month_num), 1).strftime("%b")

print(month_name)

>> May

1
好的答案,将月份名称转换为数字的通用方法(适用于完整或部分名称):datetime.datetime.strptime(month_name[:3], '%b').month - Matt

1
当将月份名称转换为列表时,您可以使用index方法。月份名称的索引将对应于月份的数字。
list(calendar.month_abbr).index('Jan')  # returns 1

这是calendar.month_abbr[1]的相反操作。

请提供一个解释,避免只给出代码的答案。 - undefined

1
要从月份编号获取完整的日历名称,您可以使用calendar.month_name。有关更多详细信息,请参阅文档:https://docs.python.org/2/library/calendar.html
month_no = 1
month = calendar.month_name[month_no]

# month provides "January":
print(month)



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接