Java Date + Calendar提供的结果与预期不同

时间:2014-10-13 20:13:19

标签: java datetime

我有以下代码:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CalendarTest {

    public static void main(String[] args) {

        try {

            Calendar calendar = Calendar.getInstance();

            Date _date = new SimpleDateFormat("ddMMyyyy").parse("13102014");
            Date _time = new SimpleDateFormat("hhmmss").parse("201100");

            calendar.setTimeInMillis(_date.getTime() + _time.getTime());

            System.out.println(calendar.getTime()); // NOK 1 hour less

        } catch (ParseException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
}

为什么会产生:

  

10月13日星期一 19 :2014年CEST 2014

而不是:

  

10月13日星期一 20 :2014年CEST 2014

4 个答案:

答案 0 :(得分:4)

UTC与DST

因为java.util.Date在UTC中工作。但是,当生成日期时间值的字符串表示时,其toString方法会混淆地应用JVM的当前默认时区。

我认为您的JVM当前默认时区是夏令时(DST),因此是小时调整。

24小时时间

此外,您的小时代码应为HH 24小时,而不是hh 12小时。

答案 1 :(得分:1)

我想说可以通过简单的改变产生所需的输出。不需要JODA或Java 8。我不明白你为什么用你的方式写它。

package cruft;

/**
 * CalendarTest description here
 * @author Michael
 * @link  https://stackoverflow.com/questions/26348140/java-date-calendar-giving-different-results-as-expected
 * @since 10/13/2014 4:16 PM
 */
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CalendarTest {

    public static void main(String[] args) {

        try {

            Calendar calendar = Calendar.getInstance();

            Date _date = new SimpleDateFormat("ddMMyyyy hhmmss").parse("13102014 201100");

            calendar.setTimeInMillis(_date.getTime());

            System.out.println(calendar.getTime()); 

        } catch (ParseException e1) {
            e1.printStackTrace();
        }
    }
}

这是我得到的输出:

"C:\Program Files\Java\jdk1.7.0_45\bin\java" -Didea.launcher.port=7536 "
Mon Oct 13 20:11:00 EDT 2014

Process finished with exit code 0

答案 2 :(得分:1)

当您只分析与日期分开的时间时,它会将其视为1970年1月1日的时间。这是在标准时间的冬天。因此,当您将两者结合在一起时,您将得到一个标准时间内的值,比当前时间的一个小时落后于白天时间。

答案 3 :(得分:0)

约达时间

java.util.Date和.Calendar类非常麻烦。避免他们。请使用合格的日期时间库。在Java中,这意味着:

  • Joda-Time
    许多人多年来使用古老的图书馆作为j.u.Date/Calendar的替代品。
  • java.time│与Java 8捆绑在一起,灵感来自Joda-Time,由JSR-310定义,在The Tutorial中描述)

在Joda-Time中,DateTime对象知道自己指定的时区(与j.u.Date不同)。

你的问题中的字符串格式非常糟糕。如果可能,请使用ISO 8601标准字符串替换。标准字符串更具可读性和直观性。此外,Joda-Time和java.time都默认解析并生成标准字符串。

使用Joda-Time 2.5的示例代码。我们不知道你的时区,所以我随意选择柏林。我假设您的输入字符串代表该时区的一个时刻,尽管您的问题不明确。

解析输入字符串。

String input = "13102014201100";
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Berlin" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "ddMMyyyyHHmmss" );
DateTimeFormatter formatterBerlin = formatter.withZone( timeZone );
DateTime dateTimeBerlin = formatterBerlin.parseDateTime( input );

调整到另一个时区。在这种情况下,UTC

DateTime dateTimeUtc = dateTimeBerlin.withZone( DateTimeZone.UTC );

转储到控制台。

System.out.println( "input: " + input );
System.out.println( "dateTimeBerlin: " + dateTimeBerlin );
System.out.println( "dateTimeUtc: " + dateTimeUtc );

跑步时。

input: 13102014201100
dateTimeBerlin: 2014-10-13T20:11:00.000+02:00
dateTimeUtc: 2014-10-13T18:11:00.000Z