Java Convert long value to date with exact precision of nano seconds - java

The date in database is 2012-03-20 12:24:34.123456. We need to display it in long format.so, we used getTime() method. But when we are converting back to date again, the nano seconds are not matching exact precision. The date after conversion is 2012-03-20 12:24:34.123. last 456 is missing. any one help to get exact date with nano seconds.

From javadoc
java.util.Date, getTime(), returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object. 456 is missing because is less than millisecond, is microseconds

You can use getTimestamp() instead of getTime(). The java.sql.Timestamp object returned, when treated like a java.util.Date, has integer seconds. By calling getNanos() on it, you can get the fractional seconds in nanoseconds.

Related

Cannot convert from java Double to java Date

I am having an issue with converting a double to a Java date object in the format: yyyy-MM-dd HH:mm:ss
I have tried to convert this double value to a long value then instanciate a Date object with the result, but I got errors saying that I cannot convert from double to long.
my timestamp double values are in this format:
1.511554592277516E9
Can anybody help me with this issue please, thanks in advance.
Assuming that this floating point value is seconds past the Unix Epoch of 1 Jan 1970 0:00 GMT, this will provide a conversion to a LocalDateTime with that offset:
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(
Double.valueOf(1.511554592277516E9).longValue(), 0, ZoneOffset.UTC);
System.out.println(localDateTime);
I leave converting this to a Date as an exercise for the reader.
Your floating-point value, 1.511554592277516E9, no doubt denotes seconds since the epoch of January 1, 1970 at midnight UTC, with microsecond precision: 1 511 554 592 seconds and 277 516 microseconds (millionths of a second).
I suggest using java.time, the modern Java date and time API also known as JSR-310, for this. It is much nicer to work with than the outdated Date class and friends, and also offers nanosecond precision (Date only has millisecond precision, so you would lose precision if converting into one). More specifically I will first create a java.time.Instant object (conversion to other date-time types will be easy, I’ll touch on one example at the end).
Getting the full precision through into an Instant requires a little thought. I played a little with double and long, but realized (1) double doesn’t have the full precision required, the nanoseconds will not be right (2) converting to a long holding the nanoseconds (not the only way, but certainly the easiest) will create a “year 2262 problem”, so if you are handling dates in a far future, it will not work. In any case, I think that the easy and safe solution is to use BigDecimal for the math required before feeding the numbers into an Instant.
String secondsSinceEpoch = "1.511554592277516E9";
BigDecimal decimalSeconds = new BigDecimal(secondsSinceEpoch);
long seconds = decimalSeconds.longValue();
long nanos = decimalSeconds.subtract(BigDecimal.valueOf(seconds))
.movePointRight(9)
.longValueExact();
Instant inst = Instant.ofEpochSecond(seconds, nanos);
System.out.println(inst);
This prints:
2017-11-24T20:16:32.277516Z
The printed date-time is in UTC. If the value is as expected, I should say it confirms that your floating-point value was indeed seconds since the epoch.
You requested a date-time in the format yyyy-MM-dd HH:mm:ss. You will need to decide in which time zone you want the date-time. Date objects don’t have a format, so you will also need to get the format in a string. For example:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(inst.atZone(ZoneId.of("America/Vancouver")).format(formatter));
This prints
2017-11-24 12:16:32
You substitute your desired time zone, of course. atZone() converts the Instant into a ZonedDateTime, another often used class of java.time.
EDIT: In case you don’t want to bother with BigDecimal, you accept a slight inaccuracy and/or your receive your value as a double rather than a string, here’s an alternative in fewer lines of code:
double secondsSinceEpoch = 1.511554592277516E9;
long longSeconds = (long) secondsSinceEpoch;
long micros = Math.round((secondsSinceEpoch - longSeconds) * 1_000_000);
Instant inst = Instant.ofEpochSecond(longSeconds).plus(micros , ChronoUnit.MICROS);
In this particular case it gives exactly the same result, down to the nanosecond. I’m not sure whether with other inputs, the microseconds may end up inaccurate, but on the other hand, if you receive a double (not a string), there’s nothing you could do about that anyway.

Converting datetime in millisec with timezone info

