【问题标题】:Weird issue with Month in SimpleDateFormatSimpleDateFormat 中月份的奇怪问题
【发布时间】:2021-11-25 09:04:48
【问题描述】:

我尝试格式化我的日期时间:

Locale locale = context.getResources().getConfiguration().locale;
dateFormatDayMonth = new SimpleDateFormat("EEE, MMM d", locale);
textView.setText(dateFormatDayMonth.format(calendar.getTime()));

但是,结果是Sat, M10 2。我希望它是Sat, Oct 2。以前是可以用的,但是突然就不能用了。 这里有什么我错过的吗?

【问题讨论】:

  • 语言环境是default。
  • 我知道它的默认值。我的意思是你在语言环境中获得了什么价值?
  • 我将其记录为locale.toString(),并命名为default。格式化后的文本为Sat, M10 2。但是,我在我的设备中使用的是英语,它应该是Sat, Oct 2。
  • LocalDate.now().format(DateTimeFormatter.ofPattern("EEE, MMM d"))
  • 我建议你不要使用SimpleDateFormat、Calendar和Date。这些类设计不佳且早已过时,尤其是第一个类是出了名的麻烦。而是使用来自java.time, the modern Java date and time API 的LocalDate 和DateTimeFormatter。

标签: java android datetime simpledateformat


【解决方案1】:

像这样初始化你的日期格式

Locale locale = Locale.getDefault();
    DateFormat dateFormat = new SimpleDateFormat("EEE, MMM d", locale);
    Calendar calendar = Calendar.getInstance(locale);
    outputDate.setText(dateFormat.format(calendar.getTime()));

【讨论】:

    【解决方案2】:

    java.time

    java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*。

    使用现代日期时间 API java.time 的解决方案:

    import java.time.OffsetDateTime;
    import java.time.ZoneOffset;
    import java.time.format.DateTimeFormatter;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) {
            // A dummy Locale for the demo
            Locale localeFromResponse = new Locale("default");
    
            Locale locale = localeFromResponse.toString().equals("default") ? Locale.getDefault() : localeFromResponse;
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE, MMM d", locale);
            String formatted = OffsetDateTime.now(ZoneOffset.UTC).format(dtf);
            System.out.println(formatted);
    
            // textView.setText(formatted);
        }
    }
    

    输出:

    Tue, Oct 5
    

    ONLINE DEMO

    如果你有一个现有的java.util.Calendar 对象

    您可以使用Calendar#toInstant 将现有的java.util.Calendar 对象转换为java.time.Instant,而Calendar#toInstant 又可以转换为java.time API 的其他日期时间类型。

    演示:

    import java.time.ZoneOffset;
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Calendar;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) {
            // Dummy Locale and Calendar objects - for the demo
            Locale localeFromResponse = new Locale("default");
            Calendar calendar = Calendar.getInstance();
    
            Locale locale = localeFromResponse.toString().equals("default") ? Locale.getDefault() : localeFromResponse;
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE, MMM d", locale);
            ZonedDateTime zdt = calendar.toInstant().atZone(ZoneOffset.UTC);
            String formatted = zdt.format(dtf);
            System.out.println(formatted);
    
            // textView.setText(formatted);
        }
    }
    

    输出:

    Tue, Oct 5
    

    ONLINE DEMO

    从 Trail: Date Time 了解有关现代日期时间 API 的更多信息。

    以防万一您需要使用旧版 API 进行操作

    无论出于何种原因,如果您想坚持使用旧版 API,您可以按照我在上面所做的相同方式映射 Locale,即它将是

    Locale localeFromResponse = context.getResources().getConfiguration().locale;
    
    Locale locale = localeFromResponse.toString().equals("default") ? Locale.getDefault() : localeFromResponse;
    dateFormatDayMonth = new SimpleDateFormat("EEE, MMM d", locale);
    textView.setText(dateFormatDayMonth.format(calendar.getTime()));
    

    * 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring。请注意,Android 8.0 Oreo 已经提供了support for java.time。

    【讨论】:

      猜你喜欢
      • 2016-06-09
      • 2011-01-06
      • 2013-08-25
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      相关资源
      最近更新 更多