如何使用日历获取 ISO 星期几 API

How to get the ISO Day of Week using Calendar API

我想使用 Calendar API 获取 ISO 星期几,但是 returns 错误的日期。

星期日是一周的最后一天,按照 ISO 标准应该是数字 7,星期一是第一天,数字 1。

但是 运行 以下星期日 (2017-07-30) 的代码返回我的号码 1。为什么 Calendar API 返回一个不同的值?

Calendar cal = Calendar.getInstance(Locale.US);
cal.set(Calendar.YEAR, 2017);
cal.set(Calendar.MONTH, Calendar.JULY);
cal.set(Calendar.DAY_OF_MONTH, 30);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);

System.out.println(dayOfWeek);

结果是:1

我尝试使用 Joda Time,它运行良好,但我需要使用 Calendar 和 Java6,所以使用另一个库不是解决方案。

int 常量以星期日开始,以星期六结束。

记录在 java.util.Calendar JavaDoc for Java 6

所以我的建议是自己计算。

在发布问题之前检查 java 6 日历的 Javadoc values of Constants in Calendar

对于美国区域设置,Calendar.SUNDAY 的值为 1。

tl;博士

确定星期几的传统方法定义了 ISO 8601(周一至周日,1-7):

int dayOfWeekISO = cal.get( Calendar.DAY_OF_WEEK ) - 1 ;
if( dayOfWeekISO == 0 ) {  // For Sunday ( 1 - 1 = 0), add 7. 
    dayOfWeekISO = ( dayOfWeekISO + 1 ) ; 
}

现代方式:

LocalDate.of( 2017 , Month.JULY , 30 )  // Date-only value.
         .getDayOfWeek()                // `DayOfWeek.SUNDAY` enum object.
         .getValue()                    // 7 for Sunday. (1 = Monday, per ISO 8601 standard.)

7

详情

is correct: Those int constants on Calendar define the week as 1-7 for Sunday-星期六,按照美国的习俗。

DAY_OF_WEEK

public static final int DAY_OF_WEEK

Field number for get and set indicating the day of the week. This field takes values SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, and SATURDAY.

如果您绝对不能添加图书馆,那么您必须根据 Calendar 一周的定义进行调整,即 Sunday-Saturday 1-7。要将金钱放在首位,请减去 1,然后检查 0 并添加 7。

int dayOfWeekISO = cal.get( Calendar.DAY_OF_WEEK ) - 1 ;
if( dayOfWeekISO == 0 ) {  // For Sunday ( 1 - 1 = 0), add 7. 
    dayOfWeekISO = ( dayOfWeekISO + 1 ) ; 
}

顺便走另一条路,从ISO 8601 style to US-style (Sunday first), calculate modulo7然后加1。

( DayOfWeek.SUNDAY.getValue() % 7 ) + 1

像这样:

System.out.println( ( DayOfWeek.SUNDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.MONDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.TUESDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.WEDNESDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.THURSDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.FRIDAY.getValue() % 7 ) + 1 ) ;
System.out.println( ( DayOfWeek.SATURDAY.getValue() % 7 ) + 1 ) ;

1

2

3

4

5

6

7

但请考虑添加 a library of modern date-time classes。非常值得为您的项目添加一个 jar。那些老掉牙的classes真是可怜

避免遗留日期时间 classes

Calendar class 是麻烦的旧旧日期时间 classes 的一部分,现在被 java.time classes 取代。

java.time

java.time.DayOfWeek enum is standard, representing a week defined by ISO 8601 其中一周从星期一到星期日,编号为 1-7。

LocalDate class 表示没有时间和时区的仅日期值。

LocalDate ld = LocalDate.of( 2017 , Month.JULY , 30 ) ;
DayOfWeek dow = ld.getDayOfWeek() ;
int dowNumber = dow.getValue() ;
String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; 

参见 this code run live at IdeOne.com

ld.toString(): 2017-07-30

dow.toString(): SUNDAY

dowNumber: 7

output: Sunday


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

从哪里获得java.time classes?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.