• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

JDBC returning extra ".0" in TimeStamp

 
Mike London
Ranch Hand
Posts: 1227
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am creating a List of items as a local cache so I don't have to keep checking the database -- to keep from adding duplicate rows during subsequent imports which may contain some of the previous log data.

Now, when I look at the Timestamp field in the database it says (as one example):

2014-09-30 21:16:42

I can do a SQL command in the data viewer and it shows the exact same format.

Fine.

Yet, when I get that value from the database via the JDBC driver and MySQL, I see this:

2014-09-30 21:16:42.0

So,

2014-09-30 21:16:42 != 2014-09-30 21:16:42.0

and my equality check will fail and the duplicate record gets added to the DB.

-------------

I "fixed" the problem by just changing ".equals()" to ".contains()", but I'm wondering what the deal is with that extra ".0" at the end and how it got there in the first place.

Is this a JDBC driver "issue" of some kind?

Thanks in advance,

- mike

 
Dave Tolls
Ranch Hand
Posts: 2112
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How are you reading this out?
The Timestamp class is simply a long.
 
K. Tsang
Bartender
Posts: 3585
16
Android Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The ".0" is the nanosecond in the timestamp.

java.sql.Timestamp has its own equals() method. In fact 2 equals() = equals(Object) and equals(Timestamp)

If you retrieved the timestamp using ResultSet#getTimestamp then use the equals(Timestamp) .... it should work.

Oh when you print the timestamp to console, the Timestamp class is using its toString() method which by default has that nanosecond thing. To avoid it, use the the Timestamp.valueOf(String) static method.

Hope this helps.
 
Mike London
Ranch Hand
Posts: 1227
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
K. Tsang wrote:The ".0" is the nanosecond in the timestamp.

java.sql.Timestamp has its own equals() method. In fact 2 equals() = equals(Object) and equals(Timestamp)

If you retrieved the timestamp using ResultSet#getTimestamp then use the equals(Timestamp) .... it should work.

Oh when you print the timestamp to console, the Timestamp class is using its toString() method which by default has that nanosecond thing. To avoid it, use the the Timestamp.valueOf(String) static method.

Hope this helps.


Thanks very much. It's only confusing since the display doesn't show it but the ResultSet does.

I appreciate your reply.

Thank you!

- mike
 
Mike London
Ranch Hand
Posts: 1227
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:How are you reading this out?
The Timestamp class is simply a long.


via a rs.getTimestamp(<field_name>)

In the database itself, using a query, there is no ".0", but in the result set, there is.

The Bartender told me how to fix it, but I'm fine with using .contains() instead of .equals() since it works fine and would not cause a logical error.

Thanks for your reply.

- mike
 
Dave Tolls
Ranch Hand
Posts: 2112
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What you are seeing is all about how the (in this case default) display routines work for the two systems.

The value you see via your database query (using whatever SQL IDE you use) is a formatted representation of the value actually stored in the database, it isn't the actual value (here's a precis of what Oracle does around storing Dates). The same applies to the Timestamp returned by getTimestamp. The actual value in that case would be 1412108202000 for your example (actually there's a bit more to it, but in essence it's a long).

So it's a case of mistaking what is displayed as being what the value actually is...and you're not the first person to do that.
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65342
97
IntelliJ IDE Java jQuery Mac Mac OS X
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike London wrote:but I'm fine with using .contains() instead of .equals() since it works fine and would not cause a logical error.

I would not be. Not by a long shot. It's a hack of a major nature. I'd strongly advise doing this the right way rather than relying on a hack that just happens to work.
 
Dave Tolls
Ranch Hand
Posts: 2112
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bear Bibeault wrote:
Mike London wrote:but I'm fine with using .contains() instead of .equals() since it works fine and would not cause a logical error.

I would not be. Not by a long shot. It's a hack of a major nature. I'd strongly advise doing this the right way rather than relying on a hack that just happens to work.


Oh yes, and this...
 
Mike London
Ranch Hand
Posts: 1227
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
K. Tsang wrote:The ".0" is the nanosecond in the timestamp.

java.sql.Timestamp has its own equals() method. In fact 2 equals() = equals(Object) and equals(Timestamp)

