Simpledateformat无法解析的日期

时间:2018-03-09 11:04:06

标签: java android date simpledateformat date-parsing

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

  

2018年1月4日

这是我要格式化的日期,存储为日/月/年。我想为我的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"

7 个答案:

答案 0 :(得分:3)

使用我创建的日期格式化方法

    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") 

您将获得所需的输出

答案 1 :(得分:3)

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

日期代表日期的文字之间存在差异。

示例:今天的日期 2018年3月9日。那个日期只是一个概念,是“我们日历系统中特定点”的概念。

但是,同一日期可以以多种格式表示。它可以是“图形”,围绕一张纸上的数字以及某些特定顺序的许多其他数字形成的圆形,或者可以是纯文本,例如:< / p>

  • 09/03/2018(日/月/年)
  • 03/09/2018(monty / day / year)
  • 2018-03-09(ISO8601 format
  • March,9 th 2018
  • 9demarçode2018(葡萄牙语)
  • 2018年3月5日(日文)
  • 等......

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

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

在Android中,您可以使用java.time类(如果您使用的API级别可用),或threeten backport的API级别低于check here how to use it。您将拥有更轻松,更可靠的工具来处理日期。

在您的情况下,您有String(表示日期的文本),并且您希望将其转换为其他格式。您必须分两步完成:

  1. String转换为某种日期类型(将文本转换为数字日/月/年值) - 这称为解析
  2. 将此日期类型值转换为某种格式(将数值转换为特定格式的文字) - 称为格式
  3. 为什么你的尝试不起作用:

    • 第一次尝试给你错误的格式,因为你调用了Date::toString() method,它以该格式(Sun Apr 08 00:00:00 GMT+00:00 2018)生成输出(文本表示) - 所以解析是正确的,但是格式化没有“T
    • 在第二次尝试中,您使用了输出模式(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

答案 2 :(得分:1)

尝试使用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

答案 3 :(得分:1)

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

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());
}

答案 4 :(得分:1)

tl; dr

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

正确使用数据类型

我在数据库(match.getDate)中有一个具有以下日期格式的字符串:

请勿将日期时间值存储为文本。

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

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

java.time

其他答案使用过时的类,几年前被内置于Java 8和更高版本以及现代Android 26和更高版本的现代 java.time 类所取代。对于早期的Java和Android,请参见下面的链接。

在Java中,无日期且无时区的仅日期值由LocalDate类表示。

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框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

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

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

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

在哪里获取java.time类?

答案 5 :(得分:0)

试试这个,您可以使用此

创建所需的任何日期格式
        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 "";
    }

答案 6 :(得分:0)

首先检查你的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日星期五