Java8使用LocalDateTime获取正确的第几周和计算日期最佳方式

先上问题

public static void main(String[] args) {
        //使用DateTimeFormatter获取当前周数
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("w");
        //2018年第一天
        System.out.println(LocalDateTime.of(2018, 1, 1, 0, 0, 0).format(dateTimeFormatter));
        //2018年最后一天
        System.out.println(LocalDateTime.of(2018, 12, 31, 0, 0, 0).format(dateTimeFormatter));
        //2019年第一天
        System.out.println(LocalDateTime.of(2019, 1, 1, 0, 0, 0).format(dateTimeFormatter));
        //2019年最后一天
        System.out.println(LocalDateTime.of(2019, 12, 31, 0, 0, 0).format(dateTimeFormatter));
        //这天是星期六
        System.out.println(LocalDateTime.of(2019, 4, 6, 0, 0, 0).format(dateTimeFormatter));
        //这天是星期日
        System.out.println(LocalDateTime.of(2019, 4, 7, 0, 0, 0).format(dateTimeFormatter));
        //这天是星期一
        System.out.println(LocalDateTime.of(2019, 4, 8, 0, 0, 0).format(dateTimeFormatter));
    }

执行结果:

1
1
1
1
14
15
15

有没有发现很奇怪的一件事情,每年的最后1天和第1天居然都是第1周而且每周的第1天是周日!这明显不符合我们要获取的周数,正常的周数是每年最后1天是53周,第1天为第1周,每周从周一开始计算,那么为什么呢?

因为默认使用ISO8061 标准,该标准与我们所认知的周数计算并不一致所以导致了获取的周数不符合预期

ISO8061自然周
自然周的标准很多。其中以ISO8061 为准。
在这里插入图片描述

可以看到一年的第一个自然周应当满足:

1,有第一个星期四
2,包含1月4号
3,第一个自然周应当有4个或者4个以上的天数
4,这个星期开始的时间(即周一)在去年的12月29号(星期一)到今年的1月4号之间
所以如果1月1号是周一、周二、周三或者周四,它属于第一个自然周,如果不是,他属于去年的52周或者53周。

解决方案:

public static void main(String[] args) {
        //使用DateTimeFormatter获取当前周数
        WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY,1);
        //2018年第一天
        System.out.println(LocalDateTime.of(2018, 1, 1, 0, 0, 0).get(weekFields.weekOfYear()));
        //2018年最后一天
        System.out.println(LocalDateTime.of(2018, 12, 31, 0, 0, 0).get(weekFields.weekOfYear()));
        //2019年第一天
        System.out.println(LocalDateTime.of(2019, 1, 1, 0, 0, 0).get(weekFields.weekOfYear()));
        //2019年最后一天
        System.out.println(LocalDateTime.of(2019, 12, 31, 0, 0, 0).get(weekFields.weekOfYear()));
        //这天是星期六
        System.out.println(LocalDateTime.of(2019, 4, 6, 0, 0, 0).get(weekFields.weekOfYear()));
        //这天是星期日
        System.out.println(LocalDateTime.of(2019, 4, 7, 0, 0, 0).get(weekFields.weekOfYear()));
        //这天是星期一
        System.out.println(LocalDateTime.of(2019, 4, 8, 0, 0, 0).get(weekFields.weekOfYear()));
    }

执行结果:

1
53
1
53
14
14
15

此时结果已经符合预期,每周从周一开始且每年的第一天为第一周
如果有更好的方案欢迎留言交流

其他方案
如果按照每年的第N周计算周数,在1月1日非周日的情况下必然会有一周中包含两个周数会导致数据错乱
建议使用指定周数,即为当前时间-某个周一的相差周数

public static void main(String[] args) {
        LocalDateTime currentLocalDateTime = LocalDateTime.of(2019,12,16,0,0,0);
        LocalDateTime staticLocalDateTime = LocalDateTime.of(1900,1,1,0,0,0);
        //计算日期最佳方式
        //以下两种计算方式等价
        System.out.println(ChronoUnit.WEEKS.between(staticLocalDateTime,currentLocalDateTime)+1);
        System.out.println(staticLocalDateTime.until(currentLocalDateTime,ChronoUnit.WEEKS)+1);
    }

参考资料:java localdate获取自然周

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值