爪哇的古怪约会

问题描述 投票:0回答:4

以下 Java 代码仅使用

2009-01-28-09:11:12
解析日期(带时间部分)
SimpleDateFormat
。我们来看看吧。

final public class Main
{
    public static void main(String[] args)
    {            
        try
        {
            DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
            Date d = df.parse("2009-01-28-09:11:12");
            System.out.println(d);
        }
        catch (ParseException ex)
        {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

上述代码(解析后)显示的日期(带时间)如下,

Sun Nov 30 22:07:51 IST 2008

即使我们正在尝试解析日期

2009-01-28-09:11:12
。看起来有些古怪。为什么会这样解析?

java date-parsing
4个回答
5
投票

你的日期格式不应该是这样的吗:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");

要匹配此格式:

Date d = df.parse("2009-01-28-09:11:12");

至于为什么,按此:

解析器实际上将这些视为数字,技巧是 - 是数字的一部分,代表负数。所以如果你这样做:

df.parse("2009-01-02-00:00:00")

它给出:

Mon Dec 01 00:02:00 EST 2008

将 2009 解析为 yyyy,然后将 -0 解析为 MM(这是上个月,因为月份从 1 开始),然后将 1 解析为 dd,等等。

根据 DateFormat 中的解析:

默认情况下,解析是宽松的:如果输入不是该对象的 format 方法使用的形式,但仍然可以解析为日期,则解析成功。客户端可以通过调用 setLenient(false) 来坚持严格遵守格式。

我想,如果您有选择的话,如果您喜欢像 2009/01/02 12:34:56 这样的格式,最好使用斜杠而不是破折号。这个:

df.parse("2009/01/02-00:00:00")

会抛出异常:

ERROR java.text.ParseException:
Unparseable date: "2009/01/02-00:00:00"

我只能得出结论,

/
不被视为DateFormat的数字除法,这是一件非常好的事情...


2
投票

好吧,您可以定义您实际正在解析的格式...


1
投票

默认情况下以宽松模式解析日期。这意味着如果不是闰年,它会容忍诸如将 2 月 29 日解析为 3 月 1 日之类的错误。您要求它解析的是 2009 年 -1 月的 -28 天,它会尽职尽责地尝试准确地为您提供您所要求的内容。

要关闭此行为,请调用 format.setLenient(false)。然后,如果您尝试解析不是真实日期的内容,则日期格式将引发异常。


0
投票

tl;博士

如果您必须为数据使用自定义格式而不是标准格式,请定义与

java.time.format.DateTimeFormatter
匹配的格式模式以解析为
java.time.LocalDateTime
对象。

LocalDateTime
.parse ( 
    "2009-01-28-09:11:12" , 
    DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH:mm:ss" ) 
)
.toString()  // Generate text in standard ISO 8601 format. 

2009-01-28T09:11:12

避免遗留类

您正在使用有严重缺陷的遗留类,这些类已被 JSR 310 for Java 8+ 中定义的现代 java.time 类所取代。

java.time

DateTimeFormatter

定义格式模式以匹配您的非标准格式。实例化一个

DateTimeFormatter
对象。

String input = "2009-01-28-09:11:12" ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH:mm:ss" ) ;

LocalDateTime 

要表示包含当天时间但缺少时区上下文或相对于 UTC 的偏移量的日期,请使用

java.time.LocalDateTime

LocalDateTime ldt = LocalDateTime.parse ( input , formatter );

ISO 8601

ISO 8601 是文本日期时间格式的国际标准。

日期(带时间部分)2009-01-28-09:11:12

不要发明自己的格式,而是使用 ISO 8601。日期的标准格式在日期部分和时间部分之间使用

T

2009-01-28T09:11:12

java.time 类在解析/生成文本时默认使用 ISO 8601 格式。

解析:

LocalDateTime ldt = LocalDateTime.parse( "2009-01-28T09:11:12" ) ;

生成:

String output = ldt.toString() ;  // Produces "2009-01-28T09:11:12".
© www.soinside.com 2019 - 2024. All rights reserved.