Simpledateformat 不可解析的日期

Simpledateformat unparseable date

我在数据库 (match.getDate) 中有一个 String,其日期格式如下:

01/04/2018

这是我要格式化的日期,存储为day/month/year。我想为我的 Android 应用程序设置格式。

我想将日期格式化为:

Sun 01 Apr 2018

我的代码如下:

SimpleDateFormat fDate = new SimpleDateFormat("dd/MM/yyyy");
try {
    textViewDate.setText(fDate.parse(match.getDate()).toString());
} catch (ParseException ex) {
    System.out.println(ex.toString());
}

这输出:

Sun Apr 08 00:00:00 GMT+00:00 2018.

我也试过"EE, MM d, yyyy",但它给了我:

java.text.ParseException: Unparseable date: "01/04/2018"

试试 new SimpleDateFormat("EEE dd MMM yyyy", Locale.ENGLISH);

示例代码:

DateFormat originalFormat = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);
DateFormat targetFormat = new SimpleDateFormat("EEE dd MMM yyyy", Locale.ENGLISH);
Date date = originalFormat.parse("01/04/2018");
String formattedDate = targetFormat.format(date);  // Sun 01 Apr 2018

使用我创建的这个日期格式化程序方法

    public static String dateFormater(String dateFromJSON, String expectedFormat, String oldFormat) {
    SimpleDateFormat dateFormat = new SimpleDateFormat(oldFormat);
    Date date = null;
    String convertedDate = null;
    try {
        date = dateFormat.parse(dateFromJSON);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(expectedFormat);
        convertedDate = simpleDateFormat.format(date);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return convertedDate;
}

并像

一样调用此方法
dateFormater(" 01/04/2018" , "EE dd MMM yyyy" , "dd/MM/yyyy") 

你会得到想要的输出

试试这个,你可以用这个创建任何你想要的日期格式

        public String parseTime(String date){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-dd-MM HH:mm:ss");
        try {
            Date date1 = format.parse(date.replace("T"," "));
            String d= new SimpleDateFormat("yyyy/dd/MM HH:mm:ss").format(date1);
            return d;
        }catch (Exception e){
            e.printStackTrace();
        }
        return "";
    }

这里需要两个日期格式化程序。一个用于解析输入,另一个格式化程序用于格式化输出。

SimpleDateFormat inDateFmt = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat outDateFmt = new SimpleDateFormat("EEE dd MMM yyyy");
try {
    Date date = inDateFmt.parse(match.getDate());
    textViewDate.setText(outDateFmt.format(date));
} catch (ParseException ex) {
    System.out.println(ex.toString());
}

首先检查您的 match.getDate() 方法,如果上面给出了给定日期的格式,则使用下面的代码并在上面定义的格式中显示日期...

String date="09/03/2018";
    SimpleDateFormat parseDateFormat = new SimpleDateFormat("dd/MM/yyyy"); // if your match.getDate() given this format date.and if is given different format that time define that format.
    DateFormat formatdate = new SimpleDateFormat("EEE dd MMM yyyy");

    try {
        Date date1=parseDateFormat.parse(date);
        Log.d("New Date",formatdate.format(date1));
    } catch (ParseException e) {
        e.printStackTrace();
    }

输出:: 2018 年 3 月 9 日星期五

其他答案解决了您的问题,但我认为了解一些概念以及您第一次尝试失败的原因很重要。

日期和表示日期的文本之间存在差异

示例:今天的日期是 2018 年 3 月 9 日。那个日期只是一个概念,一个想法 "a specific point in our calendar system".

不过,同一日期可以以多种格式表示。它可以是 "graphical",在一张纸上以圆圈形式围绕一个数字,并以某种特定顺序包含许多其他数字,也可以是 纯文本 ,如:

  • 2018 年 9 月 3 日(day/month/year)
  • 2018 年 3 月 9 日(monty/day/year)
  • 2018-03-09 (ISO8601 format)
  • 2018 年 3 月 9 日
  • 9 de março de 2018(葡萄牙语)
  • 2018年3月5日(日语)
  • 等等...

请注意,文本表示形式不同,但它们都表示相同的日期(相同的值)。

考虑到这一点,让我们看看 Java 如何使用这些概念。

  • 一段文字由String表示。这个 class 包含一个字符序列,仅此而已。这些字符可以代表任何东西;在这种情况下,它是一个日期
  • 日期最初由 java.util.Date 表示,然后由 java.util.Calendar 表示,但 those classes are full of problems and you should avoid them if possible. Today we have a better API for that.

在 Android 中,您可以使用 java.time classes(如果在您正在使用的 API 级别或 threeten backport for API levels lower than that ( 中可用) .您将拥有更简单、更可靠的工具来处理日期。

在您的例子中,您有一个 String(表示日期的文本)并且您想要将其转换为另一种格式。您必须分两步完成:

  1. String 转换为某些 date-type(将文本转换为数值 day/month/year 值)- 这称为 解析
  2. 将此 date-type 值转换为某种格式(将数值转换为特定格式的文本)- 这称为 格式化

为什么你的尝试没有奏效:

  • 第一次尝试给出了错误的格式,因为您调用了 Date::toString() method,它以该格式 (Sun Apr 08 00:00:00 GMT+00:00 2018) 生成输出(文本表示)——因此解析是正确的,但是格式不是
  • 在第二次尝试中,您使用了输出模式(EE dd MMM yyyy,您应该用于格式化的模式)来解析日期(这导致 ParseException)。

对于第 1 步,您可以使用 LocalDate,一种表示日期的类型(日、月和年,没有小时和时区),因为这就是您的输入:

String input = "01/04/2018";
DateTimeFormatter inputParser = DateTimeFormatter.ofPattern("dd/MM/yyyy");
// parse the input
LocalDate date = LocalDate.parse(input, inputParser);

这比 SimpleDateFormat 更可靠,因为它解决了旧 API 的 lots of strange bugs and problems

现在我们有了 LocalDate 对象,我们可以执行第 2 步:

// convert to another format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EE dd MMM yyyy", Locale.ENGLISH);
String output = date.format(formatter);

请注意,我使用了 java.util.Locale。那是因为你想要的输出有英文的星期几和月份名称,如果你没有指定语言环境,它将使用 JVM 的默认值(谁保证它总是英文?最好告诉API 您使用的是哪种语言,而不是依赖于默认配置,因为这些配置可以随时更改,甚至可以被同一 JVM 中的其他应用程序 运行 更改。

我怎么知道 DateTimeFormatter 中必须使用哪些字母?好吧,我刚读完 javadoc.

tl;博士

LocalDate
.parse( 
    "01/04/2018"  ,
    DateTimeFormatter            // Parses & generates text in various formats
    .ofPattern( "dd/MM/uuuu" )   // Define a formatting pattern to match your input.
)                                // Returns a `LocalDate` object.
.toString()                      // Generates text in standard ISO 8601 format.

2018-04-01

适当使用数据类型

I have a String in a database (match.getDate) that has the following date format:

不要将日期时间值存储为文本。

您应该使用日期时间数据类型将日期时间值存储在数据库中。在标准 SQL 中,没有时间和时区的仅日期值存储在 DATE.

类型的列中

另一个问题是,您试图在 Java class 中表示一个仅限日期的值,该值表示一个时刻,一个在时区或偏移量上下文中带有时间的日期-来自-UTC。方钉,圆孔。使用仅限日期的数据类型可以解决您的问题。

java.time

其他答案使用过时的 classes,多年前被现代 java.time classes 取代 Java 8 及更高版本,并内置于 Android 26 及更高版本中。对于较早的 Java 和 Android,请参阅下面的链接。

在 Java 中,没有时间和时区的仅日期值由 LocalDate class.

表示
LocalDate ld = LocalDate.parse( "2020-01-23" ) ;  // Parsing a string in standard ISO 8601 format.

对于自定义格式模式,请使用 DateTimeFormatter

String input = "01/04/2018" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;

生成标准 ISO 8601 格式的字符串。

String output = ld.toString() ;

以您的自定义格式生成一个字符串。

String output = ld.format( f ) ;

提示:使用 DateTimeFormatter.ofLocalizedDate 自动本地化您的输出。


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* classes.

从哪里获得java.time classes?