Java日历 - 一周的第一天VS实际最小值

时间:2015-04-07 09:29:39

标签: java calendar

我正在测试我们的日期管理框架,它应该重置一些Calendar字段(使用actual minimum)。

但是,当changing first day of week时,Calendar总是将SUNDAY1)作为actual minimum day of weeks返回MVCE。这是一个错误吗?

{{3}}:

import java.util.*;

public class Main {
  public static void main(String[] args) {
    System.out.printf("Java specification: %s%n", System.getProperty("java.vm.specification.version"));
    System.out.printf("Java version: %s%n", System.getProperty("java.specification.version"));
    System.out.printf("VM version: %s%n", System.getProperty("java.vm.version"));

    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));

    int[] days = { 1, 5, 7 };
    for (int day : days) {
      cal.setTimeInMillis(0L);
      cal.setFirstDayOfWeek(day);
      System.out.printf("expected: %d, actual: %d%n", day, cal.getActualMinimum(Calendar.DAY_OF_WEEK));
    }
  }
}

2 个答案:

答案 0 :(得分:4)

  

你应该使用cal.getFirstDayOfWeek()的instand   cal.getActualMinimum(Calendar.DAY_OF_WEEK)

,因为 cal.getActualMinimum(Calendar.DAY_OF_WEEK)将始终返回周日看看java源代码中getActualMinimum(Calendar.DAY_OF_WEEK)的实现

  public int getActualMinimum(int field) {
        if (field == DAY_OF_MONTH) {
            GregorianCalendar gc = getNormalizedCalendar();
            int year = gc.cdate.getNormalizedYear();
            if (year == gregorianCutoverYear || year == gregorianCutoverYearJulian) {
                long month1 = getFixedDateMonth1(gc.cdate, gc.calsys.getFixedDate(gc.cdate));
                BaseCalendar.Date d = getCalendarDate(month1);
                return d.getDayOfMonth();
            }
        }
        return getMinimum(field);
    }

getMinimum是: -

   public int getMinimum(int field) {
        return MIN_VALUES[field];
    }

和MIN_VALUES数组定义为: -

 static final int MIN_VALUES[] = {
        BCE,            // ERA
        1,              // YEAR
        JANUARY,        // MONTH
        1,              // WEEK_OF_YEAR
        0,              // WEEK_OF_MONTH
        1,              // DAY_OF_MONTH
        1,              // DAY_OF_YEAR
        SUNDAY,         // DAY_OF_WEEK
        1,              // DAY_OF_WEEK_IN_MONTH
        AM,             // AM_PM
        0,              // HOUR
        0,              // HOUR_OF_DAY
        0,              // MINUTE
        0,              // SECOND
        0,              // MILLISECOND
        -13*ONE_HOUR,   // ZONE_OFFSET (UNIX compatibility)
        0               // DST_OFFSET
    };

答案 1 :(得分:0)

Answer by K M PATEL是正确的。

问题和答案都使用过时的课程。与最早版本的Java捆绑在一起的旧日期时间类已被java.time类取代。

标准定义

DayOfWeek enum根据ISO 8601标准定义一周,Monday为1,Sunday为7。

您可以向DayOfWeek对象询问此1-7号码。

int dayOfWeekNumber = DayOfWeek.WEDNESDAY.getValue();

但是不要在代码中传递这个数字。而是传递DayOfWeek个对象以享受type-safety的好处并保证有效值。

本地化定义

对于星期几,周和周年字段的本地化定义,请使用WeekFields类。

WeekFields weekFields_US = WeekFields.of ( Locale.US );
DayOfWeek firstDayOfWeek = weekFields_US.getFirstDayOfWeek ();

转储到控制台。

System.out.println ( "weekFields_US: " + weekFields_US + " | firstDayOfWeek: " + firstDayOfWeek );
  

weekFields_US:WeekFields [SUNDAY,1] | firstDayOfWeek:SUNDAY

定义您自己的周变化

我建议坚持指定Locale个对象来定义周。但如果你坚持,你可以定义自己的一周变化。致电WeekFields.of并指定(a)一周的第一天,以及(b)定义一年中第一周或第一周的最小天数。

首先,为了进行比较,使用IsoFields类中包含的标准ISO 8601定义获取星期数。

// Using standard IsoFields.
LocalDate localDate = LocalDate.of ( 2016 , 2 , 3 ); // Feb 3 2016 = Wednesday
DayOfWeek dow = DayOfWeek.from ( localDate );
int ordinalNumberDayOfWeek = dow.getValue ();

转储到控制台。

System.out.println ( "localDate: " + localDate + " | dow: " + dow + " | ordinalNumberDayOfWeek: " + ordinalNumberDayOfWeek );
  

localDate:2016-02-03 |道琼斯:星期三| ordinalNumberDayOfWeek:3

现在切换到定义我们自己的WeekFields对象,并再次询问星期几编号。上面我们看到3因为2016年2月3日是星期三,所以星期一 - 星期二 - 星期三渲染3。下面我们看到4,因为周日 - 周一 - 周二 - 周三。

// Define our own WeekFields to use in place of IsoFields.
WeekFields weekFields_SUNDAY_1 = WeekFields.of ( DayOfWeek.SUNDAY , 1 );
int ordinalNumberDayOfWeek_SundayBasedWeek = localDate.get ( weekFields_SUNDAY_1.dayOfWeek () );

转储到控制台。

System.out.println ( "ordinalNumberDayOfWeek_SundayBasedWeek: " + ordinalNumberDayOfWeek_SundayBasedWeek );
  

ordinalNumberDayOfWeek_SundayBasedWeek:4

(基于JodaStephen的this Answer的例子)

参见类似的问题,java get week of year for given a date