1

I have many long numbers which look like 1568694302232954486 and 1568703521360049938, and I need to convert each of them into a Java Date object.

How to implement the above requirement in Java 8? I also need transform the nanosecond value into elasticsearch's timestamp and have found the correct way; thanks for all the help!

Just for those who need it, the following code block has passed the test. It's actually part of a logstash configuration file:

ruby {
            init => ""
            code => "
            event.set('time_local',event.get('time_local').to_f*0.000001)
            "
        }

        date {
                #15/Aug/2019:14:46:19 +0800 [02/Sep/2019:09:28:33 +0800]
            match => [ "time_local" , "yyyy-MM-dd HH:mm:ss,SSS","UNIX_MS"]
            timezone => "Asia/Shanghai"
            target => "@timestamp"
        }
fengnix
  • 85
  • 6

2 Answers2

1

If you want it as a Date object, then you are going to lose some information, because Date only has millisecond precision. Date is also obsolete in Java 8, so if you are using Java 8 or above, consider using Instant instead.

Here is how to convert to Date. Don't do this unless you really have to.

long nano = 1568694302232954486L;
Date d = new Date(nano / 1000000); // 1000000 is how many nanoseconds there are in a millisecond

Instant on the other hand has nanosecond precision, and is what you should be doing:

// 1000000000 is how many nanoseconds there are in a second.
Instant i = Instant.ofEpochSecond(nano / 1000000000, nano % 1000000000);
Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

java.time

It’s very easy when you know how. While the second parameter of the two-arg Instant.ofEpochSecond() is named nanoAdjustment, it has type long, and the method accepts the full nano value being passed in this parameter. So just pass 0 as the seconds and leave the conversion to the method:

    Instant instant1 = Instant.ofEpochSecond(0, 1_568_694_302_232_954_486L);
    System.out.println(instant1);
    Instant instant2 = Instant.ofEpochSecond(0, 1_568_703_521_360_049_938L);
    System.out.println(instant2);

Output is:

2019-09-17T04:25:02.232954486Z
2019-09-17T06:58:41.360049938Z

If you do need an old-fashioned Date object for a legacy API that you cannot change or don’t want to upgrade just now:

    Date oldfashionedDate1 = Date.from(instant1);
    System.out.println(oldfashionedDate1);

On my computer the converted Date was printed as:

Tue Sep 17 06:25:02 CEST 2019

Generally do avoid the Date class, though. It is poorly designed and long outdated. Working with java.time, the modern Java date and time API, is so much nicer.

Link: Oracle tutorial: Date Time explaining how to use java.time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161