【问题标题】:Parsing from String to Date throws Unparsable Date Error从字符串解析到日期会引发不可解析的日期错误
【发布时间】:2018-05-24 16:23:38
【问题描述】:

我有一个名为data 的变量,它具有今天的日期,格式如下:Thu May 24 13:14:41 BRT 2018。然后我将其格式化为 MySQL 的 Date 类型格式,即yyyy-MM-dd。这段代码做到了:

String dataFormatada = new SimpleDateFormat("yyyy-MM-dd").format(data);

我想要做的是将它带回日期类型。我尝试了一些东西,但它们没有用。主要的解决方案是按照其他Stack Overflow's questioin 中的说明进行操作,并且通过一个小模型,我得到了我想要的东西:

String target = "Thu Sep 28 20:29:30 JST 2000";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date result =  df.parse(target);  
System.out.println(result);

但它不起作用,因为我在尝试解析时收到此错误:

java.text.ParseException: Unparseable date: "Thu Sep 28 20:29:30 JST 2000"

所以我不能只重新格式化data 变量,也不能将dataFormatada 恢复为日期格式。如何将dataFormatada 带入格式为 yyyy-MM-dd 的日期类型?

【问题讨论】:

标签: java date


【解决方案1】:

您的目标字符串格式为EEE MMM dd HH:mm:ss zzz yyyy 格式。所以你需要使用EEE MMM dd HH:mm:ss zzz yyyy 作为模式而不是yyyy-MM-dd

    String target = "Thu Sep 28 20:29:30 JST 2000";
    DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);
    Date result =  df.parse(target);  
    System.out.println(result);

如果您想将 Date 对象(即结果)转换为 yyyy-MM-dd,请使用以下代码。

    DateFormat dfDateToStr = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
    String formattedDate  = dfDateToStr.format(result);
    System.out.println("Formatted Date String : "+formattedDate);

【讨论】:

  • 这给了我一个“EEE MMM dd HH:mm:ss zzz yyyy”格式的日期。我需要最终的日期类型为“yyyy-MM-dd”
  • @William 你得到的结果是Date objectDate 真的没有任何格式。当你打印它调用 Date#toString
【解决方案2】:

您需要两个格式化程序,一个将原始字符串解析为Date 对象,一个将其格式化为所需的字符串:

public static void main(String[] args) throws Exception {
    String target = "Thu Sep 28 20:29:30 JST 2000";
    DateFormat parser = new SimpleDateFormat("EEE MMM dd kk:mm:ss z yyyy", Locale.ENGLISH);
    Date result = parser.parse(target);
    System.out.println(result);

    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    String dataFormatada = format.format(result);
}

【讨论】:

  • 这个方法最后给了我一个格式正确的字符串,但我需要一个日期,而不是字符串,@Neng Liu 先生
【解决方案3】:

tl;博士

对于 SQL 标准的 DATE 列,将 java.time.LocalDate 类与 JDBC 4.2 或更高版本一起使用。

myPreparedStatement.setObject(
    … ,
    ZonedDateTime.parse(  // Represent a moment in a particular time zone.
        "Thu May 24 13:14:41 BRT 2018".replace( "BRT" , "Europe/London" ) ,
        DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" , Locale.UK )
    )
    .toLocalDate()        // Extract a date-only value, without time-of-day and without time zone.
)

ISO 8601

我有一个名为 data 的变量,它有今天的日期,格式如下:Thu May 24 13:14:41 BRT 201

这是一种可怕的格式。将日期时间值交换为文本时,仅使用标准的ISO 8601 格式。方便的是,java.time 类在解析/生成字符串时默认使用这些格式。

BST = ?? (巴西标准时间、英国标准时间……)

continent/region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的缩写,例如 BSTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。

ZonedDateTime 类将尝试猜测预期的时区。但是您不应该依赖代码中的猜测。

String input = "Thu May 24 13:14:41 BRT 2018";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" , Locale.UK );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );

2018-05-24T13:14:41-03:00[美国/圣保罗]

看起来 java.time 猜到了 BST 的意思是 Brazil Standard Time。如果您指的是其他时区,例如英国时间,请将 BST 字符串替换为适当的时区名称。

指定 Locale 以确定 (a) 用于翻译日期名称、月份名称等的人类语言,以及 (b) 决定缩写、大写、标点符号、分隔符等问题的文化规范。

String input = "Thu May 24 13:14:41 BRT 2018".replace( "BRT" , "Europe/London" );
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" , Locale.UK );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );

2018-05-24T13:14:41+01:00[欧洲/伦敦]

LocalDate

您显然只关心日期。所以提取一个只有日期的对象,一个LocalDate

LocalDate ld = zdt.toLocalDate() ;

智能对象,而不是哑字符串

不要与您的数据库交换日期时间值作为文本。而是使用 JDBC 和对象。从 JDBC 4.2 及更高版本开始,您可以直接与数据库交换 java.time 对象。

myPreparedStatement.setObject( … , ld ) ;

检索。

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

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

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

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

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

  • 英国夏令时。只是为了强调混乱。
猜你喜欢
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-21
  • 1970-01-01
相关资源
最近更新 更多