这是我的时间戳问题:
在MySql数据库中,列名为creation_date
,数据类型为timestamp
列中的值为2014-07-04 17:35:07.0
当我尝试使用java代码将其转换为毫秒时,它显示不同的行为
例如
如果我使用hibernate获取它并打印timestamp.getTime()
它会显示1404484507000
但在做的时候
Timestamp t=new Timestamp(2014, 7, 4, 17, 35, 7, 0);
System.out.println("t.getTime() - "+t.getTime());
显示61365297907000
这里出了什么问题。
答案 0 :(得分:1)
您是否为正在调用的(已弃用的)构造函数阅读了documentation?特别是:
年 - 年减去1900年 月 - 0到11
我强烈建议你不要打电话给那个构造函数。如果您使用的是Java 8,请使用java.time.Instant
,然后使用java.sql.Timestamp.fromInstant
。
否则,您可以调用构造函数取long
(毫秒数),然后单独设置nanos部分。
请注意,值1404484507000代表UTC时间14:35:07,因此您的数据库可能正在执行时区转换。
答案 1 :(得分:1)
来自数据库。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ; // Most databases including MySQL store a moment in a column of a data type akin to the SQL-standard `TIMESTAMP WITH TIME ZONE` as UTC. So retrieve as a `OffsetDateTime` object, expecting its zone to be set to UTC.
ZonedDateTime zdt = odt.atZoneSameInstant( ZoneId.of( "Pacific/Auckland" ) ) ; // Adjust into any time zone you desire. Same moment, different wall-clock time.
到数据库。
myPreparedStatement.setObject( // As of JDBC 4.2, exchange java.time objects with your database, not mere integers or strings.
… ,
ZonedDateTime.of(
2014 , 7 , 4 ,
17 , 35 , 7 , 0 ,
ZoneId.of( "Africa/Tunis" ) // Specify the time zone giving context to that date and time – where on earth did you mean 5 PM?
)
.toOffsetDateTime() // Adjust from that zone to UTC.
.withOffsetSameInstant(
ZoneOffset.UTC
)
) ;
现代解决方案使用 java.time 类。
LocalDate ld = LocalDate.of( 2014 , Month.JULY , 4 ) ; // Or use integer `7` for July, 1-12 for January-December.
LocalTime lt = LocalTime.of( 17 , 35 , 7 );
要确定时刻,您需要的不仅仅是日期和时间。您需要一个时区来提供上下文。您是指日本的下午5点,法国的下午5点,还是魁北克的下午5点?那将是三个不同时刻中的任何一个。
时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。例如,Paris France午夜之后的几分钟是新的一天,而Montréal Québec仍然是“昨天”。
如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将desired/expected time zone明确指定为参数。
如果要使用JVM的当前默认时区,请提出要求并作为参数传递。如果省略,则会隐式应用JVM的当前默认值。最好明确一点,因为默认值可能会在运行时的任何时候被JVM中任何应用程序的任何线程中的任何代码更改。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
从该区域调整为UTC。
OffsetDateTime odt = zdt.toOffsetDateTime().withOffsetSameInstant( ZoneOffset.UTC ) ;
从JDBC 4.2开始,我们可以直接与数据库交换 java.time 对象。
myPreparedStatement.setObject( … , odt ) ;
和检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
请注意,我们从未要求epoch reference中的整数。我们使用智能对象,而不是哑的整数或字符串。
对于Hibernate,我不是用户,但是我知道它已经更新为可以与 java.time 类一起使用。
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。
答案 2 :(得分:0)
MySQL使用与Java不同的日期格式。
您可以使用getTime和getDate函数从ResultSet转换它:
String query = "SELECT date FROM bean";
[...]
bean.setDate(toJavaDate(resultSet.getDate(1), resultSet.getTime(1)));
toJavaDate代码是:
public java.util.Date toJavaDate(java.sql.Date sqlDate, java.sql.Time sqlTime){
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.YEAR, sqlDate.getYear() + 1900);
calendar.set(Calendar.MONTH, sqlDate.getMonth());
calendar.set(Calendar.DAY_OF_MONTH, sqlDate.getDate());
calendar.set(Calendar.HOUR_OF_DAY, sqlTime.getHours());
calendar.set(Calendar.MINUTE, sqlTime.getMinutes());
calendar.set(Calendar.SECOND, sqlTime.getSeconds());
return calendar.getTime();
}
反向操作,以便在MySQL表中保存新日期:
String query = "UPDATE bean SET date = '" + toSqlDate(bean.getDate());
其中toSqlDate是:
public String toSqlDate(java.util.Date javaDate){
String sqlDate = (javaDate.getYear()+1900)+"-"+javaDate.getMonth()+"-"+javaDate.getDate()+" "
+javaDate.getHours()+":"+javaDate.getMinutes()+":"+javaDate.getSeconds();
return sqlDate;
}
现在你可以重新检查毫秒:
long milliseconds = date.getTime();