In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
In this issue, Xiaobian will bring you an error analysis on how to understand Java Date Timestamp date comparison. The article is rich in content and analyzed and described from a professional perspective. After reading this article, I hope you can gain something.
Scene reproduction:
In the mysql database (innodb engine) tab table there is a createAt field of type datetime(6) accurate to milliseconds. Of course, we all know that the date field of mysql is only accurate to the second level by default. To be accurate to the millisecond level, it can be defined as datetime(6). It is supported since version 5.6.4.
Business interface A stores a record in the table through the ORM framework, where createAt is stored
2016-04-13 15:20:39.152
Business interface B needs to find that this record is loaded into entity class Entity, where createAt attribute is Date type, and the value is the date above. (Note: If @Temporal(TemporalType.TIMESTAMP) annotation is added, the field type is Timestamp.) This scene is Date)
Get the current system time, note that Timestamp is used here
Date now = new Timestamp(System.currentTimeMillis())
millisecond formatted string is 2016-04-13 15:20:39.952
You'll notice there's an extra millisecond fraction 952.
Calling now.after(entire.createAt) expected to return true, but actually returned false!!
This led to a strange situation: a record with a timestamp was originally stored in the database, but when it was taken out and compared with the current system timestamp, it was discovered that the previously stored time was in the future?!
What happened here that caused
Current system time.after = false?
source code analysis
You can see the problem by looking at the source code.
First, the first if judgment of the Date class method getMillisOf() is that date is not empty, but isNormalized() returns true. This normalize is a private property in CalendarDate, and becomes false whenever a method such as set/add is called to modify the time. For further information, see the cdate notes.
Second, the Date constructor directly assigns the system's millisecond long value to fasttime.
Again, the Timestamp constructor intercepts seconds of time and stores them in fasttime, counting milliseconds into nanos.
/* * If cdate is null, then fastTime indicates the time in millis. * If cdate.isNormalized() is true, then fastTime and cdate are in * synch. Otherwise, fastTime is ignored, and cdate indicates the * time. */
private transient BaseCalendar.Date cdate;public Date() {
this(System.currentTimeMillis());}
public Date(long date) { fastTime = date;}
static final long getMillisOf(Date date) {
if (date.cdate == null || date.cdate.isNormalized()) {
return date.fastTime; } BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
return gcal.getTime(d);}Timestamp construction method:
public Timestamp(long time) {
super((time/1000)*1000); //millisecond Divide 1000 to the nearest second and multiply by 1000 to get the millisecond value nanos = (int)((time00) * 1000000);
if (nanos
< 0) { nanos = 1000000000 + nanos; super.setTime(((time/1000)-1)*1000); }} 调试分解 然后我们对比下new Date() vs new Timestamp(System.currentTimeMillis()) 两者存储方式的区别通过下面两个图就可以清楚分辨,只要注意fastTime。 Date fastTime的最后三位是956,说明是精确到毫秒的 Timestamp的最后三位是000,说明被截取到秒,而真正的毫秒166被放到nanos中了 结论说明 错误的根源是混用了Date 和 Timestamp, 导致日期比对失效。 ORM从数据库中取出的时间类型是Date first(见文末图),而当前的时间戳获取方式错用了Timestamp second(见文末图), 只要修改为new Date() 就可以了。 如果无法避免混用,那就不要使用after() before()做日期对比! 直接用 getTime() 比较long的大小即可!有兴趣的同学可以看下Timestamp getTime()的源码, 它会把nanos拼装回数值中! 如何重现 两个long类型的数据,一个800毫秒,一个900毫秒,可以看出after(before类似, compareTo慎用)返回的结果是错误的。 public static void main(String[] args) throws IOException { Date d = new Date(1473247063800L); Date t = new Timestamp(1473247063900L); System.out.println(d.getTime()); System.out.println(t.getTime()); System.out.println(t.after(d)); //false, 错误结果 System.out.println(t.compareTo(d)); //1, 正确结果...Timestamp的compareTo方法被重载了所以这里没问题。 System.out.println(d.compareTo(t)); //1, 错误结果...Date的compareTo方法还是错误的。 System.out.println(t.getTime() >d.getTime()); //true, correct result
} The above is how to understand the error analysis of Java Date Timestamp date comparison shared by Xiaobian for everyone. If there is a similar doubt, please refer to the above analysis for understanding. If you want to know more about it, please pay attention to the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.