乔达日期时间问题与年份
Joda DateTime Issue with Year
当我运行下面的代码片段:
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。任何帮助将不胜感激。
此代码:
Date aDate1880 = new Date(-20, 0, 1);
创建一个相当于 1880 年 1 月 1 日的 Date
。由于未提供时间字段,因此将它们设置为 JVM 默认时区的午夜。在我的例子中,它是“America/Sao_Paulo”,所以下面的结果可能与你的情况不同——但它无论如何都会解释发生了什么。在我的例子中,创建日期是:
Thu Jan 01 00:00:00 BRT 1880
(January 1st 1880 at midnight in America/Sao_Paulo timezone - BRT means "Brazilian Time")
正在调用 aDate1880.getTime()
returns 值 -2840130000000
,在 UTC 中对应于 1880-01-01T03:00:00Z
。
转换为 DateTime
时,它使用 joda-time 内部时区数据,在我的例子中 DateTime
是:
1879-12-31T23:53:32.000-03:06:28
那是因为在1900年之前,很多国家都没有使用现行的时区规则,大多数城市都有自己的当地时间。而且大多数偏移量都是根据经度计算的,这就是为什么它会出现 "-03:06:28".
这样奇怪的结果
可能你的时区有类似的问题。
注意: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();
当我运行下面的代码片段:
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。任何帮助将不胜感激。
此代码:
Date aDate1880 = new Date(-20, 0, 1);
创建一个相当于 1880 年 1 月 1 日的 Date
。由于未提供时间字段,因此将它们设置为 JVM 默认时区的午夜。在我的例子中,它是“America/Sao_Paulo”,所以下面的结果可能与你的情况不同——但它无论如何都会解释发生了什么。在我的例子中,创建日期是:
Thu Jan 01 00:00:00 BRT 1880
(January 1st 1880 at midnight in America/Sao_Paulo timezone - BRT means "Brazilian Time")
正在调用 aDate1880.getTime()
returns 值 -2840130000000
,在 UTC 中对应于 1880-01-01T03:00:00Z
。
转换为 DateTime
时,它使用 joda-time 内部时区数据,在我的例子中 DateTime
是:
1879-12-31T23:53:32.000-03:06:28
那是因为在1900年之前,很多国家都没有使用现行的时区规则,大多数城市都有自己的当地时间。而且大多数偏移量都是根据经度计算的,这就是为什么它会出现 "-03:06:28".
这样奇怪的结果可能你的时区有类似的问题。
注意: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();