[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[日期时间] 批处理日期转数字,数字转日期

日期转数字思路:每一年的天数累加。
     公式:年数 x 365 + 闰年多出的天数 + M月D日的当年天数

核心算法同:批处理计算给定日期(年月日)是星期几
http://bbs.bathome.net/thread-57642-1-1.html
  1. ::日期转数字函数date2num
  2. @echo off
  3. setLocal enableDelayedExpansion
  4. ::日期变数字  2021-01-23:737813
  5. set idate=2021-01-23
  6. set fdate=%idate:-=%
  7. call :date2num fdate nday
  8. echo 日期 %idate% 对应数字 %nday%
  9. pause
  10. goto :eof
  11. ::====完====
  12. ::计算日期的天号。参数YYYYMMDD,输出num
  13. :date2num formatdate index
  14. setlocal
  15. set "fdate=!%1!"
  16. set/a y=1%fdate:~,4%-10000,m=1%fdate:~4,2%-100,d=1%fdate:~6,2%-100
  17. set/a y1=y-1,m3=(m-1)*3
  18. set/a "leap=^!(y%%4)&^!^!(y%%100)|^!(y%%400)",T2=28+leap
  19. set Mdays=+31+T2+31+30+31+30+31+31+30+31+30+31
  20. set/a days=d!Mdays:~,%m3%!
  21. set/a nday=y1/4-y1/100+y1/400+y1*365+days
  22. endlocal&set %2=%nday%
  23. goto :eof
复制代码
这个相对简单些,直接转成函数形式了。

假设当前历法不变(假设很重要)!计算是从0001-01-01为第1天开始。

set/a nday=(y1/4-y1/100+y1/400)+y1*365+days
nday为天数,y为年,days为月日代表的天数;
y1/4-y1/100+y1/400 红色的为闰年数,即每个闰年比365多出的天数;
y1*365 就是粗算的年转天数。
如无特别说明,代码测试环境均为 XP SP3

本帖最后由 cutebe 于 2021-2-20 11:17 编辑

数字转日期思路:数字按一年一年天数递减,年累加;多出的不足一年的天数换算成月份和日号。
     加速:一年一年加循环次数太多,会很慢。先预估一个大致年数,循环可减少2个量级。

也是假定当前历法不变!数字也是从0001-01-01为第1天开始算起。
  1. ::数字转日期
  2. @echo off
  3. setLocal enableDelayedExpansion
  4. :input        输入
  5. ::set/a num=737840 %_2021-02-19%
  6. set/p num=输入数字:
  7. ::计算年月日
  8. set/a n=num,year=1,y=n/366 %_估算年_%
  9. set/a ny=y/4-y/100+y/400+y*365,y+=year,n-=ny
  10. :iyear 精算年份。                //多出的天一年一年加入,减少循环次数
  11. call :Lyear n y flag leap
  12. if %flag%==0 goto :mday
  13. set/a y+=flag,n-=365+leap
  14. goto :iyear
  15. :mday 计算几月几日。        //leap在最后一次调用:Lyear函数时得出
  16. set/a T2=28+leap,m=1,d=n
  17. set Mdays=+31+T2+31+30+31+30+31+31+30+31+30+31
  18. for /l %%m in (36,-3,3)do (
  19.         set/a days=0!Mdays:~,%%m!
  20.         if %n% gtr !days! set/a m+=%%m/3,d=n-days&goto :outfor
  21. )
  22. :outfor
  23. ::显示结果
  24. echo/  转换成日期 %y%年 %m%月 %d%日
  25. echo/
  26. goto :input
  27. ::====完====
  28. ::根据数字年号判断是否加一年及闰年
  29. :Lyear num year flagYearAdd leap
  30. setlocal
  31. set/a n=%1,y=%2
  32. set/a "leap=^!^!(y%%100)&^!(y%%4)|^!(y%%400)"
  33. set/a ty=365+leap,fy=0
  34. if %n% gtr %ty% set fy=1
  35. endlocal&set %3=%fy%&set %4=%leap%
  36. goto :eof
复制代码
核心算法说明:
set/a y=n/366        //估算年份,选用366是因为所有年份≤366天,除得的商会小于实际年数方便后面计算;
set/a ny=(y/4-y/100+y/400)+y*365    //前面的估年不准确,这里是估算年份之前的 精确天数;
:iyear 循环        //得到精确天数后,把剩余天数超过整年的部分累加到年数里;
:mday 标号下方代码        //最后剩下的不足整年的分配到月日中,算法是 给定年月日计算星期几 的逆运算,即通过月份之前天数与剩余天数对比 来获取月份。
year 函数        //判断数字是否超过一年,及当年是否闰年

数字转日期函数:num2date
  1. ::数字转日期函数num2date
  2. @echo off
  3. setLocal enableDelayedExpansion
  4. ::set/a num=3652059 %_最大数_%
  5. set/a num=737840 %_2021-02-19%
  6. call :num2date num xdate
  7. set sdate=%xdate:~,4%-!xdate:~4,2!-%xdate:~6%
  8. echo/  数字%num% 转换成日期 %sdate%
  9. pause
  10. goto :eof
  11. ::====完====
  12. ::计算数字对应的日期。参数num,输出YYYYMMDD;调用函数Lyear数字是否超过一年及闰年
  13. :num2date num fdate
  14. setlocal
  15. set/a n=%1,year=1,y=n/366 %_估年_%
  16. set/a ny=(y/4-y/100+y/400)+y*365,y+=year,n-=ny
  17. :iyear 精算年份。                //多出的天一年一年加入
  18. call :Lyear n y flag leap
  19. if %flag%==0 goto :mday
  20. set/a y+=flag,n-=365+leap
  21. goto :iyear
  22. :mday 计算几月几日。        //leap在最后一次调用:Lyear函数时得出
  23. set/a T2=28+leap,m=1,d=n
  24. set Mdays=+31+T2+31+30+31+30+31+31+30+31+30+31
  25. for /l %%m in (36,-3,3)do (
  26.         set/a days=0!Mdays:~,%%m!
  27.         if %n% gtr !days! set/a m+=%%m/3,d=n-days&goto :outfor
  28. )
  29. :outfor
  30. set/a fy=10000+y,fm=100+m,fd=100+d
  31. set fdate=%fy:~-4%!fm:~-2!%fd:~-2%
  32. endlocal&set %2=%fdate%
  33. goto :eof
  34. ::根据数字年号判断是否加一年及闰年
  35. :Lyear num year flagYearAdd leap
  36. setlocal
  37. set/a n=%1,y=%2
  38. set/a "leap=^!^!(y%%100)&^!(y%%4)|^!(y%%400)"
  39. set/a Ydays=365+leap,fy=0
  40. if %n% gtr %Ydays% set fy=1
  41. endlocal&set %3=%fy%&set %4=%leap%
  42. goto :eof
复制代码
如无特别说明,代码测试环境均为 XP SP3

TOP

返回列表