52

i.e. this code

startDate = new Date(timestampValue.getTime));

gives me :

2012-16-02 05:16:17

when

System.out.println(timestampValue);

return :

2012-01-02 05:16:17.0

Marcin Petrów
  • 1,447
  • 5
  • 24
  • 39
  • What do you want with them? Do you want them to have the save String representation or do you want to convert the objects to be used programmatically? – Poindexter May 16 '12 at 15:12
  • the question in in a topic :) How to convert from java.sql.Timestamp to java.util.Date?... what I want to do? just convert from Timestamp to Date and have that same values... I know... Date have no nanoseconds... dosent matter... – Marcin Petrów May 16 '12 at 15:16
  • 5
    No need to convert. A Timestamp *is* a Date. – Hot Licks May 16 '12 at 15:23
  • If it soo simple and Timestamp is a Date tell my why there is difference...? in example.... with after and before conversion? – Marcin Petrów May 16 '12 at 18:28
  • possible duplicate of [How to convert TimeStamp to Date in Java?](http://stackoverflow.com/questions/11839246/how-to-convert-timestamp-to-date-in-java) – Rick Mar 18 '15 at 08:38
  • @Rick That other Question is not the original, it came *after* this one. – Basil Bourque Jun 18 '15 at 21:54
  • 10
    @HotLicks Your comment is *incorrect* and ill-advised. While technically correct, a java.sql.Timestamp does inherit from java.util.Date, that inheritance is a hack. [The doc](http://docs.oracle.com/javase/8/docs/api/java/sql/Timestamp.html) explicitly says you should *not* consider j.sql.Timestamp as a sub-class of j.u.Date. See comment by Alex Shesterov on [this Answer](http://stackoverflow.com/a/18080498/642706). – Basil Bourque Jun 18 '15 at 22:16

8 Answers8

54

Class java.sql.TimeStamp extends from java.util.Date.

You can directly assign a TimeStamp object to Date reference:

TimeStamp timeStamp = //whatever value you have;
Date startDate = timestampValue;
toro2k
  • 19,020
  • 7
  • 64
  • 71
Arpit Jain
  • 782
  • 1
  • 6
  • 12
  • 39
    @jelies: **no, it shouldn't**. According to [Java docs](http://docs.oracle.com/javase/7/docs/api/java/sql/Timestamp.html): `Due to the differences between the Timestamp class and the java.util.Date class ... it is recommended that code not view Timestamp values generically as an instance of java.util.Date. The inheritance relationship between Timestamp and java.util.Date really denotes implementation inheritance, and not type inheritance.` – Alex Shesterov Feb 18 '14 at 13:52
  • 8
    woah, you're right... this inheritance is very misleading :/ correct answer is [here](http://stackoverflow.com/a/11839276/787375). – jelies Feb 18 '14 at 16:04
  • This answer should not be up-voted - it is not correct. Manipulating a mixture of Timestamp and Date instances will lead to hard to find bugs once you start comparing them etc. – Pawel Zieminski Nov 22 '19 at 23:48
19

You should use a Calendar instead:

Calendar start = Calendar.getInstance();
start.setTimeInMillis( timeStampValue.getTime() );
henriqueor
  • 849
  • 1
  • 17
  • 38
Jamie
  • 3,890
  • 3
  • 26
  • 35
  • yeah its close enaught to work, but now I have a problem with priefaces calendar component.... it support only java.util.Date :D – Marcin Petrów May 16 '12 at 15:28
13

tl;dr

Instant instant = myResultSet.getObject( … , Instant.class ) ;

…or, if your JDBC driver does not support the optional Instant, it is required to support OffsetDateTime:

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

Avoid both java.util.Date & java.sql.Timestamp. They have been replaced by the java.time classes. Specifically, the Instant class representing a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Different Values → Unverified Problem

To address the main part of the Question: "Why different dates between java.util.Date and java.sql.Timestamp objects when one is derived from the other?"

There must be a problem with your code. You did not post your code, so we cannot pinpoint the problem.

First, that string value you show for value of java.util.Date did not come from its default toString method, so you obviously were doing additional operations.

Secondly, when I run similar code I do indeed get exact same date-time values.

First create a java.sql.Timestamp object.

// Timestamp
long millis1 =  new java.util.Date().getTime();
java.sql.Timestamp ts = new java.sql.Timestamp(millis1);

Now extract the count-of-milliseconds-since-epoch to instantiate a java.util.Date object.

// Date
long millis2 = ts.getTime();
java.util.Date date = new java.util.Date( millis2 );

Dump values to console.

System.out.println("millis1 = " + millis1 );
System.out.println("ts = " + ts );
System.out.println("millis2 = " + millis2 );
System.out.println("date = " + date );

When run.

millis1 = 1434666385642
ts = 2015-06-18 15:26:25.642
millis2 = 1434666385642
date = Thu Jun 18 15:26:25 PDT 2015

So the code shown in the Question is indeed a valid way to convert from java.sql.Timestamp to java.util.Date, though you will lose any nanoseconds data.

java.util.Date someDate = new Date( someJUTimestamp.getTime() ); 

Different Formats Of String Output

Note that the output of the toString methods is a different format, as documented. The java.sql.Timestamp follows SQL format, similar to ISO 8601 format but without the T in middle.

Ignore Inheritance

As discussed on comments on other Answers and the Question, you should ignore the fact that java.sql.Timestamp inherits from java.util.Date. The j.s.Timestamp doc clearly states that you should not view one as a sub-type of the other: (emphasis mine)

Due to the differences between the Timestamp class and the java.util.Date class mentioned above, it is recommended that code not view Timestamp values generically as an instance of java.util.Date. The inheritance relationship between Timestamp and java.util.Date really denotes implementation inheritance, and not type inheritance.

If you ignore the Java team’s advice and take such a view, one critical problem is that you will lose data: any microsecond or nanosecond part of a second that may be coming from the database is lost as a Date has only millisecond resolution.

Basically, all the old date-time classes from early Java are a big mess: java.util.Date, j.u.Calendar, java.text.SimpleDateFormat, java.sql.Timestamp/.Date/.Time. They were one of the first valiant efforts at a date-time framework in the industry, but ultimately they fail. Specifically here, java.sql.Timestamp is a java.util.Date with nanoseconds tacked on; this is a hack, not good design.

java.time

Avoid the old date-time classes bundled with early versions of Java.

Instead use the java.time package (Tutorial) built into Java 8 and later whenever possible.

Basics of java.time… An Instant is a moment on the timeline in UTC. Apply a time zone (ZoneId) to get a ZonedDateTime.

Example code using java.time as of Java 8. With a JDBC driver supporting JDBC 4.2 and later, you can directly exchange java.time classes with your database; no need for the legacy classes.

Instant instant = myResultSet.getObject( … , Instant.class) ;  // Instant is the raw underlying data, an instantaneous point on the time-line stored as a count of nanoseconds since epoch.

You may want to adjust into a time zone other than UTC.

ZoneId z = ZoneId.of( "America/Montreal" );  // Always make time zone explicit rather than relying implicitly on the JVM’s current default time zone being applied.
ZonedDateTime zdt = instant.atZone( z ) ;

Perform your business logic. Here we simply add a day.

ZonedDateTime zdtNextDay = zdt.plusDays( 1 ); // Add a day to get "day after".

At the last stage, if absolutely needed, convert to a java.util.Date for interoperability.

java.util.Date dateNextDay = Date.from( zdtNextDay.toInstant( ) );  // WARNING: Losing data (the nanoseconds resolution).

Dump to console.

System.out.println( "instant = " + instant );
System.out.println( "zdt = " + zdt );
System.out.println( "zdtNextDay = " + zdtNextDay );
System.out.println( "dateNextDay = " + dateNextDay );

When run.

instant = 2015-06-18T16:44:13.123456789Z
zdt = 2015-06-18T19:44:13.123456789-04:00[America/Montreal]
zdtNextDay = 2015-06-19T19:44:13.123456789-04:00[America/Montreal]
dateNextDay = Fri Jun 19 16:44:13 PDT 2015

Conversions

If you must use the legacy types to interface with old code not yet updated for java.time, you may convert. Use new methods added to the old java.util.Date and java.sql.* classes for conversion.

Instant instant = myJavaSqlTimestamp.toInstant() ;

…and…

java.sql.Timestamp ts = java.sql.Timestamp.from( instant ) ;

See the Tutorial chapter, Legacy Date-Time Code, for more info on conversions.

Fractional Second

Be aware of the resolution of the fractional second. Conversions from nanoseconds to milliseconds means potentially losing some data.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • *this* should be the accepted answer. If one could still award points to an exceptionally good answer, I'd do that with this answer. – foo Feb 02 '19 at 20:15
6

The problem is probably coming from the fact that Date is deprecated.

Consider using

java.util.Calendar

or

Joda-Time

Edit 2015:

Java 8 and later has built-in the new java.time package, which is similar to Joda-Time.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Pierre-Antoine
  • 7,939
  • 6
  • 28
  • 36
  • Hmmm.... I just following priefaces.... and in primefaces calendar they still use java.util.Date .... I will check it with Calendar:) – Marcin Petrów May 16 '12 at 15:19
  • The java.util.Date class is *not* entirely deprecated, just many of its methods are deprecated. However, as this Answer correctly suggests, the java.util.Date class *is* outmoded by Joda-Time & java.time, and should be avoided whenever possible. – Basil Bourque Jun 18 '15 at 22:06
  • 1
    @MarcinPetrów Whenever possible, do all your business logic using java.time (or Joda-Time if before Java 8, or Joda-Time has a feature lacking in java.time like [`Interval`](http://www.joda.org/joda-time/apidocs/org/joda/time/Interval.html)). At the last moment, convert to java.util.Date where necessary for interoperability by calling [`DateTime::toDate`](http://www.joda.org/joda-time/apidocs/org/joda/time/base/AbstractInstant.html#toDate--) method in Joda-Time, or for java.time see Tutorial chapter on [Legacy Date-Time Code](http://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html). – Basil Bourque Jun 18 '15 at 22:13
  • Ditto for many other 3rd party packages such as Apache POI which only has support for java.util.Date and java.util.Calendar. As @BasilBourque stated, use the newest classes in your main programming logic, and then convert at the api to the 3rd party package. Makes maintenance easier for the future upgrade as well, when that does occur. – Nelda.techspiress Aug 17 '17 at 14:51
4

The fancy new Java 8 way is Date.from(timestamp.toInstant()). See my similar answer elsewhere.

Community
  • 1
  • 1
Garret Wilson
  • 18,219
  • 30
  • 144
  • 272
3
public static Date convertTimestampToDate(Timestamp timestamp)  {
        Instant ins=timestamp.toLocalDateTime().atZone(ZoneId.systemDefault()).toInstant();
        return  Date.from(ins);
}
Laurel
  • 5,965
  • 14
  • 31
  • 57
jaimeRambo
  • 79
  • 1
  • 1
  • 5
  • 2
    Usually we expect to see some division or explanation on Answers. Stack Overflow was meant to be more than a snippet library. Can you expound a bit? – Basil Bourque Apr 20 '16 at 16:36
  • You should add some explanation to your code. Code-only answers are frowned upon. Why does your code work, and how does it answer the question? include that in your answer. – Polygnome Apr 20 '16 at 17:21
1
java.sql.ResultSet rs;
//fill rs somehow
java.sql.Timestamp timestamp = rs.getTimestamp(1); //get first column
long milliseconds = timestamp.getTime() + (timestamp.getNanos() / 1000000);
java.util.Date date = return new java.util.Date(milliseconds);
andrej
  • 4,518
  • 2
  • 39
  • 39
1

Timestamp is a Date: https://docs.oracle.com/javase/7/docs/api/java/sql/Timestamp.html

java.lang.Object
    java.util.Date
        java.sql.Timestamp
Pablo Pazos
  • 3,080
  • 29
  • 42
  • 5
    Not a good answer. This inheritance relationship between Date and Timestamp is a hack, a **bad class design**. The [documentation](https://docs.oracle.com/javase/8/docs/api/java/sql/Timestamp.html) explicitly warns you to **“not view Timestamp values generically as an instance of java.util.Date”**. See [my Answer](http://stackoverflow.com/a/30927608/642706) for more info. – Basil Bourque Jan 18 '16 at 23:58