计算 ISO 8601 周数的好而简单的方法是什么?tl;博士java.time三十多 —YearWeek 关于 java.time

2022-09-02 02:27:21

假设我有一个日期,即年,月和日,作为整数。什么是一个好的(正确的),简洁的和相当可读的算法来计算给定日期所在的一周ISO 8601周数?我遇到了一些真正可怕的代码,让我认为肯定有更好的方法。

我希望在Java中做到这一点,但是对于任何类型的面向对象语言来说,伪代码都很好。


答案 1

tl;博士

LocalDate.of( 2015 , 12 , 30 )
         .get ( 
             IsoFields.WEEK_OF_WEEK_BASED_YEAR 
         )

53

...或。。。

org.threeten.extra.YearWeek.from (
    LocalDate.of( 2015 , 12 , 30 )
)

2015-W53

java.time

ISO 8601 周的支持现已内置于 Java 8 及更高版本的 java.time 框架中。避免旧的和臭名昭着的麻烦的java.util.Date/。日历类,因为它们已被java.time取代。

这些新的 java.time 类包括 LocalDate,用于仅日期值,没有时间或时区。请注意,您必须指定时区才能确定“今天”,因为世界各地的日期并不同时相同。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );

或者按照问题中的建议指定年、月和月中的某一天。

LocalDate localDate = LocalDate.of( year , month , dayOfMonth );

IsoFields 类根据 ISO 8601 标准提供信息,包括基于周的年份的一周。

int calendarYear = now.getYear();
int weekNumber = now.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int weekYear = now.get ( IsoFields.WEEK_BASED_YEAR ); 

在一年的开始/结束附近,基于周的年份可能与日历年不同±1。例如,请注意 2015 年底公历和 ISO 8601 日历之间的差异:第 52 周和第 1 周变为 52 和 53。

enter image description here

enter image description here

三十多 —YearWeek

年周”类将 ISO 8601 基于周的年号周数一起表示为一个对象。此类位于 ThreeTen-Extra 项目中。该项目向 Java 中内置的 java.time 类添加功能。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
YearWeek yw = YearWeek.now( zoneId ) ;

从日期生成。YearWeek

YearWeek yw = YearWeek.from (
    LocalDate.of( 2015 , 12 , 30 )
)

此类可以生成和解析标准 ISO 8601 格式的字符串。

String output = yw.toString() ;

2015-W53

YearWeek yw = YearWeek.parse( "2015-W53" ) ;

您可以提取周数或基于周的年数。

int weekNumber = yw.getWeek() ;
int weekBasedYearNumber = yw.getYear() ;

您可以通过指定要在该周内找到的所需星期几来生成特定日期 ()。要指定星期几,请使用 Java 8 及更高版本中内置的枚举。LocalDateDayOfWeek

LocalDate ld = yw.atDay( DayOfWeek.WEDNESDAY ) ;

关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


答案 2

我相信您可以使用 Calendar 对象(只需将 FirstDayOfWeek 设置为 Monday,将 MinimalDaysInFirstWeek 设置为 4,即可使其符合 ISO 8601)并调用 get(Calendar.WEEK_OF_YEAR)。