java.sql.Date date = java.sql.Date.valueOf("1900-01-01");
org.joda.time.LocalDate localDate = new org.joda.time.LocalDate(date);
基于上面的代码,我做了一些测试如下:
如果我将当地时区更改为UTC+8 Singapore Timezone
,将获得1899-12-31
如果我将当地时区更改为UTC+8 China Timezone
,将获得1900-01-01
如果我将当地时区更改为UTC-8 America/Los_Angeles Timezone
,将获得1900-01-01
如果我将当地时区更改为UTC+8 China Timezone
,将获得1900-01-01
有人可以帮忙澄清一下吗?它有点困惑。
在1900年,Singpore's抵消是UTC +6:55:25
,所以当你在新加坡时区创建日期1900-01-01
时,它应该是1899-12-31T17:04:35Z[UTC]
如下:
java.time.ZonedDateTime localDateTime = ZonedDateTime.of(1900, 01, 01, 0,
0, 0, 0, ZoneId.of("Singapore"));
System.out.println(localDateTime.withZoneSameInstant(ZoneId.of("UTC")));
// 1899-12-31T17:04:35Z[UTC]
但是,当你使用java.sql.Date
时,它使用错误的偏移量UTC +08:00
:
TimeZone.setDefault(TimeZone.getTimeZone("Singapore"));
java.sql.Date date = java.sql.Date.valueOf("1900-01-01");
java.time.Instant instant = Instant.ofEpochMilli(date.getTime());
System.out.println(instant); // 1899-12-31T16:00:00Z
当你用这个错误的值创建org.joda.time.LocalDateTime
时,Joda使用UTC +6:55:25
作为偏移量,导致日期时间1899-12-31T16:00:00 + 6:55:25
:
org.joda.time.LocalDateTime singaporeDateTime = new org.joda.time.LocalDateTime(date);
System.out.println(singaporeDateTime); // 1899-12-31T22:55:25.000
您可以使用类似的方法来检查上海和洛杉矶的结果,重点是,避免使用java.sql.Date
和其他已弃用的日期时间相关的类。如果您使用的是java8或更高版本,请使用java.time
。
java.time.LocalDate
.of(
1900 ,
Month.JANUARY ,
1
) ;
你正在使用一个可怕的旧类java.sql.Date
,设计糟糕,有缺陷的黑客。它的问题之一是它假装代表一个仅限日期的值,但实际上保持一个时间。它甚至可以在内部保持一个时区,但没有吸气剂或二传手。永远不要使用这门课。几年前由java.time.LocalDate
类取代。
Joda-Time项目也被java.time类所取代。该项目处于维护模式,接收更新和关键错误修复,但没有新功能。该项目建议迁移到java.time类。迁移很容易,因为他们有着相似的概念,两者都是由同一个人Stephen Colebourne领导的。
java.time.LocalDate
如果您想要一个没有时间且没有时区的仅限日期的值,请使用java.time.LocalDate
。你问题中提出的所有问题都会消失。
java.time.LocalDate ld = LocalDate.of( 1900 , Month.JANUARY , 1 ) ; // Simply a year-month-day date, no problems, no issues, no confusion.
ld.toString():1900-01-01
另请注意,java.time使用合理的编号,其中2018
表示2018年,1-12表示1月至12月。这与麻烦的遗产类形成鲜明对比。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.Date
,Calendar
和SimpleDateFormat
。
现在在Joda-Time的maintenance mode项目建议迁移到java.time班。
要了解更多信息,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规格是JSR 310。
您可以直接与数据库交换java.time对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。你可能会在这里找到一些有用的类,如Interval
,YearWeek
,YearQuarter
和more。