I have string like "2021-06-01" and i wish to convert it to the "2021-06-01T00:00:00+02:00" . I know that, the easiest solution is concatanation of string:
date = date+"T00:00:00+02:00";
However, i wish to do it using ZonedDateTime
. Currently my solution is:
public static String formatDate(String date, DateTimeFormatter formatter) {
return ZonedDateTime.parse(date).format(formatter);
}
and then call this method with:
formatDate('2021-06-01', DateTimeFormatter.ISO_LOCAL_DATE);
However, it complains with:
java.time.format.DateTimeParseException: Text '2021-06-01' could not be parsed at index 10
Any solution?
LocalDate#atStartOfDay
However, i wish to do it using ZonedDateTime.
It is similar (not exact) to your other question .
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getOffsetDateTime("2021-06-01"));
}
public static OffsetDateTime getOffsetDateTime(String strDate) {
return LocalDate.parse(strDate)
.atStartOfDay(ZoneOffset.of("+02:00"))
.toOffsetDateTime();
}
}
Output:
2021-06-01T00:00+02:00
If seconds and fraction-of-second are zero, they omitted by default (ie from OffsetDateTime#toString
). If you want to retain them, you can use DateTimeFormatter
eg
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getOffsetDateTime("2021-06-01"));
System.out.println(getFormattedOffsetDateTime(getOffsetDateTime("2021-06-01")));
}
public static OffsetDateTime getOffsetDateTime(String strDate) {
return LocalDate.parse(strDate)
.atStartOfDay(ZoneOffset.of("+02:00"))
.toOffsetDateTime();
}
public static String getFormattedOffsetDateTime(OffsetDateTime odt) {
return DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH).format(odt);
}
}
Output:
2021-06-01T00:00+02:00
2021-06-01T00:00:00+02:00
Learn more about the modern Date-Time API from Trail: Date Time .
Your date string does not have a time, and does not have a zone, so it can't be parsed to a ZonedDateTime
. You are also using the wrong DateTimeFormatter
to format it. ISO_LOCAL_DATE
produces the format yyyy-MM-dd
, not the one you want.
You should instead parse the date string to a LocalDate
, which is just a date , because there's only that much information in that string.
Then, you should add the time component and the offset component to the parsed date, then format it:
public static String formatDate(String date) {
return LocalDate.parse(date)
.atStartOfDay() // sets the time to 00:00:00
.atOffset(ZoneOffset.ofHours(2)) // sets the offset to +02:00
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); // formats it using the desired format
}
Note that atOffset
gives you an OffsetDateTime
, which is enough for what you want to do. If you really want to use ZonedDateTime
, just change it to atZone
, and it will work too, but I think it's unnecessary.
If you want to always have an offset of +02:00
hours, a ZonedDateTime
will not be a good choice because it will consider daylight saving time.
Here's a demo that shows why you might want to use an OffsetDateTime
:
Assume you have two methods:
public static String formatDate(String date, int offset) {
return LocalDate.parse(date)
.atStartOfDay(ZoneOffset.ofHours(offset))
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
and
public static String formatDate(String date, String zone) {
return LocalDate.parse(date)
.atStartOfDay(ZoneId.of(zone))
.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
Both of them take a String
just like your example "2021-06-01"
. The second argument is an offset in the first method and a zone name in the second.
Using both methods with the same date as String
but different second arguments, like this
public static void main(String[] args) {
String dateOne = "2021-06-11";
String dateTwo = "2019-11-19";
String dateThree = "1998-03-27";
String zone = "Europe/Paris";
int offsetHours = 2;
System.out.println(formatDate(dateOne, offsetHours));
System.out.println(formatDate(dateOne, zone));
System.out.println(formatDate(dateTwo, offsetHours));
System.out.println(formatDate(dateTwo, zone));
System.out.println(formatDate(dateThree, offsetHours));
System.out.println(formatDate(dateThree, zone));
}
will produce this output
2021-06-11T00:00:00+02:00
2021-06-11T00:00:00+02:00
2019-11-19T00:00:00+02:00
2019-11-19T00:00:00+01:00
1998-03-27T00:00:00+02:00
1998-03-27T00:00:00+01:00
As you can see, there are differences due to daylight saving time.
That means your requirement it should always be 02:00
given in a comment below your question will not reliably met if you use a ZonedDateTime
(in a way it should be used).
Please note that both example methods use a DateTimeFormatter.ISO_OFFSET_DATE_TIME
which produces a String
in your desired format. You can safely use it with a ZonedDateTime
while you cannot do it the other way round, that would mean formatting an OffsetDateTime
with a DateTimeFormatter.ISO_ZONED_DATE_TIME
because an OffsetDateTime
does not have information about a zone. A ZonedDateTime
does and, thus, always has information about the (zone-specific) offset.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.