【问题标题】:How to get the ISO Day of Week using Calendar API如何使用日历 API 获取 ISO 星期几
【发布时间】:2017-08-04 15:03:05
【问题描述】:

我想使用Calendar API 获取 ISO 星期几,但它返回错误的日期编号。

星期日是一周的最后一天,按照 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 和 Java 6,因此使用另一个库不是解决方案。

【问题讨论】:

    标签: java iso8601 dayofweek


    【解决方案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

    详情

    accepted answer by Maia 是正确的:Those int constants on CalendarSunday-Saturday 的周定义为 1-7,根据美国的习惯。

    DAY_OF_WEEK

    public static final int DAY_OF_WEEK

    get 和 set 的字段编号,表示星期几。此字段采用 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY 和 SATURDAY 值。

    如果您绝对不能添加库,那么您必须从 Calendar 星期天-星期六 1-7 的定义中进行调整。要将 Money 放在首位,请减去 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风格到美式风格(先星期日),计算modulo 7然后加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 的麻烦。那些旧的日期时间类真的很糟糕。

    避免使用旧的日期时间类

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

    java.time

    java.time.DayOfWeek 枚举是标准的,表示由ISO 8601 定义的一周,其中一周从星期一到星期日,编号为 1-7。

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

    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(): 星期日

    道数:7

    输出:周日


    关于java.time

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

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 当然,你是对的。没有枚举,常量。我已经根据这个改变了答案。
      【解决方案3】:

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

      对于美国语言环境,Calendar.SUNDAY 的值为 1。

      【讨论】:

      • Calendar.SUNDAY 的值始终相同,不会因地区而异。
      • Calendar.sunday 不会因语言环境而改变,而是星期几,因为 1 会根据语言环境而改变。我为模糊的答案道歉,但我的意图不同
      猜你喜欢
      • 1970-01-01
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-07
      相关资源
      最近更新 更多