【问题标题】:Date and time formatting depending on locale日期和时间格式取决于区域设置
【发布时间】:2011-02-20 18:03:23
【问题描述】:

我是 Java 和 Android 开发的新手,所以这可能是一个愚蠢的问题,但我已经搜索了好几天,但找不到解决方案:

我尝试根据用户的语言环境输出java.util.Date

在 StackOverflow 上搜索让我看到了这个:

java.util.Date date = new Date();
String dateString = DateFormat.getDateFormat(getApplicationContext()).format(date);

这个输出:

20/02/2011

在我的法语本地化手机上。几乎没问题。

如何使用用户的语言环境输出Date小时、分钟和秒部分?我一直在寻找 android 文档,但找不到任何东西。

非常感谢。

【问题讨论】:

    标签: java android date formatting locale


    【解决方案1】:

    使用android.text.format.DateFormat.getTimeFormat()

    参考:http://developer.android.com/reference/android/text/format/DateFormat.html

    【讨论】:

    • 很遗憾,这不包括秒数。
    【解决方案2】:

    tl;博士

    ZonedDateTime                                   // Represent a moment as seen in the wall-clock time used by the people of a particular region (a time zone). 
    .now( ZoneId.of( "Asia/Kolkata" ) )             // Capture the current moment as seen in the specified time zone. Returns a `ZonedDateTime` object.
    .format(                                        // Generate text representing the value of this `ZonedDateTime` object.
        DateTimeFormatter                           // Class controlling the generation of text representing the value of a date-time object.
        .ofLocalizedDateTime ( FormatStyle.FULL )   // Automatically localize the string representing this date-time value.
        .withLocale ( Locale.FRENCH )               // Specify the human language and cultural norms used in localizing.
    )                                               // Return a `String` object.
    

    java.time

    问题中的代码使用了麻烦的旧日期时间类,现在是遗留的,被 Java 8 及更高版本中内置的 java.time 类所取代。

    区域设置和时区彼此无关。语言环境决定了在生成表示日期时间值的字符串时使用的人类语言和文化规范。时区决定了特定区域的wall-clock time,用于表示时间线上的某个时刻。

    Instant 类表示UTC 时间线上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。

    Instant instant = Instant.now();
    

    2016-10-12T07:21:00.264Z

    应用时区以获得ZonedDateTime。我随意选择使用印度时区来展示这一刻。同一时刻,时间轴上的同一点。

    ZoneId z = ZoneId.of( "Asia/Kolkata" );
    ZonedDateTime zdt = instant.atZone( z );
    

    2016-10-12T12:51:00.264+05:30[亚洲/加尔各答]

    使用加拿大魁北克的语言环境生成一个字符串。让 java.time 自动本地化字符串。

    Locale l = Locale.CANADA_FRENCH;
    DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL ).withLocale ( l );
    String output = zdt.format ( f );  // Indian time zone with Québécois presentation/translation.
    

    mercredi 2016 年 10 月 12 日 12 时 51 分 IST


    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date.Calendarjava.text.SimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    从哪里获取 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

    • “你正在使用麻烦的旧日期时间类” 公平地说,我确实在 2011 年问过这个问题。不过感谢您的跟进。您可能需要编辑答案,以明确现在情况发生了变化。就目前而言,使用这些类似乎是当时的错误做法,这可能会让人们感到困惑。
    • 感谢您写得如此出色且结论性的回复。
    • @ereOn 无意批评,也不可能被任何读者推断。所有帖子的日期都清楚地说明了,因此帖子的年龄很明显,上下文也很清楚。事实上,我在第一句话中使用“现在”这个词暗示了你的问题和我的答案之间的时间差距。每个程序员都知道信息技术正在快速发展,并且总是在变化。
    • 没关系。我看到你编辑了这个问题,使语气不那么“迂腐”和个人化,这肯定更好。我很感激。很高兴我们都在这个过程中学到了一些东西。感谢您的回答!
    • 这个 java sdk 以及大部分仅可从 Android 上的 26 API 获得,这是一个糟糕的答案,它是从另一个与 Android 无关的问题中复制而来的
    【解决方案3】:

    java.text.DateFormat 拥有您可能需要的所有功能:

    DateFormat.getDateInstance()

    DateFormat.getTimeInstance()

    但你需要的是:

    DateFormat.getDateTimeInstance() 您还可以指定日期/时间部分的长度和区域设置。最终结果是:

    DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, Locale.FRENCH).format(Date);

    来源:http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html

    【讨论】:

      【解决方案4】:

      DateFormat.getTimeInstance() 使用默认语言环境的默认格式样式获取时间格式器。您还可以传递样式和Locale

      【讨论】:

        【解决方案5】:

        使用getBestDateTimePattern()

        来自android.text.format 包的DateFormat.getBestDateTimePattern() 根据用户设置的语言环境创建可能的最佳日期和时间。

        例如:骨架EEEE, MMM d, YYYY, jj:mm 返回本地化日期和时间,如下所示。

        Locale English (India):            Monday 9 Sep 2019, 9:33 PM
        Locale English (United States):    Monday, Sep 9, 2019, 9:33 PM
        Locale español (Estados Unidos):   lunes, 9 de sep. de 2019 9:33 PM
        Locale español (México):           lunes, 9 de sep de 2019 21:33
        Locale français (France):          lundi 9 sept. 2019 à 21:33
        Locale português (Brasil):         segunda-feira, 9 de set de 2019 21:33
        

        等等,适用于不同的语言环境。它还尊重语言环境的 12 小时或 24 小时时间格式。

        要自定义您自己的骨架,请参阅 unicode.org 上的 UTS #35 模式。

        示例代码

        这是在 Kotlin 中经过测试的示例代码:

        val skeleton = DateFormat.getBestDateTimePattern(Locale.getDefault(), "EEEE, MMM d, YYYY, jj:mm")
        val formatter = SimpleDateFormat(skeleton, Locale.getDefault()).apply {
            timeZone = TimeZone.getDefault()
            applyLocalizedPattern(skeleton)
        }
        val dateTimeText = formatter.format(calendar.time)
        Log.d("YourClass", "Locale ${Locale.getDefault().displayName}: $dateTimeText")
        

        除了Calendar 类,您还可以使用ZonedDateTime。只需将其转换为Date 对象并将其提供给format()。例如:Date(zonedDateTime.toInstant().toEpochMilli())

        希望对您有所帮助。

        【讨论】:

          【解决方案6】:
          public static String formatDate(Date date, boolean withTime)
          {
              String result = "";
              DateFormat dateFormat;
          
              if (date != null)
              {
                  try
                  {
                      String format = Settings.System.getString(context.getContentResolver(), Settings.System.DATE_FORMAT);
                      if (TextUtils.isEmpty(format))
                      {
                          dateFormat = android.text.format.DateFormat.getDateFormat(context);
                      }
                      else
                      {
                          dateFormat = new SimpleDateFormat(format);
                      }
                      result = dateFormat.format(date);
          
                      if (withTime)
                      {
                          dateFormat = android.text.format.DateFormat.getTimeFormat(context);
                          result += " " + dateFormat.format(date);
                      }
                  }
                  catch (Exception e)
                  {
                  }
              }
          
              return result;
          }
          

          【讨论】:

          • 看起来不错,但你不应该像这样中性异常。
          猜你喜欢
          • 1970-01-01
          • 2011-01-22
          • 2011-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-23
          • 2011-07-29
          相关资源
          最近更新 更多