当前位置:  开发笔记 > 编程语言 > 正文

什么是计算ISO 8601周数的好的,简单的方法?

如何解决《什么是计算ISO8601周数的好的,简单的方法?》经验,为你挑选了4个好方法。

假设我有一个日期,即年,月和日,作为整数.什么是一个好的(正确的),简洁和可读的算法,用于计算给定日期所属的一周的ISO 8601 周数?我遇到了一些真正可怕的代码,这些代码让我觉得必定有更好的方法.

我希望用Java做这个,但任何类型的面向对象语言的伪代码都可以.



1> technophile..:

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



2> Basil Bourqu..:
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/.Calendar类,因为它们已被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周和第53周成为52和53.

在此输入图像描述

在此输入图像描述

ThreeTen-Extra - YearWeek

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() ;

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

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



3> 小智..:
/* Build a calendar suitable to extract ISO8601 week numbers
 * (see http://en.wikipedia.org/wiki/ISO_8601_week_number) */
Calendar calendar = Calendar.getInstance();
calendar.setMinimalDaysInFirstWeek(4);
calendar.setFirstDayOfWeek(Calendar.MONDAY);

/* Set date */
calendar.setTime(date);

/* Get ISO8601 week number */
calendar.get(Calendar.WEEK_OF_YEAR);


而不是`calendar.get(Calendar.YEAR)`使用`calendar.getWeekYear()`来获得与ISO 8601一致的周年

4> skaffman..:

joda-time库具有ISO8601日历,并提供此功能:

http://joda-time.sourceforge.net/cal_iso.html

yyyy-Www-dTHH:MM:SS.SSS这种ISO8601格式包含以下字段:

* four digit weekyear, see rules below
* two digit week of year, from 01 to 53
* one digit day of week, from 1 to 7 where 1 is Monday and 7 is Sunday
* two digit hour, from 00 to 23
* two digit minute, from 00 to 59
* two digit second, from 00 to 59
* three decimal places for milliseconds if required

周总是完成的,一年的第一周是包括一年的第一个星期四的那一周.这个定义可能意味着一年的第一周从上一年开始,而上一周则在下一年结束.周年字段定义为指拥有本周的年份,可能与实际年份不同.

所有这一切的结果是,你创建一个DateTime对象,并调用相当容易混淆(但逻辑上)命名的getWeekOfWeekyear(),其中一周是ISO8601使用年份的特定的基于周的定义.

一般来说,joda-time是一个非常有用的API,我已经完全停止使用java.util.Calendar和java.util.Date,除非我需要与使用它们的API进行交互.

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有