如何使用日历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做到这一点,因此使用其他库是不是一个解决方案。
检查日历的Java 6的发布提问values of Constants in Calendar
Calendar.SUNDAY的值是1的美国地区之前的Javadoc。
Calendar.SUNDAY的值始终相同,它不会因区域设置而更改。 –
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类?
-
Java SE 8,Java SE 9,后来
- 内置。
- 带捆绑实现的标准Java API的一部分。
- Java 9增加了一些次要功能和修复。在ThreeTen-Backport
-
Java SE 6和Java SE 7
- 大部分的java.time功能后移植到Java 6 & 7。
-
Android
- 的ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 请参阅How to use ThreeTenABP…。
的ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval
,YearWeek
,YearQuarter
和more。
当然,你是对的。没有枚举,常量。我已经根据这个改变了答案。 – Maia