I'm trying to generate a random date and time, and convert it to the "yyyy-MM-dd'T'HH:mm:ss'Z'"
format.
Here is what I have tried:
public static String generateRandomDateAndTimeInString() {
LocalDate date = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
System.out.println("date and time :: " + date.toString());
return formatDate(date) ;
}
public static String formatDate(LocalDate date){
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
return dateFormat.format(date);
}
But in the line dateFormat.format(date)
, it complains with:
java.lang.IllegalArgumentException: Cannot format given Object as a Date
The second problem is that, the output of print does not contain the time:
date :: 1998-12-24
I don't know how to get it to work.
java.time
types using SimpleDateFormat
Using the SimpleDateFormat
, you are supposed to format only legacy date-time types e.g. java.util.Date
. In order to format the java.time
date-time types, you need to use DateTimeFormatter
.
Z
within single quotesIt's a blunder to enclose Z
within single quotes in a format. The symbol Z
stands for zulu
and specifies UTC+00:00
. If you enclose it within single quotes, it will simply mean character literal, Z
and won't function as UTC+00:00
on parsing.
For this requirement, you do not need to use a formatter explicitly because the OffsetDateTime#toString
already returns the string in the format that you need. However, if the number of seconds in an OffsetDateTime
object is zero, the same and the subsequent smaller units are truncated by OffsetDateTime#toString
. If you need the full format irrespective of the value of seconds, then, of course, you will have to use DateTimeFormatter
.
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Random;
public class Main {
public static void main(String[] args) {
System.out.println(generateRandomDateAndTimeInString());
}
public static String generateRandomDateAndTimeInString() {
LocalDate date = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
System.out.println("date and time :: " + date.toString());
return formatDate(date);
}
public static String formatDate(LocalDate date) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
// return date.atStartOfDay().atOffset(ZoneOffset.UTC).toString();
return date.atStartOfDay().atOffset(ZoneOffset.UTC).format(dtf);
}
}
A sample run:
date and time :: 1996-09-05
1996-09-05T00:00:00Z
Note that the date-time API of java.util
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.
Learn more about the modern date-time API from Trail: Date Time.
SimpleDateFormat
for whatsoever reason:Convert LocalDate
to ZonedDateTime
with ZoneOffset.UTC
and at the start of the day ➡️ Convert ZonedDateTime
to Instant
➡️ Obtain java.util.Date
object from Instant
.
public static String formatDate(LocalDate date) {
Date utilDate = Date.from(date.atStartOfDay(ZoneOffset.UTC).toInstant());
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
return dateFormat.format(utilDate);
}
If you want to ignore the time part then you can use ZonedDateTime
like this:
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
return ZonedDateTime.of(
date,
LocalTime.MIN,
ZoneId.of("Europe/Paris")
).format(dateFormat);
Output example
2013-10-19T00:00:00+0200
Or much better, you can use just toString
to get a formatted date as a String with the default format of ZonedDateTime
:
return ZonedDateTime.of(
date,
LocalTime.MIN,
ZoneId.of("Europe/Paris")
).toString();
Output
2013-10-19T00:00+02:00[Europe/Paris]
Note
This date are always with 00:00:00
for time part, because we are using LocalTime.MIN
Also, you can change the ZoneId
to the expected Zone
, this was just an example.
Important
DateFormat
and SimpleDateFormat
are legacy library, so please don't mix them with the java.time
library, in the top you are using LocalDate
which mean you are using this java.time
library so keep going with it in all your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With