Board logo

标题: [日期时间] 批处理计算给定日期(年月日)是星期几,是当年第几周 [打印本页]

作者: cutebe    时间: 2021-1-22 23:46     标题: 批处理计算给定日期(年月日)是星期几,是当年第几周

星期公式
(上年\4-上年\100+上年\400+上年+当年第几天)%7=

  1. @echo off
  2. setLocal enableDelayedExpansion
  3. :begin
  4. ::set idate=2021-01-23
  5. ::set idate=%date%
  6. set/pidate=请输入日期(YYYY-MM-DD):
  7. set idate=%idate:+=%
  8. set idate=%idate:-=%
  9. set idate=%idate:/=%
  10. set idate=%idate:.=%
  11. set idate=%idate: =%
  12. set/a y=1%idate:~,4%-10000
  13. set/a m=1%idate:~4,2%-100
  14. set/a d=1%idate:~6,2%-100
  15. set/a y1=y-1,m3=(m-1)*3
  16. ::开启变量延迟后,非运算符!要用^转义:^!
  17. set/a "leap=^!(y%%4)&^!^!(y%%100)|^!(y%%400)",t2=28+leap
  18. set E=+31+t2+31+30+31+30+31+31+30+31+30+31
  19. set/a t=0!E:~,%m3%!+d,ty=0%E%
  20. set/a w=(y1/4-y1/100+y1/400+y1+t)%%7
  21. set/a w0=(y1/4-y1/100+y1/400+y1)%%7,z=(w0+t+(7-w)%%7)/7
  22. set ytype=平闰
  23. echo/ %y%是!ytype:~%leap%,1!年,有%ty%天;
  24. set week=天一二三四五六
  25. echo/ %y%-%m%-%d%是周!week:~%w%,1!,是当年第%z%周。
  26. echo/
  27. goto :begin
  28. goto :eof
  29. 星期公式:
  30. (上年\4-上年\100+上年\400+上年+当年第几天)%7=
  31. 测试
  32. 2021-01-21
  33. (505-20+5+2020+21)%7=4 4
  34. 2013-04-08 31+28+31+8=98
  35. (503-20+5+2012+98)%7=1 1
  36. 2012-03-06 31+29+6=66
  37. (502-20+5+2011+66)%7=2 2
复制代码


星期计算原理
一个星期有七天,周而复始,循环往复。
假定现有历法不变,往前推公元元年1月1号(即0001-01-01起始)是星期一。
基于以上假设,要计算星期数,只要计算从公元起始经过了多少天,对7取余数就是星期几了!!

思考:如果知道某年1月1号是星期几,要计算当年另一个日期的星期是不是可行呢?

因为星期是周而复始的,过去的每一年天数也是固定的,我们不用每天都统计,可以简化。
每年有365或366天,平年365正好是52周多1天,因此每年1月1号的星期数是之前一年+1,闰年后面讨论。
年数是就往年去掉整周后多出来的天数,每遇到一个闰年再+1,因为闰年是52周多2天。
闰年数量是:能整除4-能整除100+能整除400。
因此星期数就是:往年年数+闰年数+当年的日期天数,对7取余数可得!

简单来说就是把以往各年非整周的剩余天数累加,再加上当年天数来除以七
平年余数累积1天,闰年累积2天。

星期计算步骤
1、判断闰年leap(1闰0平);y为年
set/a "leap=!(y%%4)&!!(y%%100)|!(y%%400)"
2、计算2月天数t2
set/a t2=28+leap
3、计算指定日期是当年第几天t;m为月,d为日
set/a m3=(m-1)*3
set E=+31+t2+31+30+31+30+31+31+30+31+30+31        //基于余数思想,这句是不是也可以简化缩短?
set/a t=0!E:~,%m3%!+d
4、计算星期w(0为周日);y1为上一年
set/a w=(y1/4-y1/100+y1/400+y1+t)%%7

注:基姆拉尔森计算公式中部分参数的含义不易理解。所以自己写了个一天一天累加的方法,原理比较简单易懂!

第几周计算原理与步骤就留给大家思考吧^_^
作者: cutebe    时间: 2021-1-22 23:48

本帖最后由 cutebe 于 2021-1-22 23:50 编辑