If you retrieved the timestamp using ResultSet#getTimestamp then use the equals(Timestamp) .... it should work.

Oh when you print the timestamp to console, the Timestamp class is using its toString() method which by default has that nanosecond thing. To avoid it, use the the Timestamp.valueOf(String) static method.

Hope this helps.


Hello,

So, do you mean something like this:

Timestamp.valueOf(rs.getTimestamp("ts").toString())

???

If so, in the code, this still produces this:

2014-09-30 21:16:42.0

I probably misunderstood what you were getting at.

Thanks,

-- mike
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65342
97
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No. Why are you converting to strings in the first place? Times in Java are long values, not strings.

Why are you resistant to using the API provided for java.sql.Timestamp, and just putting a lot of other stuff in the way?
 
Mike London
Ranch Hand
Posts: 1227
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bear Bibeault wrote:No. Why are you converting to strings in the first place? Times in Java are long values, not strings.

Why are you resistant to using the API provided for java.sql.Timestamp, and just putting a lot of other stuff in the way?


If you read the Bartender's post above, I was doing what I understood the Bartender had suggested. My reply was to the Bartender.

I'm open to constructive advice if you would care to share a suggestion (for example, something to try, a code snippet, perhaps).

To your other point previously, this is not production code, just some code for log file analysis.

Thanks Bear. I do appreciate your replies.

- mike
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65342
97
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But you still haven't answered the question: why not simply use the equals() method as intended?
 
Mike London
Ranch Hand
Posts: 1227
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bear Bibeault wrote:But you still haven't answered the question: why not simply use the equals() method as intended?


I was using the equals method all along. Not sure how that got lost. I guess I just didn't post that part of the code.

Although I wasn't able to suppress the ".0" in the nano-seconds in the Timestamp field from the database, I converted the first Timestamp I was reading separately from the log file (for comparison to the database Timestamp) to a Timestamp object (instead of assigning the file's "Timestamp" text to a string during the import).

Then, it too had the ".0" at the end and the comparisons, using .equals(), not "contains()", worked fine. This logic prevents dups on successive re-imports of a log file which could have (probably will have) some of the data at the top previously imported.

Phew!

Thanks for hanging in there and pushing this. I appreciate it!

- mike
 
Dave Tolls
Ranch Hand
Posts: 2112
16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike London wrote:
Then, it too had the ".0" at the end and the comparisons, using .equals(), not "contains()", worked fine.
- mike


This bit still sounds like you are comparing Strings.

What Bear is asking is why aren't you simply comparing the Timestamps?


With that structure there is no "it too had the ".0"" as that would be meaningless.
 
Mike London
Ranch Hand
Posts: 1227
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:
Mike London wrote:
Then, it too had the ".0" at the end and the comparisons, using .equals(), not "contains()", worked fine.
- mike


This bit still sounds like you are comparing Strings.

What Bear is asking is why aren't you simply comparing the Timestamps?


With that structure there is no "it too had the ".0"" as that would be meaningless.


Yeah, I made that change too. It's all about comparing "Values" so either code works fine.

I had to change the Bean I was using to store each database value pair (my cache stores an ArrayList of these beans I search during each row read from the log file to make sure there are no dups added) to store a timestamp instead of a String and then remove the .toString() in the actual comparison logic.

Appreciate your follow up.

- mike
 
K. Tsang
Bartender
Posts: 3585
16
Android Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Mike,

You probably found out that valueOf(String) approach didn't work. Because the String input has an extra ".0" to begin with.

Just thinking you can also use the Timestamp#getTime() method to get the long for comparison.
 
Mike London
Ranch Hand
Posts: 1227
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
K. Tsang wrote:Hi Mike,

You probably found out that valueOf(String) approach didn't work. Because the String input has an extra ".0" to begin with.

Just thinking you can also use the Timestamp#getTime() method to get the long for comparison.


Actually, my real problem was that I was reading in the log file "timestamp" as a string (instead of a timestamp) which of course didn't have the ".0".

As Dave Tolls suggested, I just made sure everything was a timestamp and compared them.

The former string comparison worked too once I had a timestamp on both sides.

Thanks for your reply,

-mike
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic