简体   繁体   English

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

[英]Java Calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY), will it roll backwards, forwards or unknown?

Suppose the following code is executed on the 22nd of August 2009 (a Saturday) 假设以下代码在2009年8月22日(星期六)执行

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

c.get(Calendar.DAY_OF_MONTH) will return 23. I'm interested in the conditions is would return 14 (last Sunday, rather than the next Sunday). c.get(Calendar.DAY_OF_MONTH)将返回23.我感兴趣的条件是将返回14(上周日,而不是下周日)。

Are there any rules associated with the direction Calendar will roll the DAY_OF_MONTH/YEAR when DAY_OF_WEEK is set? 是否有与方向相关的规则当DAY_OF_WEEK设置时,日历将滚动DAY_OF_MONTH/YEAR If so what are they? 如果是这样,他们是什么?

It should always keep the same WEEK_OF_MONTH ( http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#WEEK_OF_MONTH ). 它应始终保持相同的WEEK_OF_MONTHhttp://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#WEEK_OF_MONTH )。 From the documentation: 从文档:

When setting or getting the WEEK_OF_MONTH or WEEK_OF_YEAR fields, Calendar must determine the first week of the month or year as a reference point. 设置或获取WEEK_OF_MONTH或WEEK_OF_YEAR字段时,日历必须将月份或年份的第一周确定为参考点。 The first week of a month or year is defined as the earliest seven day period beginning on getFirstDayOfWeek() and containing at least getMinimalDaysInFirstWeek() days of that month or year. 一个月或一年的第一周定义为从getFirstDayOfWeek()开始并且至少包含该月或年的getMinimalDaysInFirstWeek()天的最早七天。 Weeks numbered ..., -1, 0 precede the first week; 周数在第一周之前编号为......,-1,0; weeks numbered 2, 3,... follow it. 周数为2,3,......跟随它。 Note that the normalized numbering returned by get() may be different. 请注意,get()返回的规范化编号可能不同。 For example, a specific Calendar subclass may designate the week before week 1 of a year as week n of the previous year. 例如,特定的日历子类可以指定一年的第1周之前的一周作为前一年的第n周。

the following formula returns "current" day in a week in range of [0;6] 以下公式在[0; 6]范围内的一周内返回“当前”日

(d + numberOfDaysInAWeek - firstDayOfWeek) % numberOfDaysInAWeek

or add 1 if you would like range [1;7] 如果你想要范围,可以加1 [1; 7]

(d + numberOfDaysInAWeek - firstDayOfWeek) % numberOfDaysInAWeek + 1

d is what Calendar.get(Calendar.DAY_OF_WEEK) returns dCalendar.get(Calendar.DAY_OF_WEEK)返回的内容

to get first day of a week, subtract formula's result from current date. 获取一周中的第一天,从当前日期中减去公式的结果。 The following code does it: 以下代码执行此操作:

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

It depends, actually. 实际上,这取决于。 Consider the following Java code. 请考虑以下Java代码。 It is actually quite simple and I expect it to print the monday preceding 2011-09-18, that is 2011-09-12: 它实际上非常简单,我希望它能打印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));

But in fact the result is a bit different: 但实际上结果有点不同:

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)

In other words, the result depends on whether my calendar knows that I might be interested in the week. 换句话说,结果取决于我的日历是否知道我可能对本周感兴趣。 The result actually changes if I query WEEK_OF_YEAR ! 如果我查询WEEK_OF_YEAR ,结果实际上会改变!

Using java.time 使用java.time

The modern approach is with the java.time classes that supplant the troublesome old legacy date-time classes. 现代方法是使用java.time类来取代麻烦的旧遗留日期时间类。

The java.time classes are much easier to work with. java.time类更容易使用。 In particular, they remove the ambiguity raised in the Question. 特别是,它们消除了问题中提出的模糊性。 You can explicitly ask either for the earlier Sunday or for the later Sunday. 您可以明确询问早期星期日或晚些星期日。

The LocalDate class represents a date-only value without time-of-day and without time zone. LocalDate类表示没有时间且没有时区的仅日期值。

The Month enum provides a dozen pre-defined objects, one for each month of the year. Month enum提供了十几个预定义的对象,每年对应一个。 These enum objects are safer to use, but you can instead use a plain number for the month. 这些枚举对象使用起来更安全,但您可以使用月份的普通数字。 Unlike the legacy classes, these months have sane numbering, 1-12 for January-December. 与传统课程不同,这几个月有一个合理的编号,1月至12月为1-12。

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

The TemporalAdjuster interface provides for manipulation of date-time values. TemporalAdjuster接口提供对日期时间值的操作。 The TemporalAdjusters class (note the plural s ) provides several handy implementations. TemporalAdjusters类(注意复数s )提供了几个方便的实现。

The previous & next adjusters exclude the date itself from consideration. previousnext调整者不考虑日期本身。 The previousOrSame & nextOrSame methods return the date in question if it is indeed the desired day-of-week. previousOrSamenextOrSame方法返回有问题的日期,如果它确实是所需的星期几。

The DayOfWeek enum provides seven pre-defined objects, one for each day of the week. 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 ));

Dump to console. 转储到控制台。

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 ( Saturday ) localDate:2009-08-22(星期六)

previousSunday: 2009-08-16 previousSunday:2009-08-16

nextSunday: 2009-08-23 nextSunday:2009-08-23


About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参阅Oracle教程 And search Stack Overflow for many examples and explanations. 并搜索Stack Overflow以获取许多示例和解释。 Specification is JSR 310 . 规范是JSR 310

Where to obtain the java.time classes? 从哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目是未来可能添加到java.time的试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

From the Javadoc : 来自Javadoc

If there is any conflict in calendar field values, Calendar gives priorities to calendar fields that have been set more recently. 如果日历字段值中存在任何冲突,则日历会优先考虑最近设置的日历字段。 The following are the default combinations of the calendar fields. 以下是日历字段的默认组合。 The most recent combination, as determined by the most recently set single field, will be used. 将使用由最近设置的单个字段确定的最新组合。

For the date fields: 对于日期字段:

 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

I interpret this to mean that given that you're setting day of week, it will end up being combined with week of month or week of year in order to produce the actual date and time. 我认为这意味着,假设您正在设置星期几,它将最终与一周中的一周或一周中的一周相结合,以产生实际的日期和时间。

You should also check what is the first day in a week. 您还应该检查一周中的第一天。 I also thought it is always Sunday, but this depend on local settings, and in my case Monday is the first day in week. 我也认为它总是星期天,但这取决于当地的设置,在我的情况下,星期一是一周的第一天。 Setting Sunday as first day of the week fixed my problem. 将星期日设置为一周的第一天解决了我的问题。

Depends on the first day of the week: 取决于一周的第一天:

 /**
 * 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;
}

You can use like this method. 你可以使用这种方法。

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;
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM