java日期库中一年中的一周不一致

piwo6bdm  于 2021-06-27  发布在  Hive
关注(0)|答案(1)|浏览(408)

根据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>
r3i60tvu

r3i60tvu1#

java.time文件

String date = "2018-10-21";
    LocalDate ld = LocalDate.parse(date);
    int weekOfYear = ld.get(WeekFields.ISO.weekOfYear());
    System.out.println(weekOfYear);

输出:
42
由于您对iso 8601周数规则感兴趣,请使用 WeekFields.ISO 用于从 LocalDate . 如果您喜欢,也可以使用格式化程序:

DateTimeFormatter weekFormatter = DateTimeFormatter.ofPattern("ww", Locale.FRANCE);
    System.out.println(ld.format(weekFormatter));

输出相同:
42
区域设置传递给 DateTimeFormatter.ofPattern 确定周方案。如果我通过 Locale.US 相反,我得到43分。
我建议您使用java.time,即现代的java日期和时间api,不要使用像这样的旧日期时间类 SimpleDateFormat 以及 Calendar . 旧的设计很差,现代的更好用。

你的代码哪里出错了?

都是过时的 SimpleDateFormat 阶级与现代 DateTimeFormatter 从他们的区域设置中获取他们的周编号方案。如果没有为格式化程序指定区域设置,它将使用jvm的默认区域设置。因此,如果jvm具有美国语言环境,例如,格式化程序将在第一个示例中打印43,因为在美国,今年10月21日星期日是第43周。如果区域设置是法语,它将打印42,因为那天是在法国的第42周。法国遵循iso 8601标准,美国则不遵循。
在您的示例中,设置 Calendar 的一周中的第一天到星期一将使周数如您所预期的那样为42。然而,情况并非总是如此。周数不仅由一周的第一天定义,而且由第一周的定义来定义。从您的链接:
一年中的第一个iso周最多可以有三天,实际上是在公历年结束时;如果是星期一、星期二和星期三。类似地,一年的最后一周可能有三天实际上是在公历年开始的;如果是星期五、星期六和星期天。每个iso周的星期四总是在公历年中,由iso周编号年份表示。
美国人对哪一周是第一周的定义是不同的:在美国,一月一日总是在第一周。因此如果你的 Calendar 是用美国语言环境创建的,将一周的第一天设置为星期一不足以使它遵循iso 8601规则。巧合的是,2018年的周数一致。

相关问题