2017-01-05 32 views
2

我想比较几周的字符串表示形式,例如,星期“01/17”在“02/17”之前和“52/16”之后。使用Java 8解析周字符串以进行比较

下面的代码会抛出一个异常,我猜是因为我的字符串没有提示每周的确切日期。然而,我不在乎 - 它可能都是星期一或星期四或者其他:

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

我需要修改解析器吗?或者解析为其他格式? Unfortunatley这个星期没有像YearMonth这样的对象...

+1

你在这里定义的“星期”究竟是什么? –

回答

5

一个解决办法是始终默认为星期一说,这一天。你可以建立一个自定义的格式为:

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

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

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后。

+0

太好了,parseDefaulting()是缺少的一块:) – Tom

2

我无法找到一种方法与DateTimeFormatter类一起工作,但我想建议一种不同的方法。

Threeten Extra library包含多个类别,这些类别被认为过于具体以至于不包含在java.time库中。其中之一是你提到的YearWeek类。

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

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

谢谢,很高兴认识这个图书馆。我发现很奇怪的是,通过模式字符串构建的格式化程序无法提供使用from()创建YearWeek所需的详细信息。但是,通过DateTimeFormatterBuilder构造的工作。不过,这很不幸,因为我想从配置中提供模式。 – Tom

+2

@Tom或者 - 还有更多额外功能 - 还有我的lib Time4J,它提供了[CalendarWeek]类(http://time4j.net/javadoc-en/net/time4j/range/CalendarWeek.html),包括好的i18n - 支持和星期算术(像'plusWeeks()')的方法。 Threeten-Extra中都缺少这两个。但仅用于比较日历周,添加额外的依赖似乎不是必需的。 –

2

TL;博士

YearWeek.parse("2017-W01") 

ISO 8601

或解析为其它格式?

是的,使用其他格式。

将日期时间值序列化为文本时,使用标准ISO 8601格式。该标准包括support for week dates

对于一年四周的数字,连字符,W和一年中的两位数字。

2017年-W01

得到清晰的您一个“周”的定义。在ISO 8601的定义是:

  • 本周#1包含了一年的第一个星期四,并且
  • 是从周一至周日。

因此,这些年可以运行52周或53周。并且请注意,根据这一定义,今年的前几天可能是前一年的周编号。同样,一年中的最后几天可能会在下一个星期编号。

如果您想在该周内指定特定日期,请在星期一至星期日附加一个连字符和一个数字1-7。

提示:要在计算机上默认查看ISO 8601周数,您可能需要调整操作系统设置。例如,在macOS上设置系统首选项>语言&地区>日历> ISO 8601,使应用程序(如Calendar.app)能够显示具有此标准定义的星期编号。

2017年,W01-7

顺便说,一对夫妇类似表述的:

  • 顺序日期意味着一年从运行天的年数1-366是年份,连字符和三位数字:2017-123
  • 不带年份的月份是两个连字符,月份编号,连字符和日期编号:--01-07

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

YearWeek

Unfortunatley有像YearMonth没有对象周...

唉唉,但有这样一类。

对于一个班直接代表每周的想法,请参阅correct Answer by Henrik。答案显示ThreeTen-Extra图书馆的类YearWeek

YearWeek类可以直接解析并生成标准格式的字符串。

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

你可以用方法YearWeek比较对象:compareToequalsisBeforeisAfter

yw.isBefore(thatYw) 

的ThreeTen-EXTRA项目提供了其他类,如YearQuarter,你可能会发现有用的。