使用 Java 8 解析周字符串以进行比较

Parse week strings for comparison using Java 8

我想比较星期的字符串表示,例如周“01/17”在“02/17”之前和“52/16”之后。

我猜下面的代码会引发异常,因为我的字符串没有暗示每周的确切日期。但是,我不在乎 - 可能都是星期一或星期四或其他任何时间:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ww/YY", Locale.GERMANY);
LocalDate date1 = formatter.parse(str1, LocalDate::from);

我需要修改解析器吗?或者解析为其他格式?不幸的是,数周以来都没有像 YearMonth 这样的对象...

我无法找到与 DateTimeFormatter class 一起使用的方法,但我想建议一种不同的方法。

你说的Threeten Extra library contains a number of classes that were deemed too specific to include in the java.time library. One of them is the YearWeekclass

您的问题可以通过从输入字符串中手动解析周数和年份然后像这样调用 YearWeek 创建者方法来解决:

YearWeek yw = YearWeek.of(year, monthOfYear);

一个解决方案是始终默认为同一天,比如星期一。您可以为此构建自定义格式化程序:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
          .appendPattern("ww/YY")
          .parseDefaulting(ChronoField.DAY_OF_WEEK, 1)
          .toFormatter(Locale.GERMANY);

您现在可以构建 LocalDates 代表给定周的星期一:

LocalDate d1 = LocalDate.parse("01/17", fmt);
LocalDate d2 = LocalDate.parse("52/16", fmt);
System.out.println(d1.isAfter(d2));

打印 true 因为 01/17 在 52/16 之后。

tl;博士

YearWeek.parse( "2017-W01" )

ISO 8601

Or parse to some other format?

是,使用其他格式。

使用标准 ISO 8601 formats when serializing date-time values to text. The standard includes support for week dates.

对于年-周来说,这将是四位年份数字、一个连字符、一个 W 和两位数字表示一年中的星期。

2017-W01

弄清楚你对“一周”的定义。 ISO 8601 定义是:

  • 第 1 周包含一年中的第一个星期四,并且
  • 周一至周日运行。

所以 运行 年有 52 周或 53 周。请注意,根据此定义,年份的前几天可能在前一年进行周编号。同样,一年的最后几天可能在下一年的周数。

如果您想指明该周内的特定日期,请附加一个连字符和一个数字 运行ning 1-7 表示星期一至星期日。

提示:要在计算机上默认查看 ISO 8601 周数,您可能需要调整 OS 设置。例如,在 macOS set System Preferences > Language & Region > Calendar > ISO 8601 to make apps such as Calendar.app 上显示具有此标准定义的周数。

2017-W01-7

顺便说一下,几个类似的表示:

  • 表示年份和日期的序数日期 运行ning 从 1-366 是年份,一个连字符和一个三位数:2017-123
  • 没有年份的月-日是两个连字符、月份数字、连字符和日期数字:--01-07

请注意,问题中使用的 Locale 与标准 ISO 8601 格式无关。

YearWeek

Unfortunatley there is no object like YearMonth for weeks...

啊啊啊,可是就是这样的class.

对于 class 直接表示周年的想法,请参阅 . That Answer shows the ThreeTen-Extra library’s class YearWeek

YearWeekclass可以直接解析生成标准格式的字符串

YearWeek yw = YearWeek.parse( "2017-W01" );

您可以将 YearWeek 个对象与方法进行比较:compareToequalsisBeforeisAfter.

yw.isBefore( thatYw )

ThreeTen-Extra 项目提供了其他 class 内容,例如 YearQuarter 您可能会觉得有用。