如何使用日历API获取ISO日期

如何使用日历API获取ISO日期

问题描述:

我想使用Calendar API获取ISO日的一周,但它会返回错误的日期编号。如何使用日历API获取ISO日期

周日是一周的最后一天,应该是数从ISO标准,与周一是第一天为1号。

但运行下面的代码为周日(2017-07 -30)正在重新调整我的号码。 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

我尝试使用约达时间,它工作得很好,但我需要使用日历和Java 6做到这一点,因此使用其他库是不是一个解决方案。

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

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

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

+0

当然,你是对的。没有枚举,常量。我已经根据这个改变了答案。 – Maia

检查日历的Java 6的发布提问values of Constants in Calendar

Calendar.SUNDAY的值是1的美国地区之前的Javadoc。

+0

Calendar.SUNDAY的值始终相同,它不会因区域设置而更改。 –

+0

Calendar.sunday不会由语言环境更改,而会根据语言环境更改为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.) 

详细信息

accepted answer by Maia是正确的:Those int constants on Calendar定义一周为1-7为Sunday-星期六,根据美国的习俗。

DAY_OF_WEEK

公共静态最终诠释DAY_OF_WEEK

场数get和set表示星期几。该字段的值为星期日,星期一,星期二,星期三,星期四,星期五和星期六。

如果你绝对不能添加一个图书馆,那么你必须从一个星期是星期日至星期六1-7的Calendar定义调整。把钱放在第一位,减去1,然后检查你添加的0。

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

但不要考虑添加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年7月30日

dow.toString():星期日

dowNumber:7

输出:星期日


关于java.time

java.time框架内置于Java 8及更高版本。这些类取代了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore