{"id":7,"date":"2003-08-14T16:42:13","date_gmt":"2003-08-14T06:42:13","guid":{"rendered":"http:\/\/www.thunderguy.com\/plusplus\/20050414\/javasqldate-is-not-a-real-date"},"modified":"2009-04-26T14:47:57","modified_gmt":"2009-04-26T01:47:57","slug":"java-sql-date-is-not-a-real-date","status":"publish","type":"post","link":"https:\/\/thunderguy.com\/semicolon\/2003\/08\/14\/java-sql-date-is-not-a-real-date\/","title":{"rendered":"<code>java.sql.Date<\/code> is not a real date"},"content":{"rendered":"<p><code>java.sql.Date<\/code> stores only date information, not times. Simply converting a <code>java.util.Date<\/code> into a <code>java.sql.Date<\/code> will silently set the time to midnight. So, to store date\/times to be manipulated as <code>java.util.Date<\/code> objects, don&#8217;t do this:<\/p>\n<pre class=\"code\">\r\n<code class=\"bad-code\">\/\/ BUG: loses time of day\r\npreparedStatement.setDate(1, new java.sql.Date(date.getTime()));<\/code>\r\n<\/pre>\n<p>do this instead:<\/p>\n<pre class=\"code\">\r\n<code>preparedStatement.setTimestamp(1, new java.sql.Timestamp(date.getTime()));<\/code>\r\n<\/pre>\n<p><code>java.sql.Timestamp<\/code> extends <code>java.util.Date<\/code>, but it should not be used as a <code>Date<\/code>. In JDK 1.3.1, <code>Timestamp.getTime()<\/code> (inherited from <code>Date<\/code>) returns the time to the nearest second only, but JDK 1.4.2 and JDK 1.5 it returns the time to the nearest millisecond as expected. <!--more-->So in JDK 1.3, when reading a timestamp from a <code>ResultSet<\/code>, don&#8217;t do this:<\/p>\n<pre class=\"code\">\r\n<code class=\"bad-code\">\/\/ Java 1.3\r\njava.util.Date d = resultSet.getTimestamp(1);\r\nlong millis = d.getTime(); \/\/ BUG: loses fractional seconds in JDK 1.3<\/code>\r\n<\/pre>\n<p>To get the full date including milliseconds, you have to do this:<\/p>\n<pre class=\"code\">\r\n<code>java.sql.Timestamp timestamp = resultSet.getTimestamp(1);\r\njava.util.Date d = new java.util.Date(timestamp.getTime() +\r\n                                      timestamp.getNanos() \/ 1000000);<\/code>\r\n<\/pre>\n<p>In JDK 1.4.2 and JDK 1.5, you can just do this, depending on what you&#8217;re going to do with the Date:<\/p>\n<pre class=\"code\">\r\n<code>\/\/ Java 1.4+\r\njava.util.Date d = resultSet.getTimestamp(1);<\/code>\r\n<\/pre>\n<p>But this might be safer since it avoids any other potential <code>Timestamp<\/code> problems:<\/p>\n<pre class=\"code\">\r\n<code>\/\/ Java 1.4+\r\njava.util.Date d = new java.util.Date(resultSet.getTimestamp(1).getTime());<\/code>\r\n<\/pre>\n<p>If your code needs to run on JDK 1.3 and later, you&#8217;ll have to do this:<\/p>\n<pre class=\"code\">\r\n<code>java.sql.Timestamp timestamp = resultSet.getTimestamp(1);\r\nlong millis = (timestamp.getTime() \/ 1000) * 1000 + timestamp.getNanos() \/ 1000000;\r\njava.util.Date d = new java.util.Date(millis);<\/code>\r\n<\/pre>\n<p>For more information, see the Javadoc for <code>java.sql.Timestamp<\/code>.<br \/>\n<a href=\"http:\/\/java.sun.com\/j2se\/1.3\/docs\/api\/java\/sql\/Timestamp.html\"  >JDK 1.3.1 TimeStamp Javadoc<\/a><br \/>\n<a href=\"http:\/\/java.sun.com\/j2se\/1.4.2\/docs\/api\/java\/sql\/Timestamp.html\">JDK 1.4.2 TimeStamp Javadoc<\/a><br \/>\n<a href=\"http:\/\/java.sun.com\/j2se\/1.5.0\/docs\/api\/java\/sql\/Timestamp.html\">JDK 1.5.0 TimeStamp Javadoc<\/a><\/p>\n<p>Note the subtle difference between 1.3.1 and the later ones: The following lines appear in the 1.3.1 Javadoc, but were removed in subsequent version.<\/p>\n<blockquote><p>\nThe <code>getTime<\/code> method will return only integral seconds. If a time value that includes the fractional seconds is desired, you must convert nanos to milliseconds (nanos\/1000000) and add this to the <code>getTime<\/code> value.\n<\/p><\/blockquote>\n<p>See also the amusing notes on <a href=\"http:\/\/bugs.sun.com\/bugdatabase\/view_bug.do?bug_id=4679060\">Bug 4679060<\/a> on <a href=\"http:\/\/developers.sun.com\/\">developers.sun.com<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>java.sql.Date stores only date information, not times. Simply converting a java.util.Date into a java.sql.Date will silently set the time to midnight. So, to store date\/times to be manipulated as java.util.Date objects, don&#8217;t do this: \/\/ BUG: loses time of day preparedStatement.setDate(1, new java.sql.Date(date.getTime())); do this instead: preparedStatement.setTimestamp(1, new java.sql.Timestamp(date.getTime())); java.sql.Timestamp extends java.util.Date, but it should [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[4],"class_list":["post-7","post","type-post","status-publish","format-standard","hentry","tag-java"],"_links":{"self":[{"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/posts\/7","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/comments?post=7"}],"version-history":[{"count":1,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/posts\/7\/revisions"}],"predecessor-version":[{"id":149,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/posts\/7\/revisions\/149"}],"wp:attachment":[{"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/media?parent=7"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/categories?post=7"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/tags?post=7"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}