I'm trying to convert date time string like 25-05-2022 05:40:51 to nanoseconds (1653457251000000000) since epoch in Java
CodePudding user response:
// Use any online Java Compiler like Programiz to test this
import java.util.Date;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
class HelloWorld {
public static void main(String[] args) throws Exception{
String sDate6 = "25-05-2022 05:40:51";
SimpleDateFormat formatter6=new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Date date6=formatter6.parse(sDate6);
System.out.println("Hello" date6 );
Instant instant = date6.toInstant();
System.out.println("\n seconds: " instant.getEpochSecond());
System.out.println("\n remaining ns: " instant.getNano());
System.out.println("\n ns since epoch: " (TimeUnit.SECONDS.toNanos(instant.getEpochSecond()) instant.getNano()));
}
}
CodePudding user response:
I think you will have to calculate the nanos (as already mentioned in an answer to a similar question), there seems to be no possibility of directly deriving that value from an Instant
or any equivalent class in java.time
. You will have to explicitly provide a time zone (java.time.ZoneId
) if you want a reliable solution that does not depend on the configuration of the JVM the code is executed on.
Steps you can perform:
- define a formatter and use it to parse the
String
, which should result in aLocalDateTime
because your input does not contain a time zone or offset - provide the time zone and use it together with the
LocalDateTime
producing aZonedDateTime
- get the
Instant
defined by theZonedDateTime
and use its epoch millis value in order to calculate the nanos
Here's a demo that shows you how a time zone matters in your case:
Different ones are likely to produce different values, so better explicitly define one in your code (long version for readability).
public static void main(String[] args) {
// define the expected nano value
long expectedNanos = 1653457251000000000L;
// your example input (no time zone or offset given!)
String input = "25-05-2022 05:40:51";
// create a formatter to be used as parser for the input
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm:ss");
// parse it to have a LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(input, dtf);
// create two zones in order to find out how the zones matter here
ZoneId utc = ZoneId.of("UTC");
ZoneId kolkata = ZoneId.of("Asia/Kolkata");
// apply each zone to the LocalDateTime and create two ZonedDateTimes
ZonedDateTime timeInUtc = localDateTime.atZone(utc);
ZonedDateTime timeInKolkata = localDateTime.atZone(kolkata);
// Instants can be derived from ZonedDateTimes, do so twice here
Instant utcInstant = timeInUtc.toInstant();
Instant kolkataInstant = timeInKolkata.toInstant();
// provide a factor for a full nano calculation
long nanoFactor = 1000000L;
// calculate the nanos
long nanosInUtc = utcInstant.toEpochMilli() * nanoFactor utcInstant.getNano();
long nanosInKolkata = kolkataInstant.toEpochMilli() * nanoFactor kolkataInstant.getNano();
// produce some meaningful output (expected value or not?)
String utcOutput = String.format("UTC: %-40s ––> %d => %s",
timeInUtc, nanosInUtc,
(expectedNanos == nanosInUtc) ? "expected" : "unexpected");
String kolkataOutput = String.format("Kolkata: %-40s ––> %d => %s",
timeInKolkata, nanosInKolkata,
(expectedNanos == nanosInKolkata) ? "expected" : "unexpected");
// and actually print that output
System.out.println(utcOutput);
System.out.println(kolkataOutput);
}
This will result in the following lines pointing out the importance of the time zone:
UTC: 2022-05-25T05:40:51Z[UTC] ––> 1653457251000000000 => expected
Kolkata: 2022-05-25T05:40:51 05:30[Asia/Kolkata] ––> 1653437451000000000 => unexpected
As you can see, the time of day as well as the date is the same (in your input and both output values), but the offset from UTC is different (Z is an offset of 00:00
hours). That will of course result in different Instant
s.
Given your expected result, you should provide UTC as zone.