我正在测试我们的日期管理框架,它应该重置一些Calendar字段(使用actual minimum)。
但是,当changing first day of week时,Calendar总是将SUNDAY(1
)作为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));
}
}
}
答案 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的例子)