【问题标题】:Android SimpleDateFormat, how to use it?Android SimpleDateFormat,如何使用?
【发布时间】:2012-03-05 20:55:18
【问题描述】:

我正在尝试像这样使用 Android SimpleDateFormat

String _Date = "2010-09-29 08:45:22"
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");

try {
    Date date = fmt.parse(_Date);
    return fmt.format(date);
}
catch(ParseException pe) {
    return "Date";    
}

结果很好,我有:2010-09-29

但如果我将SimpleDateFormat 更改为

SimpleDateFormat("dd-MM-yyyy");

问题是我会得到 03-03-0035 !!!!

为什么以及如何获得dd-MM-yyyy这样的格式?

【问题讨论】:

  • 对于这个问题的新读者,请考虑扔掉早已过时且臭名昭著的麻烦SimpleDateFormat 和朋友。看看您是否可以使用desugaring 或将ThreeTenABP 添加到您的Android 项目中,以便使用现代Java 日期和时间API 的java.time。使用起来感觉好多了。

标签: java android


【解决方案1】:

使用 java.util 的日期时间 API 和它们的格式化 API,SimpleDateFormat 我遇到了好几次惊喜,但这是最大的一个! ???

下面是您在问题中描述的说明:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

class Main {
    public static void main(String[] args) {
        System.out.println(formatDateWithPattern1("2010-09-29 08:45:22"));
        System.out.println(formatDateWithPattern2("2010-09-29 08:45:22"));
    }

    static String formatDateWithPattern1(String strDate) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = fmt.parse(strDate);
            return fmt.format(date);
        } catch (ParseException pe) {
            return "Date";
        }
    }

    static String formatDateWithPattern2(String strDate) {
        SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy");
        try {
            Date date = fmt.parse(strDate);
            return fmt.format(date);
        } catch (ParseException pe) {
            return "Date";
        }
    }
}

输出:

2010-09-29
03-03-0035

令人惊讶的是,SimpleDateFormat 默默地执行了解析和格式化,没有发出警报。任何阅读本文的人都会毫不犹豫地完全停止使用它们并切换到modern date-time API

无论出于何种原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7。

如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

使用现代日期时间 API:

由于根据输入字符串,这两个函数中使用的模式都是错误的,因此解析器应该发出警报,并且现代日期时间 API 的解析/格式化类型会负责任地做到这一点。

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

class Main {
    public static void main(String[] args) {
        System.out.println(formatDateWithPattern1("2010-09-29 08:45:22"));
        System.out.println(formatDateWithPattern2("2010-09-29 08:45:22"));
    }

    static String formatDateWithPattern1(String strDate) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd");
        try {
            LocalDateTime date = LocalDateTime.parse(strDate, dtf);
            return dtf.format(date);
        } catch (DateTimeParseException dtpe) {
            return "Date";
        }
    }

    static String formatDateWithPattern2(String strDate) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-uuuu");
        try {
            LocalDateTime date = LocalDateTime.parse(strDate, dtf);
            return dtf.format(date);
        } catch (DateTimeParseException dtpe) {
            return "Date";
        }
    }
}

输出:

Date
Date

故事的寓意

  1. java.util 的日期时间 API 及其格式 API SimpleDateFormat 已过时且容易出错。完全停止使用它们并切换到现代日期时间 API。通过 Trail: Date Time 了解现代日期时间 API。
  2. 在解析时坚持输入日期时间字符串中的格式。如果您希望输出格式不同,请使用解析器/格式化程序类的不同实例。

演示:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class Main {
    public static void main(String[] args) {
        String strDateTime = "2010-09-29 08:45:22";
        DateTimeFormatter dtfForParsing = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtfForParsing);
        System.out.println(ldt);// The default format as returned by LocalDateTime#toString

        // Some custom formats for output
        System.out.println("########In custom formats########");
        DateTimeFormatter dtfForFormatting1 = DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm:ss");
        DateTimeFormatter dtfForFormatting2 = DateTimeFormatter.ofPattern("dd-MM-uuuu");
        DateTimeFormatter dtfForFormatting3 = DateTimeFormatter.ofPattern("'Day: 'EEEE, 'Date: 'MMMM dd uuuu");
        System.out.println(dtfForFormatting1.format(ldt));
        System.out.println(dtfForFormatting2.format(ldt));
        System.out.println(dtfForFormatting3.format(ldt));
        System.out.println("################################");
    }
}

