根据日期获取所在周数-原理篇

发布时间 2023-10-11 17:49:37作者: 元宇宙的元

1. 谁是每周的第1天?

1.1 以 周日 为每周的第1天

根据《圣经·创世纪》,上帝是星期一到星期六创造了世界,星期日休息,所以犹太教和基督教星期日要做礼拜,这一天他们叫做“礼拜日”,而一周七天称“一个礼拜”。

敬神这样的事情自然要优先,所以放在每星期的第一天来做,于是星期日也就是每周的第一天了。

1.2 以周一为每周的第1天

但宗教的影响江河日下,后来大家逐渐开始接受周一(Monday)作为每周第一天,因为周一(Monday)是每周第一个工作日,无论是从人的主观体验还是工作安排来说,用Monday作为每周第一天是更直观的。

现在国际标准 ISO8601 《数据存储和交换形式·信息交换·日期和时间的表示方法》中,已经把Monday作为每周第一天了。大多数欧洲国家,包括英国,也普遍采用了国际标准,我国的国家标准 GB/T 7408-2005 也规定了周一是每周的第一天。

2. 每年的第1周从何算起?

2.1 元旦所在周是每年的第1周吗?

不一定。

image-20231011155228437

拿上图举例,2022-01-01属于2021年的最后一周,并不属于2022年的第一周。

但是将时间往前选一下,切换到2020年,则情况马上发生了变化:2020年的元旦就是2020年的第一周。

image-20231011160749913

2.2 每年的第1周究竟从何算起?

有个规则:看当前年份在当前周内是否占有4天及以上。

比如某一周A,2019年占了3天而2020年占了4天,那么这一周就属于2020年,即新一年的第一周。

又比如另一周B,2021年占了5天而2022年只占2天,那么这一周就属于2021年,即旧一年的最后一周。

好了,规则搞清楚了我们开始用代码实现。

3. 根据日期计算所在周数

    /**
     * 每年第一周的判断条件:第一次并且在本周内至少有4天以上是当前年份的日期
     */
    static int MINIMAL_DAYS_IN_FIRST_WEEK = 4;

    /**
     * 根据日期计算所在周数
     * @param date 日期
     * @return 所在周数
     */
    public static int calcWeekOfYear(Date date) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        // 周一作为每周的第一天
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        // 每年第一周的判断条件:第一次并且在本周内至少有4天以上是当前年份的日期
        calendar.setMinimalDaysInFirstWeek(MINIMAL_DAYS_IN_FIRST_WEEK);
        calendar.setTime(date);
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

2020-01-01 调用一下试试看

    public static void main(String[] args) {
        try {
            String today = "2020-01-01";
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date date = format.parse(today);
            int num = calcWeekOfYear(date);
            System.out.println(today + " 是一年中的第 " + num + " 周");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

输出结果 第1周

2020-01-01 是一年中的第 1 周

换个日期 2022-01-01,结果是 第52周(前一年的第52周)

2022-01-01 是一年中的第 52 周