I have one simple question. How to achieve this format of date 1438117140000+0300. First part 1438117140000 its the time in millisec , that i convert with no problem, second part with timezone info is my headache , how to get it ??
You can use String.format for this purpose:
Date now = new Date();
System.out.println(String.format("%tQ%tz", now, now));
Executing the code just printed out this:
1438635740416+0300
The conversions for date/time are specified in the documentation. Here, I've used the following two conversion characters:
'Q': Milliseconds since the beginning of the epoch starting at 1
January 1970 00:00:00 UTC, i.e. Long.MIN_VALUE to Long.MAX_VALUE.
'z': RFC 822 style numeric time zone offset from GMT, e.g. -0800. This
value will be adjusted as necessary for Daylight Saving Time. For
long, Long, and Date the time zone used is the default time zone for
this instance of the Java virtual machine.
It looks like +0300 means +3 hours from GMT. so convert 0300 (3 hours) to milliseconds and add to 1438117140000. then convert to a date time as you are already
Split the value you have to '+' then add 3 hours as miliseconds to the first value of the array that split method returned.

Possible underflow error through the usage of java.util.Date

This code:
package test;
import java.util.Date;
public class DateUnderflow {
public static void main(String[] args) {
Long timestamp = -8120649749785140250L;
System.out.println(new Date(timestamp));
}
}
Produces the following output:
"Sat Aug 03 10:00:59 CET 257325894"
How come? An underflow without an exception?
Doc says says the date parameter of Date(long date) is the number of milliseconds since epoch, so I'm a bit surprised to find myself that far into the future..
My setup:
Linux mint 17.1
Eclipse Luna Service Release 1a (4.4.1)
java7-openjdk-amd64
RTFM (manual)
public Date(long date)
Constructs a Date object using the given
milliseconds time value. If the given milliseconds value contains time
information, the driver will set the time components to the time in
the default time zone (the time zone of the Java virtual machine
running the application) that corresponds to zero GMT.
Parameters:
date - milliseconds since January 1, 1970, 00:00:00 GMT not to exceed
the milliseconds representation for the year 8099. A negative number
indicates the number of milliseconds before January 1, 1970, 00:00:00
GMT.
not to exceed the milliseconds representation for the year 8099
In addition to this I am most likely saving someones time by saying: if you deal with time in java use joda time library:
http://www.joda.org/joda-time/
Max long value is 9223372036854775807. If you exceeds this max value, next value would be minimum max value.
If you construct a date out of this max long value, this will results to a date. What about a date next to that. If you add more mili-second to the next starts from minimum long value.
-8120649749785140250 is equivalent to 9223372036854775807 + 1102722287069635559
Try System.out.println(9223372036854775807L+1102722287069635559L);
I believe your code is equivalent to
Date d1 = new Date(9223372036854775807L); // Date for max long value
Date d2 = new Date(d1.getTime() + 1102722287069635559L); // plus some mili-seconds
System.out.println(d2);
This gives the result you are getting.

Algorithm of Java Date getTime

How does java.util.Date.getTime method convert a given date & time into long number?
Java API documents say that - "Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object."
Appreciate any help.
Check out the Date.java source code.
You'll see that in the simplest case, the Date object stores the number of milliseconds since 1970, rather than the date/time etc.
Actually, despite the apparently unambiguous definition in the Java API doc, it is interesting to note that the number of milliseconds reported is not the actual number of physical milliseconds, or seconds for that matter, that have elapsed since January 1st 1970 00:00:00 GMT. It is really the number of physical seconds plus the number of leap seconds that have been artificially inserted.

How to retrieve milliseconds from java.sql.Timestamp

I have a timestamp object and need to get the milliseconds from it, can someone help me with an example code snippet ?
You can use Timestamp.getTime()
Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
represented by this Timestamp object.
Example:
long timeInMilliSeconds = t.getTime();
// do magic trick here
Note: Timestamp is extend from Date.
You can just call getTime() to get milliseconds since the Unix epoch. Is that what you were after, or did you want "milliseconds within the second" or something similar?
Note that using just milliseconds is slightly odd for a Timestamp, given that it's designed specifically to be precise to the nanosecond. So you should usually be using getTime() in conjunction with getNanos().
From the Java Docu (link):
public long getTime()
Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Timestamp object.
I guess this will give the output you want.
public void timeInMills(Timestamp t){
System.out.println("Time in Milli second "+t.getTime());
}

Categories