Reputation: 835
I have a logic in python that I am converting into Java code. The logic is I need to read from a timestamp attribute in JSON file and convert it into ISO date format. Python query:
datetime.datetime.fromtimestamp(jsonMsg["time"]).isoformat(timespec='seconds')
Here is the code I wrote in Java 1627065646.444 is an example of the value I get from JSON script
long timestamp = (long) 1627065646.444 * 1000;
Timestamp time = new Timestamp(timestamp);
Date d = new Date(time.getTime());
DateFormat df = new SimpleDateFormat();
String dateToString = df.format(d);
LocalDateTime datetime = LocalDateTime.parse(dateToString, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
ZoneOffset offset = ZoneOffset.UTC;
String formattedTimeStamp = datetime.atOffset(offset).toString();
When I run the code I get compile error "Text '7/23/21 11:40 AM' could not be parsed at index 0 at java.time.format.DateTimeFormatter.parseResolved0" This exception occurs at LocalDateTime.parse(dateToString, DateTimeFormatter.ISO_LOCAL_DATE_TIME. Can someone please help me in understanding what I am doing wrong here.
Upvotes: 0
Views: 3042
Reputation: 79580
The java.util
Date-Time API and their formatting API, SimpleDateFormat
are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time
, the modern Date-Time API:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
long timestamp = (long) (1627065646.444 * 1000);
Instant instant = Instant.ofEpochMilli(timestamp);
System.out.println(instant);
ZonedDateTime zdt = instant.atZone(ZoneOffset.UTC);
LocalDateTime ldt = zdt.toLocalDateTime();
System.out.println(ldt);
// A custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/u h:m:s a", Locale.ENGLISH);
String formatted = dtf.format(zdt);
System.out.println(formatted);
}
}
Output:
2021-07-23T18:40:46.444Z
2021-07-23T18:40:46.444
7/23/2021 6:40:46 PM
The Z
in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC
timezone (which has the timezone offset of +00:00
hours).
Learn more about the modern Date-Time API* from Trail: Date Time.
You have done
long timestamp = (long) 1627065646.444 * 1000;
in which 1627065646.444
will be cast to long
resulting in 1627065646
and thus the result of the multiplication will be 1627065646000
, not 1627065646444
what you are expecting. You need to cast to long
after performing the multiplication.
A valuable comment by Ole V.V.:
I’d use
Math.round(1627065646.444 * 1000)
to make sure that floating-point inaccuracy is handled.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Upvotes: 3