nttwqz 发表于 2023-9-6 22:26:56

【批处理】一行代码的昨天日期计算

主要算法就一行,代码来自网络,年代久远,作者未知,非本人编写!

@echo off
set/a D=1%date:~8,2%%%100-1,M=1%date:~5,2%%%100-!D,Y=%date:~0,4%-!M,M+=!M*12,"K=!(M-4)|!(M-6)|!(M-9)|!(M-11)","D+=!D*(!(M-2)*(28+!(Y%%4))+K*30+(!!(M-2)&!K)*31)"
set M=0%M%&set D=0%D%
echo;%Y%-%M:~-2%-%D:~-2%&pause


chiannet 发表于 2023-9-7 00:19:40

本帖最后由 chiannet 于 2023-9-7 00:31 编辑

@Echo Off


For /f "Tokens=1-3 Delims=/ " %%I In ('Echo %Date:-=/%') Do Set TT=%%I-%%J-%%K

Call :DateDiff %TT% -2 T
echo 前天%T%

Call :DateDiff %TT% -100 T
echo 100天前是%T%

Call :DateDiff %TT% 9999 T
echo 9999天后的日期%T%借花献佛

dayeye 发表于 2023-9-7 00:50:06

借花献佛

batche 发表于 2023-9-7 00:53:51

本帖最后由 batche 于 2023-9-7 00:55 编辑

感谢分享,好算法,把润平年、大小月、跨年跨月都考虑进去了。
我尝试理解一下:
%date%是形如"yyyy(分隔符)MM(分隔符)DD"的日期格式,因为截取方式和计算方法的原因其他格式不行。
D=1%date:~8,2%%%100-1,截取日期,模100取余是为了处理0开头的日期,比如把08变成8,
然后把日期减一,遗憾的是它只能减一,因为D不能为负,也可以改但就不能跨了;
M=1%date:~5,2%%%100-!D,前面一样,最后-!D是处理跨月,当D为0时!D为1,即月份减一;
Y=%date:~0,4%-!M,同理,这是处理跨年的年份的;
M+=!M*12,这是处理跨年的月份的,当M为0时!M为1,月份为12;
年月份确定了,后面是计算日期的,
K=!(M-4)|!(M-6)|!(M-9)|!(M-11),当月份为1、2、3、5、7、8、10、12时,k为0;
D+=!D*(!(M-2)*(28+!(Y%%4))+K*30+(!!(M-2)&!K)*31),这里比较复杂,
当原来的D不为0时,即不跨年跨月时,D不变;
(!(M-2)*(28+!(Y%%4)),!(Y%%4)是判断闰年,闰年为1否则为0,!(M-2)是判断是否2月,闰年2月29天,平年28天,不是2月表达式为0不影响D;
K*30,月份4、6、9、11,k为1,30天,否则表达式为0不影响D;
(!!(M-2)&!K)*31),当月份为1、3、5、7、8、10、12时,31天。

megatron 发表于 2023-9-7 04:19:52

对于编程是一窍不通

5962903 发表于 2023-9-7 06:19:11

算法就一行

martin313 发表于 2023-9-7 06:36:54

路过学习
奉行拿来主义

yyz2191958 发表于 2023-9-7 07:38:32

进来学习

dx163 发表于 2023-9-7 09:17:28

向好学的坛友致敬

创新科技2015 发表于 2023-9-7 09:53:27

谢谢分享!

dfdfdfdf99 发表于 2023-9-7 10:31:25

学习学习,谢谢分享。

nttwqz 发表于 2023-9-7 11:12:42

batche 发表于 2023-9-7 00:53
感谢分享,好算法,把润平年、大小月、跨年跨月都考虑进去了。
我尝试理解一下:
%date%是形如"yyyy(分隔 ...

作者灵活运用了一元运算,省去了一堆条件判断。

话说,睡的挺晚啊……

nttwqz 发表于 2023-9-7 11:25:14

megatron 发表于 2023-9-7 04:19
对于编程是一窍不通

这个其实和编程没什么关系,主要还是要数学好,就是灵活运用了一元运算符的数学公式。

!0=1
!1=0

0|0=0
0|1=1
1|1=1

0&0=0
0&1=0
1&1=1

yc2428 发表于 2023-9-7 11:31:10

谢谢分享!

wmjm 发表于 2023-9-7 11:37:19

学习一下,谢谢

12315sa 发表于 2023-9-7 13:06:27

谢谢分享

Climbing 发表于 2023-9-7 15:31:06

chiannet 发表于 2023-9-7 00:19
借花献佛

你这个核心应该是datediff啊,没有啊。https://cdn.jsdelivr.net/gh/master-of-forums/master-of-forums/public/images/patch.gif

ppll2030 发表于 2023-9-8 00:28:06

batche 发表于 2023-9-7 00:53
感谢分享,好算法,把润平年、大小月、跨年跨月都考虑进去了。
我尝试理解一下:
%date%是形如"yyyy(分隔 ...

感谢解析。{:1_195:}

batche 发表于 2023-9-8 00:56:45

nttwqz 发表于 2023-9-7 11:12
作者灵活运用了一元运算,省去了一堆条件判断。

话说,睡的挺晚啊……

是很巧妙,我本以为会很复杂,但作者利用日期从1开始的特殊性,适用于计算昨天日期,利用取非就分开了跨年跨月,然后就只要判断月份就知道日期了。不过日期加减很多天还是很复杂,我尝试了一下还是弄不出来。

yjstone 发表于 2023-9-8 13:34:53

思路真的是极为巧妙,跪拜了!也多谢batche的解读,要不真的要研究很久才弄得懂。

CYYspace 发表于 2023-9-8 21:24:30

感谢分享

dfdfdfdf99 发表于 2023-9-9 14:02:12

感谢分享

bg888 发表于 2023-9-9 14:34:13

为什么不用 echo %date% 呢,出来今天的日期,不就知道昨天的日期了

yjstone 发表于 2023-9-9 17:53:29

bg888 发表于 2023-9-9 14:34
为什么不用 echo %date% 呢,出来今天的日期,不就知道昨天的日期了

知道昨天日期是一回事,用电脑自动处理又是另一回事了。

pda8888 发表于 2023-9-11 14:03:25

在windows 11 22h2 2134 命令行下,报错:
运算符不存在。
-01-00
请按任意键继续. . .

nttwqz 发表于 2023-9-11 18:57:16

pda8888 发表于 2023-9-11 14:03
在windows 11 22h2 2134 命令行下,报错:

仅适用于默认日期格式

yyz2191958 发表于 2023-9-16 19:21:17

有什么用?

窄口牛 发表于 2023-9-19 15:00:37

pda8888 发表于 2023-9-11 14:03
在windows 11 22h2 2134 命令行下,报错:

不要开启变量延迟

2012myjoys 发表于 2023-9-20 17:20:30

然而有啥用处呢

DarlingC 发表于 2023-9-22 14:49:57

看着好难
页: [1] 2
查看完整版本: 【批处理】一行代码的昨天日期计算