Java Calendar.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY),它会向后滚动,转发还是未知?

时间:2009-08-23 20:30:04

标签: java calendar

假设以下代码在2009年8月22日(星期六)执行

   Calendar c = Calendar.getInstance();
   c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);

c.get(Calendar.DAY_OF_MONTH)将返回23.我感兴趣的是条件将返回14(上周日,而不是下周日)。

是否有任何与方向相关的规则日历会在设置DAY_OF_MONTH/YEAR时滚动DAY_OF_WEEK?如果是这样,他们是什么?

8 个答案:

答案 0 :(得分:12)

应始终保持相同WEEK_OF_MONTHhttp://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#WEEK_OF_MONTH)。来自文档:

  

设置或获取时   WEEK_OF_MONTH或WEEK_OF_YEAR字段,   日历必须确定第一周   作为参考的月份或年份   点。一个月的第一周或   年被定义为最早的七年   开始的一天   getFirstDayOfWeek()并包含at   至少getMinimalDaysInFirstWeek()天   当月或一年。周数   ......,-1,0在第一周之前;   周数为2,3,......跟随它。   注意标准化编号   get()返回可能会有所不同。   例如,特定的日历   子类可以指定前一周   作为第n周的第1周   去年。

答案 1 :(得分:7)

以下公式在[0; 6]

范围内的一周内返回“当前”日
(d + numberOfDaysInAWeek - firstDayOfWeek) % numberOfDaysInAWeek

或如果您想要范围[1; 7]

,请添加1
(d + numberOfDaysInAWeek - firstDayOfWeek) % numberOfDaysInAWeek + 1

dCalendar.get(Calendar.DAY_OF_WEEK)返回的内容

获取一周的第一天,从当前日期减去公式的结果。以下代码执行此操作:

final int currentDayOfWeek = (calendar.get(Calendar.DAY_OF_WEEK) + 7 - cal.getFirstDayOfWeek()) % 7;
cal.add(Calendar.DAY_OF_YEAR, -currentDayOfWeek);

答案 2 :(得分:4)

实际上,这取决于。请考虑以下Java代码。它实际上非常简单,我希望它能打印出2011-09-18之前的星期一,即2011-09-12:

Calendar calendar = Calendar.getInstance(Locale.GERMANY);
System.out.printf("First day of week: %d%n%n", calendar.getFirstDayOfWeek());

calendar.set(2011, Calendar.SEPTEMBER, 18);
System.out.printf("Starting day: %tF%n", calendar);
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.printf("Last monday: %tF%n%n", calendar);

calendar.set(2011, Calendar.SEPTEMBER, 18);
System.out.printf("Starting day: %tF (week %d)%n",
        calendar, calendar.get(Calendar.WEEK_OF_YEAR));
calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.printf("Last monday: %tF (week %d)%n", calendar,
        calendar.get(Calendar.WEEK_OF_YEAR));

但实际上结果有点不同:

First day of week: 2

Starting day: 2011-09-18
Last monday: 2011-09-19

Starting day: 2011-09-18 (week 37)
Last monday: 2011-09-12 (week 37)

换句话说,结果取决于我的日历是否知道我可能对本周感兴趣。如果我查询WEEK_OF_YEAR,结果实际上会发生变化!

答案 3 :(得分:1)

来自Javadoc

  

如果日历字段值中存在任何冲突,则日历会优先考虑最近设置的日历字段。以下是日历字段的默认组合。将使用由最近设置的单个字段确定的最新组合。

     

对于日期字段:

 YEAR + MONTH + DAY_OF_MONTH
 YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
 YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
 YEAR + DAY_OF_YEAR
 YEAR + DAY_OF_WEEK + WEEK_OF_YEAR

我认为这意味着,假设您正在设置星期几,它将最终与一周中的一周或一年中的一周结合,以生成实际的日期和时间。

答案 4 :(得分:1)

使用java.time

现代方法是使用java.time类来取代麻烦的旧遗留日期时间类。

java.time类更容易使用。特别是,它们消除了问题中提出的模糊性。您可以明确询问之前的星期日或之后的星期日。

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

Month枚举提供了十几个预定义的对象,一年中的每个月都有一个。这些枚举对象使用起来更安全,但您可以使用月份的普通数字。与传统课程不同,这几个月的编号很合理,1月至12月为1-12。

LocalDate localDate = LocalDate.of( 2009 , Month.AUGUST, 22 );

TemporalAdjuster接口提供了对日期时间值的操作。 TemporalAdjusters类(注意复数s)提供了几个方便的实现。

previous& next调整员将日期本身排除在考虑之外。 previousOrSame& nextOrSame方法返回有问题的日期,如果它确实是所需的星期几。

DayOfWeek枚举提供了七个预定义的对象,每周对应一个。

LocalDate previousSunday = localDate.with( TemporalAdjusters.previous ( DayOfWeek.SUNDAY ));
LocalDate previousOrSameSunday = localDate.with( TemporalAdjusters.previousOrSame ( DayOfWeek.SUNDAY ));

LocalDate nextSunday = localDate.with( TemporalAdjusters.next ( DayOfWeek.SUNDAY ));
LocalDate nextOrSameSunday = localDate.with( TemporalAdjusters.nextOrSame ( DayOfWeek.SUNDAY ));

转储到控制台。

System.out.println ("localDate: " + localDate + " ( " + localDate.getDayOfWeek ().getDisplayName ( TextStyle.FULL, Locale.US )  + " )");
System.out.println ("previousSunday: " + previousSunday );
System.out.println ("nextSunday: " + nextSunday );
  

localDate:2009-08-22(星期六)

     

previousSunday:2009-08-16

     

nextSunday:2009-08-23

关于java.time

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

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

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

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

答案 5 :(得分:0)

您还应该检查一周中的第一天。 我也认为它总是星期天,但这取决于当地的设置,在我的情况下 星期一是一周的第一天。将星期日设置为一周的第一天解决了我的问题。

答案 6 :(得分:0)

取决于一周的第一天:

 /**
 * Gets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S.,
 * <code>MONDAY</code> in France.
 *
 * @return the first day of the week.
 * @see #setFirstDayOfWeek(int)
 * @see #getMinimalDaysInFirstWeek()
 */
public int getFirstDayOfWeek()
{
    return firstDayOfWeek;
}

答案 7 :(得分:-1)

您可以像这种方法一样使用。

public Integer whichDayOfWeek(Calendar calendar) {
            if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
                return 1;
            } else if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY) {
                return 2;
            } else if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY) {
                return 3;
            } else if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.THURSDAY) {
                return 4;
            } else if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) {
                return 5;
            } else if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
                return 6;
            } else if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
                return 7;
            } else {
                return null;
            }
        }