计算星期的做成函数
  1. ::计算指定日期是星期几,函数:weekday
  2. @echo off
  3. setLocal enableDelayedExpansion
  4. set idate=%date%
  5. call :picknum idate today
  6. call :weekday today wd
  7. echo/ 今天是周%wd%
  8. set idate=2021-01-23
  9. set fdate=%idate:-=%
  10. call :weekday fdate wd
  11. set week=天一二三四五六
  12. echo/ %idate%是星期!week:~%wd%,1!
  13. pause
  14. goto :eof
  15. ::提取字串中的数字
  16. :picknum str numstr
  17. setlocal
  18. set "str=!%1!"
  19. for /l %%n in (0,1,9)do set _%%n=1
  20. :_picknext
  21. if defined _%str:~,1% set num=%num%%str:~,1%
  22. set str=%str:~1%
  23. if not "%str%"=="" goto :_picknext
  24. endlocal&set %2=%num%
  25. goto :eof
  26. ::计算日期的星期。参数YYYYMMDD,输出0-6
  27. :weekday formatdate dayofweek
  28. setlocal
  29. set "fdate=!%1!"
  30. set/a y=1%fdate:~,4%-10000,m=1%fdate:~4,2%-100,d=1%fdate:~6,2%-100
  31. set/a y1=y-1,m3=(m-1)*3
  32. set/a "leap=^!(y%%4)&^!^!(y%%100)|^!(y%%400)",T2=28+leap
  33. set daysofmonth=+31+T2+31+30+31+30+31+31+30+31+30+31
  34. set/a daysnum=0!daysofmonth:~,%m3%!+d
  35. set/a wday=(y1/4-y1/100+y1/400+y1+daysnum)%%7
  36. endlocal&set %2=%wday%
  37. goto :eof
复制代码

作者: cutebe    时间: 2021-1-22 23:54

计算第几周的也做成函数
  1. ::计算指定日期是当年第几周,函数:weekord
  2. @echo off
  3. setLocal enableDelayedExpansion
  4. set idate=%date%
  5. call :picknum idate today
  6. call :weekord today wo
  7. echo/ 今天是今年第%wo%周
  8. set idate=2021-01-23
  9. set fdate=%idate:-=%
  10. call :weekord fdate wo
  11. echo/ %idate%是当年第%wo%周
  12. pause
  13. goto :eof
  14. ::提取字串中的数字
  15. :picknum str numstr
  16. setlocal
  17. set "str=!%1!"
  18. for /l %%n in (0,1,9)do set _%%n=1
  19. :_picknext
  20. if defined _%str:~,1% set num=%num%%str:~,1%
  21. set str=%str:~1%
  22. if not "%str%"=="" goto :_picknext
  23. endlocal&set %2=%num%
  24. goto :eof
  25. ::计算日期是当年第几周。参数YYYYMMDD,输出1-54
  26. :weekord formatdate weekordinal
  27. setlocal
  28. set "fdate=!%1!"
  29. set/a y=1%fdate:~,4%-10000,m=1%fdate:~4,2%-100,d=1%fdate:~6,2%-100
  30. set/a y1=y-1,m3=(m-1)*3
  31. set/a "leap=^!(y%%4)&^!^!(y%%100)|^!(y%%400)",T2=28+leap
  32. set daysofmonth=+31+T2+31+30+31+30+31+31+30+31+30+31
  33. set/a daysnum=0!daysofmonth:~,%m3%!+d,daysmore=y1/4-y1/100+y1/400+y1
  34. set/a wday0=daysmore%%7,wday=(daysmore+daysnum)%%7
  35. set/a weeko=(wday0+daysnum+(7-wday)%%7)/7
  36. endlocal&set %2=%weeko%
  37. goto :eof
复制代码

作者: Batcher    时间: 2021-1-24 19:35

感谢分享!
有兴趣的朋友也可以参考另外几个例子:日期、星期、时间等
http://bbs.bathome.net/thread-3056-1-1.html
作者: jave000    时间: 2022-3-4 11:34

win10不支持weekord么,无法显示第几周
作者: jave000    时间: 2022-3-4 11:48

本帖最后由 jave000 于 2022-3-4 11:55 编辑

我需要根据当前周数创建对应文件夹,这个参数不支持的样子

The system cannot find the batch label specified - picknum
The system cannot find the batch label specified - weekday
作者: Batcher    时间: 2022-3-4 12:54

回复 6# jave000


批处理函数库里面有计算日期、星期、时间等实例
http://bbs.bathome.net/thread-3056-1-1.html

请参考Q-01观察一下哪行代码在报错以及详细的报错信息:
https://mp.weixin.qq.com/s/6lbb97qUOs1sTyKJfN0ZEQ




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2