输出:

2010-09-29T08:45:22
########In custom formats########
29-09-2010 08:45:22
29-09-2010
Day: Wednesday, Date: September 29 2010
################################

【讨论】:

    【解决方案2】:

    java.time 和脱糖

    我建议您使用现代 Java 日期和时间 API java.time 进行日期工作。首先为您的字符串定义一个格式化程序:

    private static DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
    

    然后做:

        String dateString = "2010-09-29 08:45:22";
        LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);
        String newString = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE);
        System.out.println(newString);
    

    输出是:

    2010-09-29

    我发现解析整个字符串是一种很好的做法,即使我们目前没有使用一天中的时间。那可能会在其他一天到来。 java.time 为您的第一个输出格式DateTimeFormatter.ISO_LOCAL_DATE 提供了一个预定义的格式化程序。如果您想要相反的日、月和年顺序,我们需要为此编写自己的格式化程序:

    private static DateTimeFormatter dateFormatter
            = DateTimeFormatter.ofPattern("dd-MM-uuuu");
    

    那么我们也可以得到:

        String dmyReversed = dateTime.format(dateFormatter);
        System.out.println(dmyReversed);
    

    29-09-2010

    你的代码出了什么问题?

    问题是我会得到 03-03-0035 !!!!

    SimpleDateFormat 与标准设置的混淆程度如下:使用格式模式 dd-MM-yyyy,它将 2010-09-29 解析为 29 年第 9 个月的第 2010 天。即公元 29 年。 9 月没有 2010 天,这并没有打扰它。它只是在接下来的几个月和几年中不断计算天数,并在五年半后结束,即 35 年 3 月 3 日。

    这只是我说的一点点原因:不要使用那个类。

    问题: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 上,请使用脱糖或 Android 版本的 ThreeTen Backport。它被称为 ThreeTenABP。在后一种情况下,请确保从 org.threeten.bp 导入日期和时间类以及子包。

    链接

    【讨论】:

      【解决方案3】:
      public String formatDate(String dateString) {
          SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
          Date date = null;
          try {
              date = fmt.parse(dateString);
          } catch (ParseException e) {
              e.printStackTrace();
          }
      
          SimpleDateFormat fmtOut = new SimpleDateFormat("dd-MM-yyyy");
          return fmtOut.format(date);
      }
      

      【讨论】:

      • 欢迎来到 SO。 (1) 感谢您愿意贡献。 (2) 我们不应该再使用SimpleDateFormatDate,而是java.time,现代Java 日期和时间API。 (3) 您是否贡献了很多其他答案中尚未出现的内容? (4) 请在您的代码中给出一些解释,我们通常会学到更多。
      【解决方案4】:

      下面是在 Android Studio 3 和 Java 9 中尝试的 SimpleDateFormat 的简单示例:

      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US); 
      String strDate = sdf.format(strDate);
      

      注意: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 显示 Android Studio 3 Lint 中的一些弃用警告。因此,添加第二个 参数Locale.US 指定日期格式的本地化。

      【讨论】:

        【解决方案5】:

        如果您分别查找日期、月份和年份

        或如何使用heloisasim答案中的字母

            SimpleDateFormat day = new SimpleDateFormat("d");
            SimpleDateFormat month = new SimpleDateFormat("M");
            SimpleDateFormat year = new SimpleDateFormat("y");
        
            Date d = new Date();
            String dayS = day.format(d);
            String monthS = month.format(d);
            String yearS = year.format(d);
        

        【讨论】:

          【解决方案6】:

          我假设您想反转日期格式?

          SimpleDateFormat 可用于解析和格式化。 您只需要两种格式,一种解析字符串,另一种返回所需的打印输出:

          SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
          Date date = fmt.parse(dateString);
          
          SimpleDateFormat fmtOut = new SimpleDateFormat("dd-MM-yyyy");
          return fmtOut.format(date);
          

          从 Java 8 开始:

          DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC);
          TemporalAccessor date = fmt.parse(dateString);
          Instant time = Instant.from(date);
          
          DateTimeFormatter fmtOut = DateTimeFormatter.ofPattern("dd-MM-yyyy").withZone(ZoneOffset.UTC);
          return fmtOut.format(time);
          

          【讨论】:

          • 附带说明,普通的旧 String.format() 也可用于格式化日期输出。它不像 SimpleStringFormat 那样可读,但可能会快一点,例如:String.format("%td-%tm-%tY", date)。
          • 改为使用:new SimpleDateFormat("dd-MM-yyyy", Locale.US);
          • 实际上两者现在或多或少都被弃用了......使用新的 Instant 类可能会更好: DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC) .format(即时)
          • API 级别 26 最低适用于 android
          • 我希望您的回答对当今(和未来)的读者有所帮助。我提议按以下方式更改它,但前提是您说您同意:我会让 Java 8 代码与问题中的搅拌一起工作并将其放在首位,然后将 SimpleDateFormat 代码放在后面请注意,不再推荐。然后我会将我的反对票改为赞成票。并删除我所有的 cmets。你想我做?如果您不时接受我的编辑,然后在看到它时不喜欢它,您可以随时将其还原。
          【解决方案7】:

          花了很多功夫。我做了很多打击和试验,最后我得到了解决方案。我曾使用 ""MMM"" 将月份显示为:JAN

          【讨论】:

            【解决方案8】:

            以下是所有可用的日期格式,请阅读更多文档here

            Symbol  Meaning                Kind         Example
            D       day in year             Number        189
            E       day of week             Text          E/EE/EEE:Tue, EEEE:Tuesday, EEEEE:T
            F       day of week in month    Number        2 (2nd Wed in July)
            G       era designator          Text          AD
            H       hour in day (0-23)      Number        0
            K       hour in am/pm (0-11)    Number        0
            L       stand-alone month       Text          L:1 LL:01 LLL:Jan LLLL:January LLLLL:J
            M       month in year           Text          M:1 MM:01 MMM:Jan MMMM:January MMMMM:J
            S       fractional seconds      Number        978
            W       week in month           Number        2
            Z       time zone (RFC 822)     Time Zone     Z/ZZ/ZZZ:-0800 ZZZZ:GMT-08:00 ZZZZZ:-08:00
            a       am/pm marker            Text          PM
            c       stand-alone day of week Text          c/cc/ccc:Tue, cccc:Tuesday, ccccc:T
            d       day in month            Number        10
            h       hour in am/pm (1-12)    Number        12
            k       hour in day (1-24)      Number        24
            m       minute in hour          Number        30
            s       second in minute        Number        55
            w       week in year            Number        27
            G       era designator          Text          AD
            y       year                    Number        yy:10 y/yyy/yyyy:2010
            z       time zone               Time Zone     z/zz/zzz:PST zzzz:Pacific Standard 
            

            【讨论】:

            • 对于像我这样的人:Mysql 24 小时格式是:“yyyy-MM-dd kk:mm:ss”而不是“yyyy-MM-dd hh:mm:ss”
            • H、h、K 和 k 之间存在差异。 kk = 1-24 格式的小时。 hh= 1-12 格式的小时数。 KK = 0-11 格式的小时数。 HH= 小时,格式为 0-23。
            • 所以对于时间戳转换我需要对mysql“2016-05-18 18:53:30”使用“yyyy-MM-dd HH:mm:ss”,对吧?
            【解决方案9】:

            这对我有用...

            @SuppressLint("SimpleDateFormat")
            private void setTheDate() {
                long msTime = System.currentTimeMillis();
                Date curDateTime = new Date(msTime);
                SimpleDateFormat formatter = new SimpleDateFormat("MM'/'dd'/'y hh:mm");
                curDate = formatter.format(curDateTime);
                mDateText.setText("" + curDate);
            }
            

            【讨论】:

              【解决方案10】:
              String _Date = "2010-09-29 08:45:22"
              SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
              SimpleDateFormat fmt2 = new SimpleDateFormat("dd-MM-yyyy");
                  try {
                      Date date = fmt.parse(_Date);
                      return fmt2.format(date);
                  }
                  catch(ParseException pe) {
              
                      return "Date";    
                  }
              

              试试这个。

              【讨论】:

                【解决方案11】:

                我认为这个Link 可能会对你有所帮助

                    Date date = Calendar.getInstance().getTime();
                    //
                    // Display a date in day, month, year format
                    //
                    DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
                    String today = formatter.format(date);
                    System.out.println("Today : " + today);
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-09-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-08-03
                  相关资源
                  最近更新 更多