根据https://en.wikipedia.org/wiki/ISO_8601#Week_dates,工作日从星期一开始。但是,从Java中,如果您尝试以两种不同的方式提取星期数,那么如果日期是星期日,则会出现两种不同的输出。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class TestDate {
public static void main(String[] args) throws ParseException {
final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
final SimpleDateFormat weekFormatter = new SimpleDateFormat("ww");
String date = "2018-10-21";
System.out.println(weekFormatter.format(formatter.parse(date)));
Calendar calendar = Calendar.getInstance();
calendar.setFirstDayOfWeek(Calendar.MONDAY);
calendar.setTime(formatter.parse(date));
System.out.println(calendar.get(Calendar.WEEK_OF_YEAR));
}
}
输出:
43
42
这是前后矛盾吗?
这只是我编写的用于重现该问题的测试程序,我注意到Hive中的问题,如下所示:
0: jdbc:hive2://zk0-something> select from_unixtime(t, 'ww'), weekofyear(from_unixtime(t, 'yyyy-MM-dd')) from (select 1540122033 as t) a;
+------+------+--+
| _c0 | _c1 |
+------+------+--+
| 43 | 42 |
+------+------+--+
1 row selected (0.388 seconds)
0: jdbc:hive2://zk0-something>
答案 0 :(得分:4)
String date = "2018-10-21";
LocalDate ld = LocalDate.parse(date);
int weekOfYear = ld.get(WeekFields.ISO.weekOfYear());
System.out.println(weekOfYear);
输出:
42
由于您对ISO 8601规则for week numbers感兴趣,因此请使用WeekFields.ISO
从LocalDate
获取与星期相关的数据。如果您愿意,也可以使用formatter
DateTimeFormatter weekFormatter = DateTimeFormatter.ofPattern("ww", Locale.FRANCE);
System.out.println(ld.format(weekFormatter));
输出相同:
42
传递给DateTimeFormatter.ofPattern
的语言环境确定星期方案。如果我通过Locale.US
,则得到43。
我建议您使用现代Java日期和时间API java.time,并远离诸如SimpleDateFormat
和Calendar
之类的旧日期时间类。旧的设计欠佳,现代的则更好用。
过时的SimpleDateFormat
类和现代的DateTimeFormatter
都从其区域设置采用周编号方案。如果未为格式化程序指定语言环境,则它将使用JVM的默认语言环境。因此,例如,如果JVM具有美国语言环境,那么格式化程序将在您的第一个示例中显示43,因为在美国,今年10月21日,星期日是第43周。如果语言环境是法语,则它将打印42,因为那一天是星期几。 42在法国。法国遵循ISO 8601标准,美国未遵循。
在您的示例中,将Calendar
的一周的第一天设置为星期一会导致星期数像您期望的那样为42。但是,情况并非总是如此。周数不仅可以通过一周的第一天来定义,还可以通过周1的定义来定义。通过链接:
一年中的第一个ISO周最多可以有三天 实际上是在公历年结束如果它们是 星期一,星期二和星期三。同样,一年中的最后一个ISO周 可能最多有公历三天 开始的一年;如果是星期五,星期六和星期日。的 每个ISO周的星期四始终是公历年 用ISO周编号年份表示。
哪个星期是第1周的美国人定义是不同的:在美国,1月1日始终是第1周。因此,如果您的Calendar
是使用美国语言环境创建的,则将第一个星期的第一天设置为星期一足以遵循ISO 8601规则。巧合的是,尽管如此,2018年的周数还是一样。