Java计算日期在当月是第几周

  • 背景
  • Java LocalDate API
    • 每月第1个周一为该月第一周的做法
    • 每月1号为第一周做法

背景

公司项目需求是统计周报,一开始我的做法是按每月1号开始为第一周统计周报,比如2020-05-01到2020-05-03属于5月第一周,2020-05-04到2020-05-10为5月第二周。


产品小姐姐看了觉得不对,账单周报统计,是以一周7天为维度,如果按照上面的做法,统计出来5月第一周的周报只有3天,4月最后一周只有4天,这种不符合账单统计型产品的需求。
后面又拿出支付宝的周报账单给我看

看了看支付宝的做法,发现这是以每月第一个星期一作为这个月一周的开始。(好吧,原来这就是所谓的自然周,又得重写打标了)

第一步当然先去Google百度,但是找了一段时间都没有想要的,不是这个抄那个,就是太杂太乱。总之最后决定还是自己写这个逻辑了。

Java LocalDate API

每月第1个周一为该月第一周的做法

其实知道了规则之后,做法和思路很简单。

  • 获得日期的所在周的周一
  • 获得日期这个月的第一个周一
  • 根据两个周一判断是这个月的第几周
/*** 传入日期判断属于哪一年哪一月第几周** @apiNote 以每月的第一个周一所在的周作为每月第一周* @param date    时间格式(yyyyMMdd) 20200701* @return java.lang.String 返回字符串(2020-06-W5) 2020年6月第5周* @author kiring*/public String getWeekOfMonthByDay(int date){DateTimeFormatter dfDay = DateTimeFormatter.ofPattern("yyyyMMdd");LocalDate localDate = LocalDate.of(date / 10000, (date / 100) % 100, date % 100);// 获得当前日期的所在周的周一(previousOrSame:如果当前日期是周一,就返回当前日期)LocalDate localDateMondy = LocalDate.of(date / 10000, (date / 100) % 100, date % 100).with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));LocalDate firstMonday = null;// 获得这个月的第一个周一(这个月的第一周)for(int day=1; day<=7; day++){DayOfWeek dayOfWeek = LocalDate.of(date / 10000, (date / 100) % 100, day).getDayOfWeek();if(DayOfWeek.MONDAY == dayOfWeek){firstMonday = LocalDate.of(date / 10000, (date / 100) % 100, day);break;}}String outYear = null;String outMonth = null;String outWeek = null;// 根据两个周一判断是这个月的第几周if(firstMonday.isBefore(localDateMondy) || firstMonday.isEqual(localDateMondy)){//a. 如果当月第一个周一小于等于当前日期所在的周一outYear = localDateMondy.format(dfDay).substring(0,4);outMonth = localDateMondy.format(dfDay).substring(4,6);outWeek = String.valueOf((localDateMondy.toEpochDay() - firstMonday.toEpochDay())/7 + 1);return outYear + "-" + outMonth + "-" + "W" + outWeek;} else {//b. 如果当月第一个周一比当前日期所在的周一还要大// 计算上一个月最后一天所在周LocalDate lastMonthDate = localDate.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());Integer lastMonthDay = Integer.valueOf(lastMonthDate.format(dfDay));return getWeekOfMonthByDay(lastMonthDay);}}

这里注意考虑两个点,
一是传进来的日期如果刚好是周一的情况,
二是传来的日期如果是上一周的最后一周,也就是当月第一个周一大于当前日期所在的周一的情况,这里我直接使用的是递归来计算

每次传值进来来都会循环计算当月的第一个周一,读者可以自行做缓存处理。

每月1号为第一周做法

/*** 计算日期在月中的周* @param day  时间格式如:20200606* @return java.lang.Integer 日期在月中的周数* @author kiring*/public Integer calculateWeekInMonth(Integer day) {if(day < 19700101 || day > 99999999){throw new RuntimeException("时间不正确");}// ISO算法:每个月的第一周至少4天,如果小于4天,算出来是第0周// WeekFields weekFields = WeekFields.ISO;// 以周一作为一周的开始,每周至少一天WeekFields weekFields = WeekFields.of(DayOfWeek.MONDAY,1);int monthInWeek = LocalDateTime.of(day / 10000, (day / 100) % 100, day % 100, 0, 0, 0).atZone(ZoneOffset.ofHours(8)).get(weekFields.weekOfMonth());return monthInWeek;}

计算日期在当月是第几周-【自然周(每月第一个周一为该月第一周)做法以及1号为第一周做法】相关推荐

  1. PLSQL计算日期是当月第几周

    网上查询的方法都是这个: SELECT TO_CHAR (p_date, 'W') INTO v_week FROM DUAL; 它实际上是星期N在当月第几次出现. 如本月的第1天是个周四,那么为个月 ...

  2. JAVA 计算日期属于当月第几周(日期周计算)

    计算日期属于当月第几周(日期周计算) 本文周计算时间方式为:当月第一个周一为第一周 计算 获取月第一个周一.从当月第一天开始找 第一个周一时间与 sourceTime [传入时间对比],sourceT ...

  3. java 根据星期计算日期_Java 根据指定日期计算所在周的周一和周日

    标签:public static void main(String[] args) throws ParseException { SimpleDateFormat sdf=new SimpleDat ...

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

    先上问题 public static void main(String[] args) {//使用DateTimeFormatter获取当前周数DateTimeFormatter dateTimeFo ...

  5. PostgreSQL 当月最后一天的工作日 , 计算日期是星期几

    可以用pg自带函数select extract(dow from current_date),之所以没用主要是展示一下通过数学方法计算日期的原理. drop function if exists ge ...

  6. cursor is oracle 日期_Oracle时间计算------日期格式参数含义说明

    Oracle时间计算------日期格式参数含义说明 D 一周中的星期几 DAY 天的名字,使用空格填充到9个字符 DD 月中的第几天 DDD 年中的第几天 DY 天的简写名 IW ISO标准的年中的 ...

  7. Excel函数之~计算日期、天数、星期

    计算日期.天数.星期的函数 1.EDATE 2.EOMONTH 3.WORKDAY 4.NETWORKDAYS 5.DATEDIF 6.YEARFRAC 7.WEEKNUM 1.EDATE 函数定义: ...

  8. MySQL排除节假日,计算日期差

    需求 计算两个日期的差,并且需要排除节假日. 首先,我们需要准备一张节假日表,存放一年里所有的周末和法定节假日. 实现下面两个需求: 1.通过主表的两个日期字段,去计算这两个字段的日期差值: 2.传入 ...

  9. oracle中datepart函数,Asp DatePart 函数的语法详解(用于计算日期并返回指定的时间间隔)...

    Asp DatePart 函数的语法详解(用于计算日期并返回指定的时间间隔) 更新时间:2012年07月31日 21:32:58   作者: ASP(VBScript) 参考手册中,已经对 DateP ...

  10. (C++)设计一个程序能计算一个日期加上若干天后是什么日期and计算日期差值

    输入第一行表示样例个数m,接下来m行每行四个整数分别表示年月日和累加的天数. 输出m行,每行按yyyy-mm-dd的个数输出. #include<cstdio>//判断是否是闰年 bool ...

最新文章

  1. html5 文字定义线宽,html 5画布线宽
  2. android adb端口被占用问题解决办法
  3. 【codeforces 807C】Success Rate
  4. MatConvnet工具箱文档翻译理解(4)
  5. python 网站发送验证码_Python爬虫模拟登录带验证码网站
  6. python模拟登录淘宝直通车_Python实现的淘宝直通车数据抓取(1)
  7. 聊天机器人-ChatterBot初试
  8. 在C++中,你真的会用new吗?
  9. Java语言程序设计(基础篇) 第十一章 继承和多态
  10. [转载] Python 内置函数 lambda、filter、map、reduce
  11. Ceph Monitor基础架构与模块详解
  12. Linux实战教学笔记
  13. php小米官网,小米商城的首页
  14. automation服务器不能创建对象的终极解决办法!
  15. android tee os,有关OP-TEE - 中文社区论区 - 中文社区 - Arm Community
  16. 湖南大学计算机博士好考吗,湖南大学最年轻的副教授是什么水平
  17. 论文翻译 | TOOD:《TOOD: Task-aligned One-stage Object Detection》详细解读
  18. 计算机专业该如何学习:准大一篇
  19. 大调查:7成网友呼吁共享单车免押金和上保险
  20. 视频超分:TGA(Video Super-resolution with Temporal Group Attention)

热门文章

  1. 牛血清白蛋白包裹氧化锌纳米粒
  2. 深圳中院判决:利用网络爬虫技术抓取他人数据构成不正当竞争
  3. C语言中 两个分号啥意思,问什么C程序里总是提示缺少分号;,而明明有分号?...
  4. 芝麻信用接口 java_java 对接芝麻信用 -用芝麻私钥解密错误
  5. BDF2各模块依赖关系
  6. python打印支票_转账支票、现金支票日期大写对照表(数字大写)
  7. 带数据库html5游戏教程,html5学习之旅-html5的简易数据库开发(18)-H5教程
  8. matlab中的小于等于,ps中如何画出小于等于符号
  9. 图片怎么转换到Excel表格?偷偷安利一个好用的方法
  10. Ubuntu下安装网易有道词典