【问题标题】:month name to month number and vice versa in python月份名称到月份编号,反之亦然在python中
【发布时间】:2010-08-05 18:44:50
【问题描述】:

我正在尝试创建一个函数,可以将月份编号转换为缩写月份名称或将缩写月份名称转换为月份编号。我认为这可能是一个常见问题,但我无法在网上找到它。

我在考虑calendar 模块。我看到要将月份编号转换为缩写月份名称,您只需执行calendar.month_abbr[num]。不过,我看不到另一个方向的方法。创建一个字典来转换另一个方向是处理这个问题的最好方法吗?或者有没有更好的方法从月份名称到月份编号,反之亦然?

【问题讨论】:

    标签: python


    【解决方案1】:

    使用calendar 模块创建一个反向字典(与任何模块一样,您需要导入该模块):

    {month: index for index, month in enumerate(calendar.month_abbr) if month}
    

    在 2.7 之前的 Python 版本中,由于该语言不支持 dict 理解语法,您必须这样做

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

    【讨论】:

      【解决方案2】:

      只是为了好玩:

      from time import strptime
      
      strptime('Feb','%b').tm_mon
      

      【讨论】:

      • 这取决于您的语言环境吗?
      • Python 2.7 | ValueError:时间数据“Fev”与格式“%b”不匹配
      • @DiegoVinícius 很确定“Fev”应该是“Feb”。
      • @FawwazYusran Diego 尝试了语言环境,但该命令仅适用于英文月份名称
      • 如果在循环中使用,效率非常低。
      【解决方案3】:

      使用calendar 模块:

      数字到缩写 calendar.month_abbr[month_number]

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

      【讨论】:

      • 示例:list(calendar.month_abbr).index('Feb') 结果:2
      • 完整月份名称使用:list(calendar.month_name).index('January')
      • 不错,但如果在循环中用于查找多个月份名称,则效率不会很高。
      【解决方案4】:

      这是另一种方法。

      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]
      

      【讨论】:

      • 你可以这样做:month_cal = dict((v,k) for v,k in zip(calendar.month_abbr[1:], range(1, 13))),然后month_cal[shortMonth]
      • 这是个好方法。我建议的方式不需要导入语句。这是一个偏好问题。
      【解决方案5】:

      信息来源:Python Docs

      要从月份名称中获取月份编号,请使用日期时间模块

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

      【讨论】:

        【解决方案6】:

        这是一个更全面的方法,也可以接受完整的月份名称

        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
        

        【讨论】:

        • 这个比我上面的好
        【解决方案7】:

        还有一个:

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

        【讨论】:

          【解决方案8】:

          完整的月份名称到月份编号(例如 JanuaryFebruary 等):

          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
          

          【讨论】:

          • 很好的答案,月份名称到数字的总称(对于全名或部分名称):datetime.datetime.strptime(month_name[:3], '%b').month
          【解决方案9】:

          要从月份编号中获取完整的日历名称,您可以使用 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)
          
          
          

          【讨论】:

            【解决方案10】:

            基于上面表达的想法,这对于将月份名称更改为适当的月份编号是有效的:

            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
            

            【讨论】:

            • 也许我误读了你的意图,但你确定它不应该是 word[0:3]?
            • 不,如果您再看一遍,您会发现第一个字母 word[0] 以大写形式使用并连接到接下来的两个字母 word[1:3]。我发布的代码在将月份单词转换为适当的月份编号方面非常有效。
            【解决方案11】:
            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)
            

            【讨论】:

            • 解释你的编码总是更好
            【解决方案12】:

            您可以使用下面的替代方法。

            1. 月月数:

            from time import strptime

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

            1. 月数到月:

            import calendar

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

            【讨论】:

              【解决方案13】:
              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))
              

              【讨论】:

              • 欢迎。感谢您抽出宝贵时间提供问题的答案。由于提供的答案通常不止一个,因此当您简要说明您的解决方案的作用以及最佳解决方案的原因时,通常会对提问者有所帮助。
              【解决方案14】:

              如果您不想导入日历库,并且需要更健壮的东西 - 您可以使您的代码比某些代码更动态地处理不一致的文本输入提供的其他解决方案。你可以:

              1. 创建一个month_to_number 字典
              2. 遍历该字典的.items() 并检查字符串s 的小写字母是否在小写键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
              

              同样,如果您有一个列表 l 而不是字符串,您可以添加另一个 for 来循环列表。我创建的列表值不一致,但输出仍然是正确月份数所需要的:

              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]
              

              这里的用例是我使用Selenium 通过根据某些条件自动选择下拉值来从网站上抓取数据。无论如何,这需要我依赖一些数据,我相信我们的供应商每个月都会手动输入标题,如果它们的格式与历史上的略有不同,我不想回到我的代码。

              【讨论】:

                猜你喜欢
                • 2017-02-19
                • 1970-01-01
                • 1970-01-01
                • 2011-03-12
                • 2014-06-16
                • 2019-12-26
                相关资源
                最近更新 更多