Joda DateTime年度问题

时间:2018-02-06 04:27:15

标签: java date timestamp jodatime date-conversion

当我运行以下代码段时:

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;

public class TimestampTest {

    public static void main(String... args) throws Exception {
        Date aDate1880 = new Date(-20, 0, 1);
        Timestamp timestamp = new Timestamp(aDate1880.getTime());
        DateTime dateTime = new DateTime(timestamp).withZoneRetainFields(DateTimeZone.getDefault());

        System.out.println(dateTime.year().get());

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(timestamp);

        System.out.println(calendar.get(Calendar.YEAR));
    }
}

我得到以下输出:

  

1879
  1880

由于aDate1880实际上代表了1880年,我不知道为什么Joda DateTime给予年份1879年。任何帮助都将受到赞赏。

1 个答案:

答案 0 :(得分:1)

此代码:

Date aDate1880 = new Date(-20, 0, 1);

创建一个等同于1880年1月1日的Date。由于未提供时间字段,它们将在JVM默认时区设置为午夜。就我而言,它是" America / Sao_Paulo",所以下面的结果可能与您的情况有所不同 - 但它解释了发生了什么。在我的例子中,创建的日期是:

  

Thu Jan 01 00:00:00 BRT 1880

     

(1880年1月1日午夜在美国/ Sao_Paulo时区 - BRT意味着"巴西时间")

调用aDate1880.getTime()会返回值-2840130000000,该值与UTC对应1880-01-01T03:00:00Z

转换为DateTime时,它会使用joda-time内部时区数据,在我的情况下,DateTime是:

  

<强> 1879 -12-31T23:53:32.000-03:06:28

那是因为在1900年之前,许多国家都没有使用现行的时区规则,大多数城市都有自己的当地时间。大多数偏移都是根据经度来计算的,这就是为什么它有如&#34; -03:06:28&#34; 这样的奇怪结果。

可能你的时区有类似的问题。

注意:new DateTime(timestamp)已使用默认时区,因此对withZoneRetainFiels的调用是多余的:

DateTime dateTime = new DateTime(timestamp);
// this prints "true"
System.out.println(dateTime.equals(dateTime.withZoneRetainFields(DateTimeZone.getDefault())));

要创建所需的日期,您只能使用Joda-Time类:

// January 1st 1880, at midnight in JVM default timezone
DateTime d = new LocalDate(1880, 1, 1).toDateTimeAtStartOfDay();