【问题标题】:Month name as a string月份名称作为字符串
【发布时间】:2011-09-05 18:33:11
【问题描述】:

我正在尝试将月份名称作为字符串返回,例如“May”、“September”、“November”。

我试过了:

int month = c.get(Calendar.MONTH);

但是,这会返回整数(分别为 5、9、11)。如何获取月份名称?

【问题讨论】:

    标签: android calendar


    【解决方案1】:

    使用getDisplayName

    供早期 API 使用 String.format(Locale.US,"%tB",c);

    【讨论】:

    • 我遇到了一个问题:getDisplayName(month, Calendar.LONG, Locale.US) 而 Eclipse 告诉我 Calendar.LONG 或 Calendar.SHORT 不存在。
    • 这很奇怪。您使用的是 java.util.Calendar 而不是其他 Calendar 类,对吧?
    • 是的。看起来 getDisplayName() 和关联的 Calendar.LONG 和 Calendar.SHORT 只是 API 级别 9。所以,它适用于 9 级,但我需要 7 级:(
    • Formatter f = new Formatter();(您可以选择给它一个区域设置)然后是 String monthName = f.format("%tB",c).toString();%tb 的简称。
    • 同时使用 Locale.getDefault() 而不是 Locale.US 可能是个好主意 :)
    【解决方案2】:

    我保留这个对其他情况有用的答案,但@trutheality 答案似乎是最简单直接的方法。

    您可以使用DateFormatSymbols

    DateFormatSymbols(Locale.FRENCH).getMonths()[month]; // FRENCH as an example
    

    【讨论】:

      【解决方案3】:

      使用这个:

      Calendar cal=Calendar.getInstance();
      SimpleDateFormat month_date = new SimpleDateFormat("MMMM");
      String month_name = month_date.format(cal.getTime());
      

      月份名称将包含完整的月份名称,如果您想要短月份名称,请使用 这个

       SimpleDateFormat month_date = new SimpleDateFormat("MMM");
       String month_name = month_date.format(cal.getTime());
      

      【讨论】:

      • "MMMM" 对于第一种情况就足够了。
      【解决方案4】:

      要在字符串变量中获取月份,请使用以下代码

      例如九月份:

      M -> 9

      MM -> 09

      嗯-> 九月

      MMMM -> 九月

      String monthname=(String)android.text.format.DateFormat.format("MMMM", new Date())
      

      【讨论】:

      • 是的,谢谢,它就像一个魅力,在我使用的所有语言(法语、英语、德语)中都有效
      【解决方案5】:

      就这么简单

      mCalendar = Calendar.getInstance();    
      String month = mCalendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
      

      Calendar.LONG 是获取月份的全名,Calendar.SHORT 是简短的名称。 例如:Calendar.LONG 将返回一月 Calendar.SHORT 将返回 Jan

      【讨论】:

      • 很好的答案。我正在自己设置日历以进行警报,并且需要稍后获取月份名称。完美的答案。谢谢
      【解决方案6】:

      “MMMM”绝对不是正确的解决方案(即使它适用于多种语言),请使用“LLLL”模式和SimpleDateFormat

      Jun. 2010 上将“L”作为独立月份名称的 ICU 兼容扩展支持添加到 Android 平台。

      即使在英语中 'MMMM' 和 'LLLL' 的编码之间没有区别,您也应该考虑其他语言。

      例如这就是你得到的,如果你使用Calendar.getDisplayName 或一月份的“MMMM”模式和俄语Locale

      января(对于完整的日期字符串是正确的:“10 января, 2014”)

      但如果是独立的月份名称,您会期望:

      январь

      正确的解决方案是:

       SimpleDateFormat dateFormat = new SimpleDateFormat( "LLLL", Locale.getDefault() );
       dateFormat.format( date );
      

      如果您对所有翻译的来源感兴趣 - here is the reference 到公历翻译(页面顶部链接的其他日历)。

      【讨论】:

      • 'LLLL' 仅在 Java 8 之后可用,您可以将 'MMMM' 与 SimpleDateFormat 一起使用,它也适用于独立版本。
      • 要清楚,在俄语中“Января”的翻译是属格,意思是“一月”,而“Январь”是主格,意思是“一月”。可能还有其他具有这种区别的斯拉夫语言,例如乌克兰语和塞尔维亚语。它只是语法上的,通常不太重要。但是这个答案中给出的用例在语法上是正确的:如果您想尽可能正确,请使用 MMMM 来表示完整的日期,并在单独显示月份时使用 LLLL。
      • 谢谢你,我在为俄罗斯的 lang 案例苦苦挣扎 :)
      • 为此苦苦挣扎了 2 天。男人,你是救命恩人!
      【解决方案7】:

      要在 Java 中“正确”执行,获得一个独立的月份名称非常困难。 (至少在撰写本文时。我目前使用的是 Java 8)。

      问题在于,在某些语言中,包括俄语和捷克语,月份名称的独立版本与“格式化”版本不同。此外,似乎没有单一的 Java API 会为您提供“最佳”字符串。到目前为止,此处发布的大多数答案仅提供格式化版本。下面粘贴的是一个有效的解决方案,用于获取单个月份名称的独立版本,或获取包含所有这些名称的数组。

      我希望这可以节省其他人一些时间!

      /**
       * getStandaloneMonthName, This returns a standalone month name for the specified month, in the
       * specified locale. In some languages, including Russian and Czech, the standalone version of
       * the month name is different from the version of the month name you would use as part of a
       * full date. (Different from the formatting version).
       *
       * This tries to get the standalone version first. If no mapping is found for a standalone
       * version (Presumably because the supplied language has no standalone version), then this will
       * return the formatting version of the month name.
       */
      private static String getStandaloneMonthName(Month month, Locale locale, boolean capitalize) {
          // Attempt to get the standalone version of the month name.
          String monthName = month.getDisplayName(TextStyle.FULL_STANDALONE, locale);
          String monthNumber = "" + month.getValue();
          // If no mapping was found, then get the formatting version of the month name.
          if (monthName.equals(monthNumber)) {
              DateFormatSymbols dateSymbols = DateFormatSymbols.getInstance(locale);
              monthName = dateSymbols.getMonths()[month.getValue()];
          }
          // If needed, capitalize the month name.
          if ((capitalize) && (monthName != null) && (monthName.length() > 0)) {
              monthName = monthName.substring(0, 1).toUpperCase(locale) + monthName.substring(1);
          }
          return monthName;
      }
      
      /**
       * getStandaloneMonthNames, This returns an array with the standalone version of the full month
       * names.
       */
      private static String[] getStandaloneMonthNames(Locale locale, boolean capitalize) {
          Month[] monthEnums = Month.values();
          ArrayList<String> monthNamesArrayList = new ArrayList<>();
          for (Month monthEnum : monthEnums) {
              monthNamesArrayList.add(getStandaloneMonthName(monthEnum, locale, capitalize));
          }
          // Convert the arraylist to a string array, and return the array.
          String[] monthNames = monthNamesArrayList.toArray(new String[]{});
          return monthNames;
      }
      

      【讨论】:

        【解决方案8】:

        Android 上为乌克兰语、俄语、捷克语等语言获取正确格式的独立月份名称的唯一方法

        private String getMonthName(Calendar calendar, boolean short) {
            int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY | DateUtils.FORMAT_NO_YEAR;
            if (short) {
                flags |= DateUtils.FORMAT_ABBREV_MONTH;
            }
            return DateUtils.formatDateTime(getContext(), calendar.getTimeInMillis(), flags);
        }
        

        在 API 15-25 上测试

        May 的输出是 Май 但不是 Мая

        【讨论】:

          【解决方案9】:

          我建议使用Calendar 对象和Locale,因为不同语言的月份名称不同:

          // index can be 0 - 11
          private String getMonthName(final int index, final Locale locale, final boolean shortName)
          {
              String format = "%tB";
          
              if (shortName)
                  format = "%tb";
          
              Calendar calendar = Calendar.getInstance(locale);
              calendar.set(Calendar.MONTH, index);
              calendar.set(Calendar.DAY_OF_MONTH, 1);
          
              return String.format(locale, format, calendar);
          }
          

          完整月份名称示例:

          System.out.println(getMonthName(0, Locale.US, false));
          

          结果:January

          短月份名称示例:

          System.out.println(getMonthName(0, Locale.US, true));
          

          结果:Jan

          【讨论】:

            【解决方案10】:

            获取日期和时间的示例方法 这种格式“2018 Nov 01 16:18:22”使用这个

            DateFormat dateFormat = new SimpleDateFormat("yyyy MMM dd HH:mm:ss");
                    Date date = new Date();
                     dateFormat.format(date);
            

            【讨论】:

              【解决方案11】:

              俄语。

              Month
              .MAY
              .getDisplayName(
                  TextStyle.FULL_STANDALONE ,
                  new Locale( "ru" , "RU" )
              )
              

              美国的英语。

              Month
              .MAY
              .getDisplayName(
                  TextStyle.FULL_STANDALONE ,
                  Locale.US
              )
              

              五月

              看到这个code run live at IdeOne.com

              ThreeTenABP 和 java.time

              这是现代答案。在 2011 年提出这个问题时,CalendarGregorianCalendar 通常用于表示日期和时间,尽管它们的设计总是很糟糕。那是 8 年前的事了,这些课程早已过时。假设您还没有达到 API 级别 26,我的建议是使用 ThreeTenABP 库,其中包含适用于 Android 的 java.time 反向移植,现代 Java 日期和时间 API。 java.time 好用得多。

              根据您的具体需求和情况,有两种选择:

              1. 使用Month 及其getDisplayName 方法。
              2. 使用DateTimeFormatter

              使用月份

                  Locale desiredLanguage = Locale.ENGLISH;
                  Month m = Month.MAY;
                  String monthName = m.getDisplayName(TextStyle.FULL, desiredLanguage);
                  System.out.println(monthName);
              

              这个 sn-p 的输出是:

              五月

              在一些语言中,使用TextStyle.FULLTextStyle.FULL_STANDALONE 会有所不同。您将不得不查看,也许与您的用户核实,这两者中的哪一个适合您的上下文。

              使用 DateTimeFormatter

              如果你有一个有或没有时间的日期,我发现DateTimeFormatter 更实用。例如:

                  DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMMM", desiredLanguage);
              
                  ZonedDateTime dateTime = ZonedDateTime.of(2019, 5, 31, 23, 49, 51, 0, ZoneId.of("America/Araguaina"));
                  String monthName = dateTime.format(monthFormatter);
              

              我正在展示ZonedDateTime 的使用,它是旧Calendar 类的最接近的替代品。上面的代码也适用于LocalDateLocalDateTimeMonthDayOffsetDateTimeYearMonth

              如果您从尚未升级到 java.time 的旧版 API 获得 Calendar 怎么办?转换为ZonedDateTime 并按上述方式进行:

                  Calendar c = getCalendarFromLegacyApi();
                  ZonedDateTime dateTime = DateTimeUtils.toZonedDateTime(c);
              

              其余的和以前一样。

              问:java.time 不需要 Android API 26 级吗?

              java.time 在较旧和较新的 Android 设备上都能很好地工作。它只需要至少 Java 6

              • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 起)中,现代 API 是内置的。
              • 在非 Android 的 Java 6 和 7 中,获取 ThreeTen Backport,这是现代类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
              • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

              链接

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2016-03-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-12-27
                • 2020-11-16
                相关资源
                最近更新 更多