提问人:user3329518 提问时间:10/9/2023 最后编辑:Mr. Polywhirluser3329518 更新时间:11/15/2023 访问量:140
java datetimeformatter 可以处理日期格式的自定义文本吗
Can java datetimeformatter handle custom text in date format
问:
我存储在数据库中:
- 一周,即 2023年的第 10 周
yyyyWww
2023W10
- 一个月的含义 2023 年 10 月
2023M10
我可以使用和格式化。yyyy'W'ww
yyyy'M'MM
SimpleDateFormat
DateTimeFormatter
在这些情况下给予。似乎只接受带有有限文本(破折号、斜杠、句点)的完整日期 ()DateTimeParseException
DateTimeFormatter
year+month+day
我在这里错过了什么?
我已经尝试过 和 格式化 ,两者都给出了 parseexceptions。yyyy'W'ww
yyyy'M'MM
dateTimeFormatter
答:
您需要使用 a 来应用默认值以及您的模式。DateTimeFormatterBuilder
一个简单的方法是提前声明所有已知格式并遍历它们。如果要消除循环,可以检查字符串是否包含“W”并调用周解析器,或者检查“M”是否包含“M”并调用月份解析器。
请注意,(大写)表示以周为基础的年份,而(小写)表示时代(正常的 365 天一年)。YYYY
yyyy
import java.time.*;
import java.time.format.*;
import java.time.temporal.*;
class DateParsing {
private static final DateTimeFormatter
PARSE_WEEK = new DateTimeFormatterBuilder()
.appendPattern("YYYY'W'ww")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())
.toFormatter(),
PARSE_MONTH = new DateTimeFormatterBuilder()
.appendPattern("yyyy'M'MM")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.toFormatter();
private static final DateTimeFormatter[] PATTERNS = { PARSE_WEEK, PARSE_MONTH };
public static LocalDate parseDate(String input) throws IllegalArgumentException {
for (DateTimeFormatter pattern : PATTERNS) {
try {
return LocalDate.parse(input, pattern);
} catch (DateTimeParseException e) {
// System.err.println("Error: " + e.getMessage());
}
}
throw new IllegalArgumentException(String.format("Unknown format: %s", input));
}
public static void main(String[] args) throws IllegalArgumentException {
String[] timestamps = {
"2023W10", // 10th week of 2023
"2023M10" // October 1, 2023
};
for (String timestamp : timestamps) {
System.out.printf(">>> %s => %s%n", timestamp, parseDate(timestamp));
}
}
}
输出:
>>> 2023W10 => 2023-03-05
>>> 2023M10 => 2023-10-01
更新
如果要删除循环和异常处理,可以检查输入字符串是否包含“M”或“W”,如上所述。
import java.time.*;
import java.time.format.*;
import java.time.temporal.*;
class DateParsing {
private static final DateTimeFormatter
PARSE_WEEK = new DateTimeFormatterBuilder()
.appendPattern("YYYY'W'ww")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())
.toFormatter(),
PARSE_MONTH = new DateTimeFormatterBuilder()
.appendPattern("yyyy'M'MM")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.toFormatter();
public static LocalDate parseDate(String input) throws DateTimeParseException, IllegalArgumentException {
if (input.contains("M")) {
return LocalDate.parse(input, PARSE_MONTH);
}
if (input.contains("W")) {
return LocalDate.parse(input, PARSE_WEEK);
}
throw new IllegalArgumentException(String.format("Unknown format: %s", input));
}
public static void main(String[] args) throws DateTimeParseException, IllegalArgumentException {
String[] timestamps = {
"2023W10", // 10th week of 2023
"2023M10" // October 1, 2023
};
for (String timestamp : timestamps) {
System.out.printf(">>> %s => %s%n", timestamp, parseDate(timestamp));
}
}
}
评论
catch (Exception e)
throws IllegalArgumentException
DateTimeParseException
Exeception
throws
TL的;博士
在您的特定情况下,您可以轻松地使用字符串操作而不是 .DateTimeFormatter
org.threeten.extra.YearWeek.parse( "2023W31".replace ( "W" , "-W" ) )
...和:
java.time.YearMonth.parse( "2023M07".replace( "M" , "-" ) )
更好的是:更改您的数据以使用标准 ISO 8601 格式。
- 2023W31
2023-W31➡️ 2023M07 2023-07➡️
详
我在这里错过了什么?
您缺少相应的类。
YearWeek
对于您的第一个案例,即一年中的一周,请使用库 ThreeTen-Extra 中的 org.threeten.extra.YearWeek
类。该库为 JSR 310 中定义的 Java 8+ 中内置的 java.time 类添加了功能。
该类在分析/生成文本时使用标准 ISO 8601 格式。因此,您不需要指定格式模式。YearWeek
输入文本符合 ISO 8601 标准的缩写样式,但不符合首选的扩展样式。要符合扩展样式,请插入连字符 .input.replace( "W" , "-W" )
String input = "2023W31".replace ( "W" , "-W" );
YearWeek yearWeek = YearWeek.parse ( input );
System.out.println ( "yearWeek = " + yearWeek );
年周 = 2023-W31
定义“周”
仅当您对“周”的定义与 ISO 8601 标准定义一致时,才使用此类:YearWeek
- 每年有 52 或 53 个完整的 7 天周。
- 一周从星期一开始。
- 第 # 1 周包含日历年的第一个星期四。
YearMonth
对于第二种情况,请使用 Java 8+ 中内置的 java.time.YearMonth
类。
一年和一个月的标准 ISO 8601 格式是 YYYY-MM。我建议您在数据库中的存储值中使用此标准格式。
YearMonth yearMonth = YearMonth.parse( "2023-07" ) ;
如果您坚持使用自定义格式,则可以定义一个 来指定您的特定格式模式。但我会用连字符替换。DateTimeFormatter
M
YearMonth yearMonth = YearMonth.parse( "2023M07".replace( "M" , "-" ) ) ;
yearMonth = 2023-07
非常感谢所有的意见。我不知道 ISO 日期格式,将来我会使用它们。我的要求是平均值,例如每天、每周和每月的价格。据我所知,日期/日历的缺陷不会影响我产生的值。当它们被弃用时,我会咬紧牙关重新编码。
评论
java.date
DateTime...
LocalDate.parse
DateTimeFormatter.ofPattern()
formatter.parse()
DateTimeFormatter
只接受具有有限文本(破折号、斜杠、句点)的完整日期(年+月+日)至少在两个方面通常不正确。是什么让你觉得是?