提问人:Diksha Goyal 提问时间:5/19/2023 最后编辑:TylerHDiksha Goyal 更新时间:5/23/2023 访问量:154
如何将JDK11中的不同日期格式转换为dd-mm-yyyy格式?[复制]
How to convert different date formats in JDK11 to dd-mm-yyyy format? [duplicate]
问:
我有一个用例,其中日期采用以下格式,
- 2023-05-09T05:55:07Z
- 2023-04-30
- 08-05-2023
- 2023-05-09 00:00:00
- 12月 31, 2021
无论输入格式如何,我都需要将其转换为格式。如何在 JDK11 中转换它?我尝试了不同的库,但没有运气。dd-mm-yyyy
答:
2赞
Mr. Polywhirl
5/19/2023
#1
您可以循环访问已知格式并跳过抛出 .DateTimeParseException
注意:如果仅将日期字符串解析为 ,则需要构建格式化程序并指定时间部分是可选的。LocalDateTime
import java.time.LocalDateTime;
import java.time.format.*;
import java.time.temporal.ChronoField;
import java.util.*;
public class DateParser {
public static void main(String[] args) {
System.out.println(normalizeDate("2023-05-09T05:55:07Z")); // 2023-05-09
System.out.println(normalizeDate("2023-04-30")); // 2023-04-30
System.out.println(normalizeDate("08-05-2023")); // 2023-08-05
System.out.println(normalizeDate("2023-05-09 00:00:00")); // 2023-05-09
System.out.println(normalizeDate("31-Dec-2021")); // 2021-12-31
System.out.println(normalizeDate("")); // null
}
public static String normalizeDate(String rawDateTimeString) {
return Optional.ofNullable(parseDateString(rawDateTimeString))
.map(displayFormat::format)
.orElse(null);
}
private static LocalDateTime parseDateString(String dateString) {
for (DateTimeFormatter formatter : knownFormats) {
try {
return LocalDateTime.parse(dateString, formatter);
} catch (DateTimeParseException e) {
continue;
}
}
return null;
}
private static final List<DateTimeFormatter> knownFormats = Arrays.asList(
DateTimeFormatter.ISO_DATE_TIME,
dateOnlyFormatter("yyyy-MM-dd"),
dateOnlyFormatter("MM-dd-yyyy"),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
dateOnlyFormatter("dd-MMM-yyyy").withLocale(Locale.ENGLISH));
private static DateTimeFormatter dateOnlyFormatter(String datePattern) {
// Credit: https://stackoverflow.com/a/40175568/1762224
return new DateTimeFormatterBuilder()
.appendPattern(datePattern)
.optionalStart()
.appendPattern(" HH:mm")
.optionalEnd()
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.toFormatter();
}
private static final DateTimeFormatter displayFormat = DateTimeFormatter.ISO_DATE;
}
这是一个修改后的版本,正如 Devin 建议的那样更简单。它完全忽略了时间的概念,在解析时只关注日期。它消除了对该方法的需求(如上所示)。dateOnlyFormatter
import java.time.LocalDate;
import java.time.format.*;
import java.util.*;
public class DateParser {
public static void main(String[] args) {
System.out.println(normalizeDate("2023-05-09T05:55:07Z")); // 2023-05-09
System.out.println(normalizeDate("2023-04-30")); // 2023-04-30
System.out.println(normalizeDate("08-05-2023")); // 2023-08-05
System.out.println(normalizeDate("2023-05-09 00:00:00")); // 2023-05-09
System.out.println(normalizeDate("31-Dec-2021")); // 2021-12-31
System.out.println(normalizeDate("")); // null
}
public static String normalizeDate(String rawDateTimeString) {
return Optional.ofNullable(parseDateString(rawDateTimeString))
.map(displayFormat::format)
.orElse(null);
}
private static LocalDate parseDateString(String dateString) {
for (DateTimeFormatter formatter : knownFormats) {
try {
return LocalDate.parse(dateString, formatter);
} catch (DateTimeParseException e) {
continue;
}
}
return null;
}
private static final List<DateTimeFormatter> knownFormats = Arrays.asList(
DateTimeFormatter.ISO_DATE_TIME,
DateTimeFormatter.ofPattern("yyyy-MM-dd"),
DateTimeFormatter.ofPattern("MM-dd-yyyy"),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
DateTimeFormatter.ofPattern("dd-MMM-yyyy").withLocale(Locale.ENGLISH));
private static final DateTimeFormatter displayFormat = DateTimeFormatter.ISO_DATE;
}
评论
1赞
Mr. Polywhirl
5/19/2023
@user16320675我添加到上面的违规格式化程序中。.withLocale(Locale.ENGLISH)
0赞
Basil Bourque
5/21/2023
很好的答案,但这已经在其他多个现有问题中涉及。
0赞
Basil Bourque
5/21/2023
在实际工作中,区域设置可能需要指定一种区域性,并可能指定一个子区域性。日期时间格式(缩写、标点符号、大写)在不同的英语地区可能会有所不同。
-1赞
DevinJM3
5/19/2023
#2
这种方法简单易懂。以下是 parseDateTime 函数的所有功能:
- 设置输出格式
- 设置所有可能的输入格式
- 循环访问每种输入格式,直到找到正确的格式
- 以指定的输出格式返回日期/时间
注意如果传递给函数的 String 不是 5 种指定的输入格式之一,则它将返回 null。这应该可以很容易地看出它是否成功!
如果您需要更多信息来帮助添加更多格式,请参阅 DateTimeFormatter 文档:https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_DATE
import java.time.*;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String[] inputDates = {
"2023-04-30T05:55:07Z",
"2023-04-30",
"30-04-2023",
"2023-04-30 00:00:00",
"30-Apr-2023"
};
for(String date : inputDates)
System.out.println(date + "\t->\t" + parseDateTime(date));
}
private static String parseDateTime(String currentDate){
//Desired Output Pattern
DateTimeFormatter outputFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy");
//All Possible Input Patterns
DateTimeFormatter[] formatters = {
DateTimeFormatter.ISO_LOCAL_DATE,
DateTimeFormatter.ofPattern("dd-MM-yyyy"),
DateTimeFormatter.ofPattern("dd-MMM-yyyy"),
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
};
//Iterate over each pattern until it finds the correct one
for(DateTimeFormatter currFormatter : formatters){
try{
return LocalDate.parse(currentDate, currFormatter).format(outputFormat);
} catch(Exception ignored){
//Current formatter did not work, so lets try the next one
}
}
return null; // String was not one of those 5 formats
}
}```
评论
2赞
user16320675
5/19/2023
请注意,解析月份名称是敏感的;这可以代表一个时区,不一定是字面意思Locale
Z
Z
0赞
Basil Bourque
5/21/2023
切勿在日期时间格式模式中将引号括起来。引号的意思是“期待但忽略此文本”。忽略该文本是不安分的,因为 a 的存在意味着“与 UTC 的偏移量为零小时-分钟-秒”。你丢弃了有价值的信息,却没有回报。我必须对建议数据丢失的解决方案投反对票。Z
Z
评论
new Date()
08-05-2023
MM-dd-uuuu
dd-MM-uuuu
DateTimeFormatter
java.util
java.time