年份和基于周的年份之间的区别?tl;博士详 y和(小写)u Y(大写)三十-额外

2022-08-31 11:16:28

Java 8 的 DateTimeFormatter 类有一个方法 ,它允许您从一串字母定义格式。这些示例没有阐明 , 和 基于周的年份之间的区别。这是什么?ofPattern(String pattern)A-za-zyY

Symbol  Meaning                     Presentation      Examples
------  -------                     ------------      -------
 y       year-of-era                 year              2004; 04
 Y       week-based-year             year              1996; 96

答案 1

这是“年-周”样式日期的年份值,如 2006-W52。如果相关周跨越年份边界,则它可能偏离年份值 +1 或 -1。

查看 http://en.wikipedia.org/wiki/ISO_8601#Week_dates


答案 2

tl;博士

table showing the calendar year of 2019-12-30 is 2019 while the week-based year is 2020

Table showing the length in days and weeks for a calendar year and a week-based year, 365 or 366 days versus 364 or 371, and 52 partial weeks versus 52 or 53 whole weeks.

其他一些答案非常有趣,但很复杂。这是一个希望更简单的答案,让你的方向。

y和(小写)u

“时代年份”的字符只是日历年,这是基于公历的西方和世界大部分地区使用的常规年份。y

DateTimeFormatter 类也使用 a 来表示几乎相同的内容。对于当代日期,没有区别。有关细节的详细信息,请参阅 Java 中 DateTimeFormatter 格式化模式代码中的 uuuuyyyyu

对于我们在日常生活中使用的常规日期,您将使用格式设置模式解析或生成表示日期值的文本,例如:

DateTimeFormatter.ofPattern( "dd/MM/yyyy" ) ;

...或。。。

DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;

在任何一种情况下,2019 年 12 月 30 日星期一都将按如下方式解析:

LocalDate localDate = LocalDate.parse( "30/12/2019" ) ;

localDate.toString(): 2019-12-30

Y(大写)

各行各业的许多人发现,按周跟踪时间很有用,为一年中的每一周分配一个数字。

有多种方法可以定义一周,例如从星期日或星期一开始。因此,有多种方法可以定义一年中的一周。第1周有1月1日吗?或者第1周有一年中的第一个星期日?

ISO 8601标准将一周定义为从星期一开始。第 1 周是新日历年的第一个星期四。

此定义意味着基于周的年份有 52 或 53 个整周,始终为 7 天(周一到周日),一年长度为 364 天或 371 天。相比之下,一个日历年有 365 天或 366 天,跨越 52 个部分周。

因此,日期2019-12-30(星期一,2019年12月30日)实际上是基于周的2020年的第一周。

calendar showing week # 1 of 2020, starting with December 30, 2019.

  • 如果需要生成或分析 2020 年基于周的年份值,请在格式设置模式中对该日期 2019-12-30 使用大写字母。YYYY
  • 如果您想要2019-12-30的日历年,即2019,请使用小写。yyyy

ISO 8601 格式

ISO 8601 标准定义了表示基于周的年份的一周内日期的特定格式:YYYY-Www-d,其中基于周的年份是固定的,表示周号 1-52 或 1-53,表示星期一到星期日运行 1-7 的星期几。YYYY-Wwwd

因此,2019 年 12 月 30 日星期一是:表示基于周的 2020 年、一年的第一周和一周的第一天(星期一)。2020-W01-1

要使用星期几数字解析ISO 8601周,我们可以使用 .无需使用 定义格式设置模式,因为这项工作已经为您完成。使用内置的 DateTimeFormatter.ISO_WEEK_DATEDateTimeFormatterYYYY

String output = localDate.format( DateTimeFormatter.ISO_WEEK_DATE ) ;

2020-W01-1

同样,解析。

LocalDate localDate = 
    LocalDate.parse( 
        "2020-W01-1" , 
        DateTimeFormatter.ISO_WEEK_DATE
    )
;

localDate.toString(): 2019-12-30

三十-额外

ThreeTen-Extra库为Java中内置的java.time类添加了功能。

org.threeten.extra.YearWeek

该库提供该类。如果您正在根据 ISO 8601 对周和基于周的年份的定义处理基于周的周数,这正是您所需要的。YearWeek

此类可以在常规日期格式和面向周的格式之间来回转换。

LocalDate localDate = LocalDate.of( 2019 , Month.DECEMBER , 30 ) ;  // Monday 2019-12-30. Its week-based year is 2020. 
YearWeek yearWeek = YearWeek.from( localDate ) ;
String wFormatted = yearWeek.toString() ;

2020-W01

从中得到一个日期。

LocalDate localDate = yearWeek.atDay( DayOfWeek.MONDAY ) ;

localDate.toString(): 2019-12-30