Java 8:如何解析借记卡的到期日期?

9

使用Joda time解析借记/信用卡的过期日期非常容易:

org.joda.time.format.DateTimeFormatter dateTimeFormatter = org.joda.time.format.DateTimeFormat.forPattern("MMyy").withZone(DateTimeZone.forID("UTC"));
org.joda.time.DateTime jodaDateTime = dateTimeFormatter.parseDateTime("0216");
System.out.println(jodaDateTime);

输出:2016-02-01T00:00:00.000Z

我尝试使用Java Time API实现相同的功能:

java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter.ofPattern("MMyy").withZone(ZoneId.of("UTC"));
java.time.LocalDate localDate = java.time.LocalDate.parse("0216", formatter);
System.out.println(localDate);

输出:

异常原因:java.time.DateTimeException: 无法从 TemporalAccessor 中获取 LocalDate:{MonthOfYear=2, Year=2016},ISO,UTC; 类型为 java.time.format.Parsed at java.time.LocalDate.from(LocalDate.java:368) at java.time.format.Parsed.query(Parsed.java:226) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) ... 30 more

我犯了什么错误,应该如何解决?


似乎本地日期不能像你想的那样广泛。本地日期需要包含一个具体的日期。 - Fallenreaper
1个回答

18

LocalDate表示由年、月和日组成的日期。如果没有这三个字段定义,您就无法创建LocalDate。在这种情况下,您正在解析一个月和一年,但没有日期。因此,您不能将其解析为LocalDate

如果日期不重要,您可以将其解析为YearMonth对象:

YearMonth是一个不可变的日期时间对象,表示年份和月份的组合。

public static void main(String[] args) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMyy").withZone(ZoneId.of("UTC"));
    YearMonth yearMonth = YearMonth.parse("0216", formatter);
    System.out.println(yearMonth); // prints "2016-02"
}
你可以通过将这个YearMonth调整为该月的第一天,然后将其转换为LocalDate
LocalDate localDate = yearMonth.atDay(1);

9
走得通 - 尽管在信用卡的情况下,可能会是 LocalDate expiry = yearMonth.atEndOfMonth(); - assylias
3
@assylias 对,但是原帖中的示例代码也会计算为当月的第一天。 - bowmore
3
是的,但这使用了旧的Calendar/Date类。在Java 8中,除非要与不支持Java Time的系统进行操作,否则不应使用这些类。 - Tunaki
3
不需要.withZone(ZoneId.of("UTC")) - JodaStephen
2
@user471011 不一定。您可以使用DateTimeFormatter.parseBest,将其解析为YearMonthLocalDateTime - Tunaki
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接