I need to convert epoch timestamp to date and time.
I have used the following code to convert but it converts to a wrong date, year and time.
String date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
.format(new java.util.Date (1319286637/1000));
Expected output was today’s date at some time, but the result I got was:
01/01/1970 05:51:59
The Date(long) constructor takes milliseconds. You should be multiplying by 1000, not dividing the epoch time you have.
In brief:
Instant.ofEpochSecond( 1_319_286_637L )
2011-10-22T12:30:37Z
Solution using java.time, the modern API:
import java.time.Instant;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.ofEpochSecond(1319286637L);
System.out.println(instant);
}
}
Output:
2011-10-22T12:30:37Z
An Instant represents an instantaneous point on the timeline. 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).
You can convert an Instant to other Date-Time types e.g.
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.ofEpochSecond(1319286637);
ZonedDateTime zdt = instant.atZone(ZoneId.of("Asia/Kolkata"));
System.out.println(zdt);
// A custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss", Locale.ENGLISH);
System.out.println(dtf.format(zdt));
}
}
Output:
2011-10-22T18:00:37+05:30[Asia/Kolkata]
10/22/2011 18:00:37
Learn more about java.time, the modern Date-Time API* from Trail: Date Time.
Note: 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*. However, for any purpose, if you need to convert this object of Instant to an object of java.util.Date, you can do so as follows:
Date date = Date.from(instant);
* 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.
Related
I have to call a web service which is expecting a Date field but they want it in the following format YYYY-MM-DDThh:mm:ss.sssZ. How can I do this?
I tried the following
OffsetDateTime transactionTime = OffsetDateTime.now(ZoneOffset.UTC);
Date.from(transactionTime.toInstant());
but this didn't work. transactionTime is 2021-06-01T15:11:09.942843400Z, but Date.from converts it to Tue Jun 01 11:11:09 EDT 2021.
BTW, I'm using Java 11
Instant.now().toString()
See that code run live at IdeOne.com.
2021-06-01T15:21:16.783779Z
That format is defined in the ISO 8601 standard. The Z on end means an offset-from-UTC of zero hours-minutes-seconds. Pronounced “Zulu”.
Use java.time.Instant to represent a moment as seen in UTC.
Going the other direction, from text to object.
Instant.parse( "2021-06-01T15:21:16.783779Z" )
If you want only milliseconds, you can lop off any microseconds and nanoseconds by truncating.
Instant.now().truncatedTo( ChronoUnit.MILLIS ) ;
Never use the legacy Date class. Use only the java.time classes.
Use DateTimeFormatter to format the Date-Time object
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
OffsetDateTime transactionTime = OffsetDateTime.now(ZoneOffset.UTC);
String formatted = transactionTime.format(dtf);
System.out.println(formatted);
}
}
Output:
2021-06-01T15:49:45.198Z
Learn more about the modern Date-Time API from Trail: Date Time.
What if I want to use java.util.Date?
For any reason, if you need to convert this object of OffsetDateTime to an object of java.util.Date, you can do so as follows:
Date date = Date.from(transactionTime.toInstant());
Note that a java.util.Date object is not a real Date-Time object like the modern Date-Time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). Since Date does not have timezone information, it applies the JVM's timezone to return the value of Date#toString in the format, EEE MMM dd HH:mm:ss z yyyy calculated from this milliseconds value. If you need to print the Date-Time in a different format and timezone, you will need to use a SimpleDateFormat with the desired format and the timezone set to the applicable one e.g.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDate = sdf.format(date);
System.out.println(strDate);
Output:
2021-06-01T15:49:45.198Z
Some other important notes:
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*.
Most of the symbols that you have used in YYYY-MM-DDThh:mm:ss.sssZ are wrong. Check the description of the symbols from the documentation pages of DateTimeFormatter and SimpleDateFormat.
* 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.
I am trying to convert datetime in a string to an Instant instance using Java 8 or a utilities package.
For example,
String requestTime = "04:30 PM, Sat 5/12/2018";
to
Instant reqInstant should result in 2018-05-12T20:30:00.000Z
reqString is in the America/Toronto time zone.
This is what I tried
String strReqDelTime = "04:30 PM, Sat 5/12/2018";
Date date = new SimpleDateFormat("hh:mm a, EEE MM/dd/yyyy").parse(requestTime);
Instant reqInstant = date.toInstant();
The above code results in "2018-05-12T23:30:00Z".
How can I do it?
tl;dr
Fix your formatting pattern for unpadded month and day.
Use only java.time classes, never the legacy classes.
Contrived example:
LocalDateTime.parse( // Parse as an indeterminate `LocalDate`, devoid of time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline.
"04:30 PM, Sat 5/12/2018" , // This input uses a poor choice of format. Whenever possible, use standard ISO 8601 formats when exchanging date-time values as text. Conveniently, the java.time classes use the standard formats by default when parsing/generating strings.
DateTimeFormatter.ofPattern("hh:mm a, EEE M/d/uuuu", Locale.US) // Use single-character `M` & `d` when the number lacks a leading padded zero for single-digit values.
) // Returns a `LocalDateTime` object.
.atZone( // Apply a zone to that unzoned `LocalDateTime`, giving it meaning, determining a point on the timeline.
ZoneId.of("America/Toronto") // Always specify a proper time zone with `Contintent/Region` format, never a 3-4 letter pseudo-zone such as `PST`, `CST`, or `IST`.
) // Returns a `ZonedDateTime`. `toString` → 2018-05-12T16:30-04:00[America/Toronto].
.toInstant() // Extract a `Instant` object, always in UTC by definition.
.toString() // Generate a String in standard ISO 8601 format representing the value within this `Instant` object. Note that this string is *generated*, not *contained*.
2018-05-12T20:30:00Z
Use single-digit formatting pattern
You used MM in your formatting pattern, to mean any single-digit value (months January-September) will appear with a padded leading zero.
But your input lacks that padded leading zero. So use a single M.
Ditto for day-of-month I expect: d rather than dd.
Use only java.time
You are using troublesome flawed old date-time classes (Date & SimpleDateFormat) that were supplanted years ago by the java.time classes. The new classes entirely supplant the old. There isn't any need to mix the legacy and modern.
LocalDateTime
Parse as a LocalDateTime because your input string lacks any indicator of time zone or offset-from-UTC. Such a value is not a moment, and it is not a point on the timeline. It is only a set of potential moments along a range of about 26-27 hours.
String input = "04:30 PM, Sat 5/12/2018";
DateTimeFormatter f = DateTimeFormatter.ofPattern("hh:mm a, EEE M/d/uuuu", Locale.US); // Specify locale to determine human language and cultural norms used in translating that input string.
LocalDateTime ldt = LocalDateTime.parse(input, f);
ldt.toString(): 2018-05-12T16:30
ZonedDateTime
If you know for certain that input was intended to represent a moment using the wall-clock time used by the people of the Toronto Canada region, apply a ZoneId to get a ZonedDateTime object.
Assigning a time zone gives meaning to your unzoned LocalDateTime. Now we have a moment, a point on the timeline.
ZoneId z = ZoneId.of("America/Toronto");
ZonedDateTime zdt = ldt.atZone(z); // Give meaning to that `LocalDateTime` by assigning the context of a particular time zone. Now we have a moment, a point on the timeline.
zdt.toString(): 2018-05-12T16:30-04:00[America/Toronto]
Instant
To see that same moment as UTC, extract an Instant. Same moment, different wall-clock time.
Instant instant = zdt.toInstant();
instant.toString(): 2018-05-12T20:30:00Z
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.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. There isn't any need for strings or for java.sql.* classes.
Where can we obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
It seems like the time zone on your computer (server) is US Pacific DST (PDT, GMT-7), but you expect to have the result for US Eastern DST (EDT, GMT-4).
Instant.toString() returns UTC (GMT+0) DateTime in ISO 8601 format. ('Z' at the end means UTC).
SimpleDateFormat treats DateTime String in the default time zone of the computer when it is not specified. And your input does not specify a time zone.
So, you need to do something about in what time zone your input is.
PS.: On my machine in Eastern DST, your code gives me the result exactly as you expected.
For the description, you can read Convert String to Date in Java.
String requestTime = "04:30 PM, Sat 5/12/2018 America/Toronto";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a, EEE M/dd/yyyy z");
ZonedDateTime zonedDateTime = ZonedDateTime.parse(requestTime, formatter);
System.out.println(zonedDateTime.toInstant());
What went wrong in your attempt?
The SimpleDateFormat uses the system's time-zone by default while you have mentioned that requestTime is in America/Toronto timezone. You should never rely on the default time-zone because when your code will be run on a machine in different time-zone your application may behave in an unexpected manner.
How should you have done it?
Set the time-zone to America/Toronto before parsing. Also, Never use Date-Time formatting/parsing API without a Locale.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) throws ParseException {
String requestTime = "04:30 PM, Sat 5/12/2018";
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a, EEE MM/dd/yyyy", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/Toronto"));
Date date = sdf.parse(requestTime);
Instant reqInstant = date.toInstant();
System.out.println(reqInstant);
}
}
Output:
2018-05-12T20:30:00Z
Do not pollute the clean java.time API with the error-prone java.util API
The java.time API introduced with Java-8 (March 2014) supplants the error-prone and outdated java.util and their formatting API, SimpleDateFormat. It is recommended to stop using the legacy date-time API and switch to the modern date-time API. You tried parsing the date-time string using the legacy API and then switching to the modern API using Date#toInstant while you could have done everything using the modern API.
You should use Date#toInstant to switch to the modern API if you are using an old code/library that uses java.util.Date.
Solution using the modern date-time API
Parse the date-time string to LocalDateTime as it does not have time-zone → Convert the obtained LocalDateTime into ZonedDateTime of the given time-zone → Convert the obtained ZonedDateTime into Instant.
Demo:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String requestTime = "04:30 PM, Sat 5/12/2018";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("h:m a, EEE M/d/u", Locale.ENGLISH);
// Parse the date-time string to LocalDateTime as it does not have time-zone
LocalDateTime ldt = LocalDateTime.parse(requestTime, dtf);
// Convert the LocalDateTime into ZonedDateTime of the given time-zone
ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/Toronto"));
// Convert the ZonedDateTime into Instant
Instant instant = zdt.toInstant();
System.out.println(instant);
}
}
Output:
2018-05-12T20:30:00Z
Note that I prefer u to y with DateTimeFormatter.
An alternative solution using the modern date-time API
You can convert the obtained LocalDateTime directly into an Instant using LocalDateTime#toInstant by supplying it with the time-zone ID.
Instant instant = ldt.toInstant(ZoneId.of("America/Toronto").getRules().getOffset(ldt));
Learn more about the the modern date-time API from Trail: Date Time.
Instant.parse(String) appropriately formatted
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String dateStr = "2017-03-09T18:30:00.000Z";
Date date = formatter.parse(dateStr);
System.out.println("here");
System.out.println(date);
Thanks i got the problem is was missing 'Z'. Z should be in single
quote as T
No! No! No!
Using 'Z' in the pattern will make Z treated as a character literal instead of as its intended meaning. The Z in the date-time string, 2017-03-09T18:30:00.000Z 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).
Moreover, the modern date-time API* is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the date-time string conforms to the ISO 8601 standards.
Demo:
import java.time.Instant;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.parse("2017-03-09T18:30:00.000Z");
System.out.println(instant);
}
}
Output:
2017-03-09T18:30:00Z
For any reason, if you need to convert this object of Instant to an object of java.util.Date, you can do so as follows:
Date date = Date.from(instant);
Learn more about the modern date-time API from Trail: Date Time.
Using the legacy API:
The legacy date-time API (java.util date-time types and their formatting type, SimpleDateFormat) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API. Just for the sake of completeness, I have written below a solution using the legacy date-time API.
Use X to handle the Z in your date-time string. Check the documentation page to learn more about the symbols.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("y-M-d'T'H:m:s.SSSX", Locale.ENGLISH);
Date date = sdf.parse("2017-03-09T18:30:00.000Z");
System.out.println(date);// Note: will display date-time in your local timezone
}
}
Output in my timezone:
Thu Mar 09 18:30:00 GMT 2017
Note that the java.util.Date object is not a real date-time object like the modern date-time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). When you print an object of java.util.Date, its toString method returns the date-time in the JVM's timezone, calculated from this milliseconds value. If you need to print the date-time in a different timezone, you will need to set the timezone to SimpleDateFormat and obtain the formatted string from it e.g.
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println(sdf.format(date));
* 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.
I have a string with date "10:00 AM 03/29/2011", I need to convert this to a long using Java, I cant use Date because its deprecated and it was not giving me the time correctly.. so i looked online to see how to come about it but still no luck. First time using java.
The problem is you're parsing the data and then messing around with it for no obvious reason, ignoring the documented return value for Date.getYear() etc.
You probably just want something like this:
private static Date parseDate(String text)
throws ParseException
{
SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a MM/dd/yyyy",
Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.parse(text);
}
If you really want a long, just use:
private static long parseDate(String text)
throws ParseException
{
SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a MM/dd/yyyy",
Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.parse(text).getTime();
}
Note that I'm punting the decision of what to do if the value can't be parsed to the caller, which makes this code more reusable. (You could always write another method to call this one and swallow the exception, if you really want.)
As ever, I'd strongly recommend that you use Joda Time for date/time work in Java - it's a much cleaner API than java.util.Date/Calendar/etc.
java.time
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:
Parse the Date-Time string into LocalDateTime.
Convert the LocalDateTime to Instant.
Convert Instant to the Epoch milliseconds.
Demo:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "10:00 AM 03/29/2011";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("h:m a M/d/u", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
Instant instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
long epochMillis = instant.toEpochMilli();
System.out.println(epochMillis);
}
}
Output in my timezone, Europe/London:
1301389200000
ONLINE DEMO
Some important notes about this code:
ZoneId.systemDefault() gives you to the JVM's ZoneId.
If 10:00 AM 03/29/2011 belongs to some other timezone, replace ZoneId.systemDefault() with the applicable ZoneId e.g. ZoneId.of("America/New_York").
If 10:00 AM 03/29/2011 is in UTC, you can do either of the following:
get the Instant directly as ldt.toInstant(ZoneOffset.UTC) or
replace ZoneId.systemDefault() with ZoneId.of("Etc/UTC") in this code.
The timezone of the Ideone server (the online IDE) is UTC whereas London was at an offset of +01:00 hours on 03/29/2011 and hence the difference in the output from my laptop and the one you see in the ONLINE DEMO. Arithmetic: 1301389200000 + 60 * 60 * 1000 = 1301392800000
Learn more about the modern Date-Time API from Trail: Date Time.
* 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.
We're searching for information on how to format instances of java.util.Calendar and more general information and coding hints regarding transition from using java.util.Date to java.util.Calendar.
best,
phil
My hint would be not to use either Date or Calendar. Use Joda Time instead. It's much, much nicer than the built-in classes. JSR-310 will hopefully, eventually bring something Joda-like into the main library, but for the moment Joda is your best bet.
If you must stick to Date/Calendar, see java.text.DateFormat and java.text.SimpleDateFormat. Remember that they're not thread-safe though :(
java.time
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*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
If you are getting an object of java.util.Date from some API, your first step should be to convert it into Instant using Date#toInstant which can be converted to other types of modern Date-Time API.
A demo with the modern Date-Time API:
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
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) {
Instant instant = Instant.now();
System.out.println(instant);
ZonedDateTime zdtUtc = instant.atZone(ZoneId.of("Etc/UTC"));
System.out.println(zdtUtc);
ZonedDateTime zdtNewYork = instant.atZone(ZoneId.of("America/New_York"));
System.out.println(zdtNewYork);
// Fixed offset
OffsetDateTime odtUtc = instant.atOffset(ZoneOffset.UTC);
System.out.println(odtUtc);
OffsetDateTime odtWithOffset0530Hours = instant.atOffset(ZoneOffset.of("+05:30"));
System.out.println(odtWithOffset0530Hours);
// OffsetDateTime from ZonedDateTime
OffsetDateTime odtNewYork = zdtNewYork.toOffsetDateTime();
System.out.println(odtNewYork);
// LocalDate in New York
LocalDate todayNewYork = zdtNewYork.toLocalDate();
System.out.println(todayNewYork);
// Alternatively
System.out.println(LocalDate.now(ZoneId.of("America/New_York")));
// LocalDateTime in New York
LocalDateTime nowNewYork = zdtNewYork.toLocalDateTime();
System.out.println(nowNewYork);
// Alternatively
System.out.println(LocalDateTime.now(ZoneId.of("America/New_York")));
// Formatted output
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMMM dd HH:mm:ss z uuuu", Locale.ENGLISH);
System.out.println(dtf.format(zdtNewYork));
}
}
Output:
2021-07-14T19:22:13.544911Z
2021-07-14T19:22:13.544911Z[Etc/UTC]
2021-07-14T15:22:13.544911-04:00[America/New_York]
2021-07-14T19:22:13.544911Z
2021-07-15T00:52:13.544911+05:30
2021-07-14T15:22:13.544911-04:00
2021-07-14
2021-07-14
2021-07-14T15:22:13.544911
2021-07-14T15:22:13.586971
Wed July 14 15:22:13 EDT 2021
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
Some helpful answers using java.time API:
Check this answer and this answer to learn how to use java.time API with JDBC.
How to use ParsePostion?
Timezone conversion.
SimpleDateFormat does not handle fraction-of-second beyond three digits in the millisecond part correctly.
How to convert LocalDate to ZonedDateTime?
'Z' is not the same as Z.
Day-of-month with ordinal.
The standard library does not support a formatted Date-Time object.
Never use SimpleDateFormat or DateTimeFormatter without a Locale.
How to check if timestamp (epoch time) is of today's or yesterday's?
* 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.