【问题标题】:Use different time formats according to language根据语言使用不同的时间格式
【发布时间】:2018-03-20 06:14:44
【问题描述】:

我应该根据我的应用程序中的语言显示不同的时间格式。当设备是英文时,用户应该得到这样的时间格式:

2018 年 3 月 18 日,下午 2:30

但是当用户的设备是德国人时,他应该得到这样的时间格式:

18.03.2018, 14:30 Uhr

有没有办法通过将时间String 格式化为SimpleDateFormat 来做到这一点,或者我应该以其他方式做到这一点,如果是这样,我该如何做到这一点?

【问题讨论】:

  • 你试过了吗?哪里失败了?
  • 我不知道如何区分它。现在它一直只显示德语格式。这就是它失败的部分。我只是有一个疯狂的想法,使用语言字符串 xml 文件将格式放入其中,但我真的不希望它起作用
  • 顺便考虑扔掉长期过时且臭名昭著的麻烦SimpleDateFormat和朋友,并将ThreeTenABP添加到您的Android项目中,以便使用java.time,现代Java日期和时间API .使用起来感觉好多了。

标签: android datetime simpledateformat datetime-format


【解决方案1】:

我不认为它会起作用,但它确实起作用了。只需将您喜欢的格式放入字符串 xml 文件中即可:

<string name="date_time_format">dd MMMM yyyy, hh.mm a</string>
<string name="date_time_format">dd.MM.yyyy, HH:mm</string>

然后像这样在 SDF 中使用它:

SimpleDateFormat fmtOut = new SimpleDateFormat(context.getString(R.string.date_time_format), Locale.getDefault());

对于德语格式末尾的“Uhr”,我添加了一个如下所示的占位符字符串:

<string name="date_time_string">%s</string>
<string name="date_time_string">%s Uhr</string>

我使用 String.format() 方法返回格式化的日期:

return String.format(context.getString(R.string.date_time_string), fmtOut.format(date));

【讨论】:

  • 只是添加,@Distra,您可能还必须根据 locale 更改时间值。它只会更新格式。
【解决方案2】:

试试这个代码 sn-p。希望它能解决问题。

        java.sql.Date date1 = new java.sql.Date((new Date()).getTime());

        SimpleDateFormat formatNowDay = new SimpleDateFormat("dd");
        SimpleDateFormat formatNowYear = new SimpleDateFormat("yyyy");
        SimpleDateFormat sdf12 = new SimpleDateFormat("hh:mm aa");
        SimpleDateFormat sdf24 = new SimpleDateFormat("HH:mm");
        SimpleDateFormat germanSdf = new SimpleDateFormat("dd.MM.yyyy");

        String currentDay = formatNowDay.format(date1);
        String currentYear = formatNowYear.format(date1);
        String time12 = sdf12.format(date1);
        String time24 = sdf24.format(date1);

        String germanTime = germanSdf.format(date1);

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

        String engTime = currentDay+" "+currentMonth+" "+currentYear+", "+time12;
        String germanFormat = germanTime+", "+time24+" Uhr";

【讨论】:

    【解决方案3】:

    另一种方法是使用java.text.DateFormat

    DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.ENGLISH);
    

    日期和时间样式(第一个和第二个参数)可以是SHORTMEDIUMLONGFULL。如果需要,您可以使用Locale.getDefault() 获取设备的默认语言。

    我不确定哪种样式组合可以满足您的需求 - 它们都给了我不同的输出,没有一个给我您描述的那个。

    这是因为 JVM 中嵌入了特定于语言环境的格式,我不确定它在不同的 API 级别和设备之间有何不同。

    如果上面的解决方案有效,那就没问题了。否则,另一种方法是为每个区域设置特定的模式:

    // get device's locale
    Locale locale = Locale.getDefault();
    
    String pattern = "";
    // check language
    if ("en".equals(locale.getLanguage())) {
        // english
        pattern = "dd MMMM yyyy, h.mm a";
    } else if ("de".equals(locale.getLanguage())) {
        // german
        pattern = "dd.MM.yyyy, HH:mm 'Uhr'";
    } else {
        pattern = // use some default pattern for other languages?
    }
    
    SimpleDateFormat sdf = new SimpleDateFormat(pattern, locale);
    String formattedDate = sdf.format(new Date());
    

    一个细节是,在我的 JVM 中,英语语言环境的 AM/PM 符号是大写的,因此您可能需要通过以下方式进行调整:

    // change AM/PM to am/pm (only for English)
    if ("en".equals(locale.getLanguage())) {
        formattedDate  = formattedDate.toLowerCase();
    }
    

    java.time API

    在 API 级别 26 中,您可以使用 java.time API。对于较低级别,有一个 nice backport,具有相同的类和功能。

    这更好用。代码可能看起来相似,但类本身解决了lots of internal issues of the old API

    您可以先尝试获取 JVM 的本地化模式,看看它们是否与您的输出匹配:

    Locale locale = Locale.getDefault();
    FormatStyle style = FormatStyle.MEDIUM;
    String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(style, style, IsoChronology.INSTANCE, locale);
    DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern, locale);
    

    或者同上:

    // get device's locale
    Locale locale = Locale.getDefault();
    
    String pattern = "";
    // check language
    if ("en".equals(locale.getLanguage())) {
        // english
        pattern = "dd MMMM yyyy, h.mm a";
    } else if ("de".equals(locale.getLanguage())) {
        // german
        pattern = "dd.MM.yyyy, HH:mm 'Uhr'";
    } else {
        pattern = ""; // use some default pattern?
    }
    
    DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern, locale);
    
    String formattedDate = LocalDateTime.now().format(fmt);
    

    在我的测试中,我遇到了英语大写 AM/PM 的同样问题。您可以通过调用toLowerCase() 来解决此问题,但此 API 还允许您创建更灵活的格式化程序。

    并且格式化程序是线程安全的(而SimpleDateFormat 不是),因此您可以根据语言创建格式化程序的静态映射,并根据需要多次重复使用它们:

    // map of formatters
    Map<String, DateTimeFormatter> formatterMap = new HashMap<>();
    
    // English formatter
    Map<Long, String> customAmPmSymbols = new HashMap<>();
    customAmPmSymbols.put(0L, "am");
    customAmPmSymbols.put(1L, "pm");
    DateTimeFormatter f = new DateTimeFormatterBuilder()
        // date/time
        .appendPattern("dd MMMM yyyy, h.mm ")
        // custom AM/PM symbols (lowercase)
        .appendText(ChronoField.AMPM_OF_DAY, customAmPmSymbols)
        // create formatter
        .toFormatter(Locale.ENGLISH);
    // add to map
    formatterMap.put("en", f);
    
    // German formatter
    formatterMap.put("de", DateTimeFormatter.ofPattern("dd.MM.yyyy, HH:mm 'Uhr'", Locale.GERMAN));
    
    // get device's locale
    Locale locale = Locale.getDefault();
    
    DateTimeFormatter fmt = formatterMap.get(locale.getLanguage());
    
    if (fmt != null) {
        String formattedDate = LocalDateTime.now().format(fmt);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 2021-09-26
      相关资源
      最近更新 更多