java.util.Date到java.sql.Date转换给出了错误的月份

时间:2011-10-16 15:40:58

标签: java date jdbc

请考虑以下代码段:

Calendar futureDate = Calendar.getInstance();
int year = 2011;
int month = 11;
int day = 14;
futureDate.set(year,month, day);
System.out.println(futureDate.toString());
java.sql.Date sqlDate  = new java.sql.Date( futureDate.getTime().getTime());

futureDate.toString()的打印输出是:

...年代= 2011,月= 11,WEEK_OF_YEAR = 43,WEEK_OF_MONTH = 4,DAY_OF_MONTH = 14,DAY_OF_YEAR = 289,DAY_OF_WEEK = 1,DAY_OF_WEEK_IN_MONTH = 3,AM_PM = 0,HOUR = 11,HOUR_OF_DAY = 11,MINUTE = 32,SECOND = 51,微差= 117,ZONE_OFFSET = -18000000,DST_OFFSET = 3600000]

表示Calendare对象保存正确的日期。但是,在转换为sql日期并存储在数据库(MySQL通过JDBC)之后,MySQL表显示此日期的“2011-12-14”而不是“2011-11-14”。 我会怀疑地区和时区,但这些会导致一天中的时间不符合日期的部分时间。

我做错了什么线索?

2 个答案:

答案 0 :(得分:5)

Calendar#set(int, int, int)将month参数解释为从零开始,因此futureDate.set(2011, 11, 14)将日历的月份设置为12月。

答案 1 :(得分:0)

TL;博士

LocalDate.of( 2011 , 11 , 14 )  // November 14th, 2011

详细

Matt Ball的回答是正确的。但现在有一种改进的方式。

java.time

麻烦的旧日期时间类如Calendarjava.util.Datejava.sql.Date现在已经遗留下来,取而代之的是java.time类。

与旧版类不同,java.time类具有理智的编号,例如1月到12月的编号 1-12 ,周一编号为1-7到星期天。

LocalDate类表示没有时间且没有时区的仅限日期的值。

LocalDate ld = LocalDate.of( 2011 , 11 , 14 ) ;

或者使用方便的Month枚举。

LocalDate ld = LocalDate.of( 2011 , Month.NOVEMBER , 14 ) ;

使用支持JDBC 4.2及更高版本的JDBC驱动程序,您可以将java.time对象直接传递给数据库。

myPreparedStatement.setObject( … , ld ) ;

提取时,请使用getObject

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore