3

I have an Unix timestamp (with microsecond precision) value in 1.514408397505346E9. What is the correct way to convert it to readable date time format?

Is it correct to convert like below?

java.util.Date dateTime = new java.util.Date((long) Double.valueOf(unixTimestamp).longValue() * 1000);
DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
final String reportDate = df.format(dateTime);
djreenykev
  • 143
  • 2
  • 14
  • What type do you want to convert it to? Also unix timestamps are in full seconds – jontro Dec 28 '17 at 10:13
  • 2
    `ofEpochSecond` with the nanoAdjustment argument https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#ofEpochSecond-long-long- would be your best bet – jontro Dec 28 '17 at 10:17
  • I know this is a duplicate of another recently active question involving the `E` notation in the number, but I cannot find it. – Basil Bourque Jan 06 '18 at 23:52

2 Answers2

2

java.time

You are using troublesome old date-time classes that are now legacy, supplanted by the java.time classes of Java 8 and later. The Date class in incapable of representing the microseconds resolution of your input data.

I assume your number represents a number of whole seconds + fractional second since the epoch reference date of first moment of 1970 in UTC, 1970-01-01T00:00Z. We need to tear apart the count of whole seconds from the fractional second. We want the fractional second as a count of nanoseconds.

We use BigDecimal for accuracy, as double/Double uses floating-point technology to trade away accuracy for performance.

String input = "1.514408397505346E9";
BigDecimal bd = new BigDecimal( input );
BigDecimal microsDivisor = new BigDecimal( 1_000_000_000L );
long seconds = bd.longValue( );
BigDecimal bdMicros = bd.subtract( new BigDecimal( seconds ) ).multiply( microsDivisor );
long nanos = bdMicros.longValue( );

input: 1.514408397505346E9

bd: 1514408397.505346

seconds: 1514408397

nanos: 505346000

From that, instantiate an Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = Instant.ofEpochSecond( seconds , nanos ) ;

instant.toString(): 2017-12-27T20:59:57.505346Z

See this code run live at IdeOne.com.


ISO 8601

This use of 1.514408397505346E9 is a terrible way to represent date-time values. When serializing date-time values, use the standard ISO 8601 formats only. In this case: 2017-12-27T20:59:57.505346Z


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.

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
0

java.util.Date

Date currentTime = new Date(11111111111L);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = formatter.format(currentTime);

And be careful, SimpleDateFormat is not threadsafe,

Hash Jang
  • 599
  • 3
  • 11
  • `Date` doesnt support micro seconds. Not sure what class the OP wants to use – jontro Dec 28 '17 at 10:14
  • @jontro The example value is milliseconds so I assume a mixup of terms – Lothar Dec 28 '17 at 11:56
  • **Incorrect answer.** The input value apparently represents a date-time value in microseconds resolution. The troublesome old legacy date-time classes used here are limited to milliseconds. `1.514408397505346E9` = `1514408397.505346` = `2017-12-27T20:59:57.505346Z` – Basil Bourque Jan 07 '18 at 00:34