【问题标题】:Parsing String date to date [duplicate]解析字符串日期至今[重复]
【发布时间】:2014-07-15 00:23:16
【问题描述】:

我有一个格式为“YYYY-MM-dd HH::mm:ss”的日期字符串。每次我解析字符串时,我都会得到错误的日期。(“Sun Dec 29 10:10:10 CET 2013”​​)。代码如下:

DateFormat timeFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
Date startDate = timeFormat.parse("2014-08-10 10:10:10");
System.out.println(startDate);

这将返回“2013 年 12 月 29 日星期日 10:10:10 CET”。如何正确解析日期字符串?

【问题讨论】:

标签: java parsing date date-formatting


【解决方案1】:

您需要使用yyyy,而不是使用YYYY

Y 指的是 WEEK_YEAR,而y 指的是 YEAR。 WEEK_YEAR 基于一年中第一个完整周的开始时间(这取决于设置),因此与 YEAR 略有(有时很大)不同。

查看 javadoc: http://docs.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#week_year

【讨论】:

    【解决方案2】:

    您使用了错误的格式。你需要yyyy 而不是YYYY

    如果你看看SimpleDateFormat documentation你会发现

    y   Year
    Y   Week year
    

    其中“week year”与WEEK_OF_YEAR 循环同步。

    现在,为什么 YYYY 会为 2014 年返回 2013 年?

    要回答这个问题,您需要了解日历如何确定该周属于某一年。规则很简单:

    • 如果这周的最后一个 N 天(通常 N=4 但由使用的日历中的 getMinimalDaysInFirstWeek 确定)属于 XXXX 年,则该周属于 XXXX 年
    • 周从getFirstDayOfWeek 的结果开始。此结果取决于区域设置,但在接下来的示例中,我们将使用星期一作为一周的第一天。

    示例 1.

    假设一周的第一天是星期一,一周需要属于某年的天数是 4,让我们尝试确定哪一周是 XXXX 年 1 月的第一天,如下所示:

           January XXXX
    Mon Tue Wed Thu Fri Sat Sun 
     27  28  29  30  31   1   2
      3   4   5   6   7   8   9
    ...
    

    第一行的周仅包含属于 XXXX 年(到一月)的第一天和第二天的两天

     27  28  29  30  31   1   2
                        ^^^ ^^^  //days which belong to January
    

    但这少于下周属于 XXXX 年所需的天数

      3   4   5   6   7   8   9
    

    包含属于 XXXX 年的 7 天。由于第一行中的周不属于 XXXX 年第一周 周年 将从 XXXX 年 1 月 3 日开始。这意味着如果我们将值XXXX 解析为YYYY 格式,我们将得到3rd January XXXX

    示例 2。

    现在假设 XXXX 年的日历看起来像这样

           January XXXX
    Mon Tue Wed Thu Fri Sat Sun 
     30  31   1   2   3   4   5
      6   7   8   9  10  11  12
    ...
    

    正如你在一周中看到的那样

     30  31   1   2   3   4   5
    

    它的最后 5 天属于 XXXX 年,比要求的 4 天多
    -> 表示本周属于 XXXX 年,
    -> 这也是 XXXX 年的第一周
    -> 这意味着今年的第一周开始于30 December (XXXX-1)
    -> 这最终意味着如果您使用YYYY 格式解析这样的年份,您将获得值 XXXX-1。


    示例2实际上是来自2014的情况,这就是为什么将年份解释为2013的原因。

    顺便说一句,如果您决定使用带有星期年份的格式来设置月份和日期,您还需要使用特殊格式来描述

    • 您要设置一年中的哪一周
    • 以及星期几

    所以你必须使用 Md 而不是

    w   Week in year
    u   Day number of week (1 = Monday, ..., 7 = Sunday)
    

    (小时、分钟、秒是时间的一部分而不是日期,所以 H ms 可以采用这种格式)

    例如

    DateFormat format = new SimpleDateFormat("YYYY-ww-uu HH:mm:ss");
    Date date = format.parse("2004-53-7 10:10:10");
    System.out.println(date);
    

    将被解析为Sun Jan 02 10:10:10 CET 2005

    【讨论】:

    • 评论多于回答?
    • @hd1 这是解决方案(所以回答,低质量但仍然回答),我正在研究“为什么”部分。
    • @hd1 这样就解决了问题。
    • 如果解决了问题,接受答案,忽略我的评论
    • “为什么”是YYYYweek-year,与年份不同,represented as yyyy
    猜你喜欢
    • 2019-08-26
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多