Board logo

标题: 【挑战】利用批处理命令findstr判断输入日期的合法性 [打印本页]

作者: batman    时间: 2011-5-29 15:43     标题: 【挑战】利用批处理命令findstr判断输入日期的合法性

要求:
  编写纯批处理对输入的日期进行合法性判断

  必须用且只能用一次findstr进行判断,模式为echo %str%|findstr

      请对代码进行简要的说明,至少讲清楚你的思路


  合法性:

    1、输入为8个纯数字,如:20100529(yyyymmdd)

    2、年份为1000-3000年,允许对平闰年进行计算判断

    3、月份合理性判断

    4、日期合理性判断,特别注意对2月日期的判断
附截图如下:
[attach]3863[/attach]全部合格[attach]3870[/attach]少位数字
[attach]3864[/attach]日期超出[attach]3865[/attach]月份超出
[attach]3866[/attach]日期超出[attach]3867[/attach]年份超出
[attach]3868[/attach]多位数字[attach]3869[/attach]日期超出
作者: abcdshenji    时间: 2011-5-29 18:28

本帖最后由 abcdshenji 于 2011-5-29 18:37 编辑
  1. @echo off||检查日期合法性(yyyymmdd)
  2. :top
  3. cls
  4. set /p dt=Enter date:
  5. echo %dt%|findstr "^[0-9]*$">nul||(call :lp "日期只能是数字")
  6. if %dt% gtr 10000000 (
  7. if %dt% lss 30000000 (ver>nul) else (
  8. call :lp "只能是3000年以内"
  9. )
  10. ) else (
  11. call :lp "不足1000年"
  12. )
  13. set/a y=%dt%/10000,m=%dt%%%10000/100,d=%dt%%%100
  14. set "ds=312831303130313130313031"
  15. for /l %%i in (1 1 12) do (
  16. if %m% equ %%i (
  17. set /a n=%m%*2
  18. setlocal enabledelayedexpansion
  19. set n=!n:~-2!
  20. endlocal
  21. )
  22. )
  23. if %d% gtr 0 (
  24. if %d% leq %n% (call :lp "合法") else (
  25. call :lp "%m%月没有%d%天"
  26. )
  27. ) else call :lp "天数不能是0"
  28. pause>nul&goto :top
  29. :lp
  30. echo %~1&pause>nul&goto :top
  31. goto :EOF
复制代码
没有进行平润年判断。。。这么多if else没什么效率可言就是了。。凑合着看吧。。
作者: batman    时间: 2011-5-29 18:36

楼上是不是没看清楚题意,只有findstr就能判断出来啊,还要这么多代码做什么?
作者: abcdshenji    时间: 2011-5-29 18:44

只能用一次findstr就能检查这么多要求哦。。原谅我水平非常有限。。唉在batman面前实在是丢脸了。。
作者: batman    时间: 2011-5-29 18:50

4# abcdshenji
兄弟怎么说的话,大家都是学习者,不过这题能叫挑战,肯定不是这么简单,在findstr有限的正则上多想想。。。
作者: caruko    时间: 2011-5-30 01:27

findstr 支持的正则太少了,早就想过。
除非 连续几个 findstr | findstr  这样。
作者: batman    时间: 2011-5-30 08:49

本帖最后由 batman 于 2011-5-30 08:51 编辑

6# caruko
全文只有一个findstr,正如题意所描述的。。。

带显示命令和pause命令这两行总共应在五行代码内吧。。。
作者: caruko    时间: 2011-5-30 09:16

没有分组功能 (ab)|(cd) 这样,这个真的可以做到?
作者: batman    时间: 2011-5-30 09:26

8# caruko
看到我的载图不,这不是做到了吗?呵呵。。。,当然肯定还有其他好办法的。。。
作者: lxzzr    时间: 2011-5-30 09:39

不知man的思路是否源于那个以前JM写的那个判断IP格式合法的批处理...

正则不是很懂,贴上其它的代码,^_^
  1. @echo off
  2. set currdate=%date:~0,10%
  3. set /p input=input:
  4. echo %input:~0,4%%date:~4,1%%input:~4,2%%date:~4,1%%input:~6,2% | date >nul && (echo.合法.& echo %currdate% | date >nul) || echo.非法.
  5. pause
复制代码

作者: cjiabing    时间: 2011-5-30 09:41     标题: !~

本帖最后由 cjiabing 于 2011-5-30 09:45 编辑

见过随风写的判断ip的!~
用到for 吗?
难道只用一个findstr命令?
作者: batman    时间: 2011-5-30 09:43

本帖最后由 batman 于 2011-5-30 09:46 编辑

10# lxzzr
不是源自,是很相似,但这个情况肯定复杂得多。。。

ps:代码不要跑题哦。。。
作者: batman    时间: 2011-5-30 09:47

11# cjiabing

用且只用一次findstr命令不是很难懂吧。。。
作者: cjiabing    时间: 2011-5-30 10:45

13# batman
哈哈,希望你透露更多信息,似乎你已经做出来了!~
对findstr的运用没那么熟,向你们学习!~
作者: 随风    时间: 2011-5-30 10:55

14# cjiabing

是呀,我曾经断言做不出,没想到硬是给他做出来了。。。虽然代码看起来有点“恐怖”
作者: caruko    时间: 2011-5-30 10:59

这样的话,看来要用 /v 开关了。
我想想。
作者: qzwqzw    时间: 2011-5-30 11:06

应该是用到了多个模式串来处理不同月份不同天数的问题
只是平闰年判断尚没有不用set的思路

一般的检测日期的方法除了简单判断溢出之外
就是使用日期的命令来辅助检测了
date是最常用的比如10楼的方案
不过它有个缺陷就是可能会改变系统日期
即使只是短期的改变在某些环境下也是不允许的
即使允许也存在在日期临界点改变日期后恢复时可能存在错误

我现在常用的方法是net user
net user _ /expires:2004-02-29 2>&1|find "日期">nul&&echo 不合法的日期||echo 合法的日期
作者: batman    时间: 2011-5-30 11:11

本帖最后由 batman 于 2011-5-30 11:12 编辑
应该是用到了多个模式串来处理不同月份不同天数的问题
只是平闰年判断尚没有不用set的思路

一般的检测日期的方法除了简单判断溢出之外
就是使用日期的命令来辅助检测了
date是最常用的比如10楼的方案
不过它有 ...
qzwqzw 发表于 2011-5-30 11:06

高人总是能一语中的。。。换句话来说:怎么变也难逃法眼

qzw我有个私人问题压积于心中很久,还望给予回复:你是不是就是willsort老大?(感觉不便可短信告之于我)
作者: caruko    时间: 2011-5-30 11:29

本帖最后由 caruko 于 2011-5-30 13:20 编辑

瑞年没有太精确。

就是把所有不合法的匹配串写进去,符合了就是不合法的。只是每个字串只匹配1-2个特征。
^[04-9]  指0000-0999  4000-9999年段。
^[3][1-9][1-9][1-9]  3111-3999好吧,这个其实不准确,没有包括3001-3099,要分成3个很麻烦。
^[0-9][0-9][0-9][0-9][2-9][0-9][0-9][0-9]$ ^[0-9][0-9][0-9][0-9][0-9][0-9][4-9][0-9]$ 指 月份不能是 20以上以及日期不能是40以上。
后面的分别对 13578,10,12 月限定 < 32, 469,11 <31 ,2月则根据年份最后一位是否02468,来决定是28还是29。
最后是限定 月份个位以及日期个位 <> 0

[^0-9]  去掉数字以外的字符,忘记了符号限定,修改一下。

呃,可以set计算的话,那么简单了。。
findstr判断了年份个位为13579的出现 0229为不合法,set 判断 02468后缀的年份情况。
  1. echo,%input%|findstr "^[04-9]  [^0-9]  ^[3][1-9][1-9][1-9][0-9]  ^[0-9][0-9][0-9][0-9][2-9][0-9][0-9][0-9]$ ^[0-9][0-9][0-9][0-9][0-9][0-9][4-9][0-9]$ ^[0-9][0-9][0-9][0-9][1][3-9][0-9][0-9] ^[0-9][0-9][0-9][0-9][0][469][3][1-9]$ ^[0-9][0-9][0-9][0-9][0][13578][3][2-9]$ ^[0-9][0-9][0-9][0-9][0][2][3-9][0-9]$ ^[0-9][0-9][0-9][13579][0][2][2][9]$ ^[0-9][0-9][0-9][0-9][1][02][3-9][2-9]$ ^[0-9][0-9][0-9][0-9][1][1][3-9][1-9]$ ^[0-9][0-9][0-9][0-9][0-9][0][0-9][0]$" >nul&& set input=10010229
  2. 2>nul set /a 1 / (%input:~0,4% %% 4) && (set /a 1 / (1%input:~4% - 10229)  && echo,合法 || echo,不合法 )  || echo,合法
复制代码

作者: caruko    时间: 2011-5-30 11:44

本帖最后由 caruko 于 2011-5-30 11:56 编辑

日期判断,其实 xcopy /d 也可以判断,日期无效会输出如“无效参数 - /d:02-29-2001” 。
  1. echo,f|xcopy "%0" a#b@c$.bat /d:02-29-2002 /l /u 2>&1|findstr "无效参数.*d:" >nul&& echo,不合法 ||echo 合法
复制代码

作者: batman    时间: 2011-5-30 11:44

19# caruko
请按题意附上简明思路,要知道看这个东东很头痛的。。。
作者: cjiabing    时间: 2011-5-30 12:10

19# caruko
看见光明了!~
作者: CrLf    时间: 2011-5-30 12:28

10# lxzzr


哈哈,我也想到那块去了:
  1. @echo off
  2. set /p test=请输入日期
  3. xcopy>nul 2>nul /l /d:%test:~-4,2%-%test:~-2%-%test:0,-4% %tmp%&&echo 日期合法||echo 日期不合法
  4. pause
复制代码

作者: batman    时间: 2011-5-30 12:38

23# zm900612
继续跑题。。。。
作者: CrLf    时间: 2011-5-30 12:39

20# caruko


晕,看来又撞车了
作者: CrLf    时间: 2011-5-30 12:41

另外,如果只是用findstr判断平润年,还是可行的
作者: caruko    时间: 2011-5-30 12:55

findstr 如何判断年份被被4整除呢?
作者: CrLf    时间: 2011-5-30 13:02

判断年份能被4整除很容易:
echo 20080102|findstr /e "[02468][048].... [13579][26]...."
若要同时对百位判断,只需要把这两条关键词排列组合成四条关键词就行了。
不过如果和日期放在一起排列组合,那...
作者: qzwqzw    时间: 2011-5-30 15:50

按照合法日期的模式排列了组合一下findstr的模式串
不考虑闰年计算是10条
[1-2][0-9][0-9][0-9]0[1-9]0[1-9]
[1-2][0-9][0-9][0-9]0[1-9]1[0-9]
[1-2][0-9][0-9][0-9]0[^2]2[0-9]
[1-2][0-9][0-9][0-9]022[0-8]
[1-2][0-9][0-9][0-9]0[13578]3[0-1]
[1-2][0-9][0-9][0-9]0[469]30
[1-2][0-9][0-9][0-9]1[0-2]0[1-9]
[1-2][0-9][0-9][0-9]1[0-2][12][0-9]
[1-2][0-9][0-9][0-9]1[02]3[0-1]
[1-2][0-9][0-9][0-9]1130

如果考虑闰年计算
需要增补XXXX0229的模式串
仅考虑被4整除是2条
[1-2][0-9][02468][048]0229
[1-2][0-9][13579][26]0229
加起来一共是12条

考虑100,400整除的情况稍微复杂些
需要将00从[02468][048]中排除
即将之拆分成[2468][048]和[02468][48]
[1-2][0-9][13579][26]0229
[1-2][0-9][2468][048]0229
[1-2][0-9][02468][48]0229
[02468][048]000229
[13579][26]000229
加起来一共15条

这是正向过滤合法日期的模式串
反向过滤非法日期的模式串应该稍微简单些
只是还未想到过滤掉长度非法的模式串
作者: caruko    时间: 2011-5-30 16:51

本帖最后由 caruko 于 2011-5-30 16:53 编辑

正向是符合任意一条都合法,而不是符合所有条件才合法。
逻辑上不对,所以不好用,加 /V 开关也不行。
反向过滤规则串更多。
包括 长度非法,非法非数字字符 等规则。

长度非法 直接 ^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$  或者 \<str>\ 也可以。
作者: qzwqzw    时间: 2011-5-30 17:45

本帖最后由 qzwqzw 于 2011-5-30 17:53 编辑

OK
感谢提醒
我的关于“正向、反向”的提法有问题
/v开关的“不包含匹配”用在正则中
实际上是指“任一模式串均不匹配”
使用/v开关后不需要改变模式串
也可以可通过逆变&&后面的程序逻辑得到相同的效果

我所说的反向应该是指模式串的“反向”
即正向模式串的逆变

正向确实是“符合任意一条都匹配”
我的正向模式串正体现了这一特性

^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$
是判定日期串长度合法而非非法的
虽然使用/v或者逆变程序逻辑
可以独立地判定字符串长度非法
但是无法与逆向模式串结合使用

我想了一下
关于逆向模式串长度非法只能使用
^$
^.$
^..$
^...$
^....$
^.....$
^......$
^.......$
^..........*$

结合其他逆向的模式
组建非法日期的模式串
[^0-9]
^[3-9]
00..$
1[3-9]..$
[2-9]...$
00$     
3[2-9]$
[4-9].$
0[469]31$
1131$
0230$
0229$

以上不考虑闰年计算的
考虑闰年需要将最后一条替换成
[13579]0229$
[13579][048]0229$
[02468][26]0229$
[13579]000229$
[13579][048]000229$
[02468][26]000229$
作者: batman    时间: 2011-5-30 19:15

本帖最后由 batman 于 2011-5-30 19:52 编辑

期待qzw完整代码的出现,先贴出本人的愚解:
  1. @echo off
  2. :lp
  3. cls&set "flag="&set "str="
  4. set /p str=请输入:
  5. set /a "p=!(%str:~,4%%%4)&!(!(%str:~,4%%%100))|!(%str:~,4%%%400)+8">nul 2>nul
  6. echo %str%|findstr /x "[1-2][0-9][0-9][0-9]0[1-9]0[1-9] [1-2][0-9][0-9][0-9]1[0-2]0[1-9] [1-2][0-9][0-9][0-9]0[1-9]1[0-9] [1-2][0-9][0-9][0-9]1[0-2][1-2][0-9] [1-2][0-9][0-9][0-9]0[13456789]2[0-9] [1-2][0-9][0-9][0-9]022[0-%p%] [1-2][0-9][0-9][0-9]0[13578]3[0-1] [1-2][0-9][0-9][0-9]0[469]30 [1-2][0-9][0-9][0-9]1[02]3[0-1] [1-2][0-9][0-9][0-9]1130 30000[1-9]0[1-9] 30001[0-2]0[1-9] 30000[1-9]1[0-9] 30001[0-2][1-2][0-9] 30000[13456789]2[0-9] 3000022[0-%p%] 30000[13578]3[0-1] 30000[469]30 30001[02]3[0-1] 30001130">nul||set "flag=不"
  7. echo 这是%flag%合法的日期
  8. pause>nul&goto lp
复制代码
简要说明下思路如下:
    整体为正向匹配法,就是列出所有合法日期的组合。正则表达式本来就很长了,如果再加入对平闰年的组合,表达式将更长,所以在前面对平闰年进行了计算并设置了针对二月的日期变量。

    随后在正则中先将合法年份的判断分为两个部分,第一部分的正则是[1-2][0-9][0-9][0-9],第二部分的正则就是3000;然后再这两种情况下分别组合日期为[0]1-9,[1-2][0-9],3[0-1]的情况,并在其中加入对月份合法的正则判断以及各月份最大天数值的正则判断,重点对2月进行了判断,正则为022[0-%p%],具体的分项为[1-2][0-9][0-9][0-9]022[0-%p%]和3000022[0-%p%]。其中p值为set/a计算出来的,平年为8,闰年为9。

    至于字符串合法性判断,以及长度判断用一个/x参数就可以实现了。

    个人测试没有发现问题,欢迎大家测试并批评指导。
作者: qzwqzw    时间: 2011-5-30 19:19

本帖最后由 qzwqzw 于 2011-5-30 20:08 编辑

以下是正、逆模式的测试代码
请各位检阅
  1. @echo off & setlocal
  2. set 正模式=
  3. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]0[1-9]0[1-9]$"
  4. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]0[1-9]1[0-9]$"
  5. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]0[^02]2[0-9]$"
  6. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]022[0-8]$"
  7. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]0[13578]3[0-1]$"
  8. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]0[469]30$"
  9. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]1[0-2]0[1-9]$"
  10. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]1[0-2][12][0-9]$"
  11. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]1[02]3[0-1]$"
  12. set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]1130$"
  13. set "正模式=%正模式% ^[1-2][0-9][13579][26]0229$"
  14. set "正模式=%正模式% ^[1-2][0-9][2468][048]0229$"
  15. set "正模式=%正模式% ^[1-2][0-9][02468][48]0229$"
  16. set "正模式=%正模式% ^[02468][048]000229$"
  17. set "正模式=%正模式% ^[13579][26]000229$"
  18. set 正模式
  19. echo.
  20. set 逆模式=
  21. set "逆模式=%逆模式% ^$"
  22. set "逆模式=%逆模式% ^.$"
  23. set "逆模式=%逆模式% ^..$"
  24. set "逆模式=%逆模式% ^...$"
  25. set "逆模式=%逆模式% ^....$"
  26. set "逆模式=%逆模式% ^.....$"
  27. set "逆模式=%逆模式% ^......$"
  28. set "逆模式=%逆模式% ^.......$"
  29. set "逆模式=%逆模式% ^..........*$"
  30. set "逆模式=%逆模式% [^0-9]"
  31. set "逆模式=%逆模式% ^[3-9]"
  32. set "逆模式=%逆模式% 00..$"
  33. set "逆模式=%逆模式% 1[3-9]..$"
  34. set "逆模式=%逆模式% [2-9]...$"
  35. set "逆模式=%逆模式% 00$"
  36. set "逆模式=%逆模式% 3[2-9]$"
  37. set "逆模式=%逆模式% [4-9].$"
  38. set "逆模式=%逆模式% 0[469]31$"
  39. set "逆模式=%逆模式% 1131$"
  40. set "逆模式=%逆模式% 0230$"
  41. set "逆模式=%逆模式% [13579]0229$"
  42. set "逆模式=%逆模式% [13579][048]0229$"
  43. set "逆模式=%逆模式% [02468][26]0229$"
  44. set "逆模式=%逆模式% [13579]000229$"
  45. set "逆模式=%逆模式% [13579][048]000229$"
  46. set "逆模式=%逆模式% [02468][26]000229$
  47. set 逆模式
  48. echo.
  49. :loop
  50. set /p 输入值=按yyyymmdd格式输入日期,输入Q退出:
  51. if /i "%输入值%"=="q" goto :eof
  52. rem 去除输入串前后的空格
  53. for %%v in (%输入值%) do set 输入值=%%v
  54. echo.%输入值%|findstr "%正模式%">nul && set 正结果=合法|| set 正结果=非法
  55. echo 正模式匹配后:'%输入值%'是%正结果%的日期
  56. echo.
  57. echo.%输入值%|findstr "%逆模式%">nul && set 逆结果=非法|| set 逆结果=合法
  58. echo 逆模式匹配后:'%输入值%'是%逆结果%的日期
  59. echo.
  60. goto :loop
复制代码

作者: batman    时间: 2011-5-30 19:40

33# qzwqzw
两种模式的判断,好!

但楼上是特意不判断3000年的吗?
作者: qzwqzw    时间: 2011-5-30 19:48

是的特意没有判断3000年
感觉没有什么意义
如果扩展的话
可以直接简单扩展到0000~9999

32楼的正则模式串
可以将10以上月份的10~29合并匹配

感觉/x没有办法适应逆模式下的非法长度判定
不可有何扩展的思路
作者: batman    时间: 2011-5-30 19:54

35# qzwqzw
多谢提醒,已合并。。。

对于逆向的多项匹配确实是不能用/x和/v,一时也无好的思路。。。
作者: qzwqzw    时间: 2011-5-30 20:11

修订了正模式中的非2月的20~29匹配模式
比如如下的值正模式判断出错
20010020

set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]0[^2]2[0-9]$"
改为
set "正模式=%正模式% ^[1-2][0-9][0-9][0-9]0[^02]2[0-9]$"
作者: qzwqzw    时间: 2011-5-31 14:30

刚才思考了一下
使用单条set应该也可以实现日期的合法性检查
有兴趣的可以贴一下的自己的方案
要求与楼主的大致相同
只是除了变换一下命令主体
作者: CrLf    时间: 2011-5-31 14:44

38# qzwqzw


单条set不难,单条算式倒是比较麻烦,不过貌似也有捷径
作者: qzwqzw    时间: 2011-6-3 21:40

贴一下单条set的方案
利用了很多Set/a的错误检测特性
_%输入值%=1%输入值%
::利用运算符不存在检测判断输入值是否全数字
1/(年/1000) 和 1/(3000/年)
::利用被0除错误检测输入值中的年份是否1000<=年<=3000
%输入值:~7%/(9/1%输入值:~8%)
::利用运算符不存在和被0除错误检测输入值长度是否等于8
诸如此类
  1. @echo off & setlocal
  2. :loop
  3. set /p 输入值=按yyyymmdd格式输入日期,输入Q退出:
  4. if /i "%输入值%"=="q" goto :eof
  5. rem 去除输入串前后的空格
  6. for %%v in (%输入值%) do set 输入值=%%v
  7. 2>nul set /a "_%输入值%=1%输入值%,%输入值:~7%/(9/1%输入值:~8%),年=1%输入值:~0,4%-10000,月=1%输入值:~4,2%-100,日=1%输入值:~6,2%-100,大月=!((月-1)*(月-3)*(月-5)*(月-7)*(月-8)*(月-10)*(月-12)),闰年=!(年%%4)&!(!(年%%100))|!(年%%400),1/((年/1000)*(3000/年)*(月/1)*(12/月)*(日/1)*(31/日)*(!(日/31)|大月)*(!(日/30)|(月-2))*(!(日/29)|(月-2)|闰年))"&&set 结果=合法||set 结果=非法
  8. echo set/a检测'%输入值%'的结果:%结果%的日期
  9. echo.
  10. goto :loop
  11. pause
复制代码

作者: youlishen    时间: 2011-12-1 16:07

呵呵,学习了,这个好用
作者: hfg1977    时间: 2012-2-3 01:28

本帖最后由 hfg1977 于 2012-2-3 02:27 编辑
  1. ::======================= 利用findstr判断输入日期的合法性 1000~2999===========
  2. @echo off
  3. set "str="&set /p "str=请输入yyyymmdd: "
  4. set "year=%str:~0,4%"
  5. set /a "yp=!(year%%4)^!(year%%100)|!(year%%400)"
  6. set "str=%yp%%str%"
  7. echo %str%>con&echo %str%|findstr "\<[0-1][1-2][0-9][0-9][0-9][0][1-9][0-1][1-9]\> \<[0-1][1-2][0-9][0-9][0-9][0][1 3-9][1-2][0-9]\> \<[0-1][1-2][0-9][0-9][0-9][0][13578][3][0-1]\> \<[0-1][1-2][0-9][0-9][0-9][0][469][3][0]\> \<[0-1][1-2][0-9][0-9][0-9][1][0-2][0][1-9]\> \<[0-1][1-2][0-9][0-9][0-9][1][0-2][1-2][0-9]\> \<[0-1][1-2][0-9][0-9][0-9][1][02][3][0-1]\> \<[0-1][1-2][0-9][0-9][0-9][1][1][3][0]\> \<[0][1-2][0-9][0-9][0-9][0][2][2][0-8]\> \<[1][1-2][0-9][0-9][0-9][0][2][2][0-9]\>">nul&&echo 这是合法的日期||echo 这不是合法的日期
  8. pause
  9. ::===================== end 判断日期合法性================================
复制代码
判断是否闰年 套用"batman "版主的公式.
作者: hfg1977    时间: 2012-2-3 01:49

本帖最后由 hfg1977 于 2012-2-3 02:27 编辑
  1. 说明:
  2. 1.第一位为闰平年标志位
  3. 2.set /a "yp=!(year%%4)^!(year%%100)|!(year%%400)"
  4. 该公式在batman版主的贴中学习到
  5. 3.枚举所有合法的日期:
  6. [0-1][1-2][0-9][0-9][0-9]-[0][1-9]-[0-1][1-9]
  7. [0-1][1-2][0-9][0-9][0-9]-[0][1 3-9]-[1-2][0-9]
  8. [0-1][1-2][0-9][0-9][0-9]-[0][13578]-[3][0-1]
  9. [0-1][1-2][0-9][0-9][0-9]-[0][469]-[3][0]
  10. [0-1][1-2][0-9][0-9][0-9]-[1][0-2]-[0][1-9]
  11. [0-1][1-2][0-9][0-9][0-9]-[1][0-2]-[1-2][0-9]
  12. [0-1][1-2][0-9][0-9][0-9]-[1][02]-[3][0-1]
  13. [0-1][1-2][0-9][0-9][0-9]-[1][1]-[3][0]
  14. [0][1-2][0-9][0-9][0-9]-[0][2]-[2][0-8]
  15. [1][1-2][0-9][0-9][0-9]-[0][2]-[2][0-9]
复制代码

作者: CrLf    时间: 2012-2-3 03:06

回复 40# qzwqzw


    正好写过日期检查函数,也贴个单 set 方案。
函数体:
  1. :ChechDate Date(YYYYMMDD)
  2. ::检查日期是否合法,合法时将改变 errorlevel 变量的值为 0,非法时为 1,参数格式错误时不作改变
  3. setlocal disabledelayedexpansion
  4. set/a"1/((date=%~1)/10000)" 2>nul||echo call :ChechDate Date(YYYYMMDD)&&exit/b
  5. set/a"b=1,y=%date:~,-4%,m=1%date:~-4,2%-100,d=1%date:~-2%-100,test=!(y%%4|!(y%%100)*!!(y%%400))*!(m^2)+(m+m/8)%%2-2*!(m^2)+30,b=0/(test/d*!(m/13))" 2>nul&&echo Right||echo Wrong
  6. exit/b%b%
复制代码
使用范例:
  1. @echo off
  2. echo 20111215
  3. call CheckDate 20111215
  4. echo   %%errorlevel%%=%errorlevel%
  5. ::一个正确的日期
  6. echo;
  7. echo 20110229
  8. call CheckDate 20110229
  9. echo   %%errorlevel%%=%errorlevel%
  10. ::一个错误的日期
  11. echo;
  12. echo 20120229
  13. call CheckDate 20120229 >nul
  14. if errorlevel 1 (echo 错误) else echo 正确
  15. echo   可以用 if errorlevel 判断
  16. ::也可以用连接符进行正误判断并自定义操作
  17. echo;
  18. echo 20120100
  19. call CheckDate 20120100 >nul&&echo 正确||echo 错误
  20. echo   也可以用管道符判断正误
  21. ::也可以用连接符进行正误判断并自定义操作
  22. pause>nul
复制代码

作者: aa77dd@163.com    时间: 2015-12-17 02:51

回复 23# CrLf


发现好象没人提计划任务, 那我提一下
  1. schtasks /create /TN faketask /TR "CMD /C" /SC ONCE /SD 2015/12/18 /ST 00:00 /F
  2. 成功: 成功创建计划任务 "faketask"。
  3. ECHO %ERRORLEVEL%
  4. 0
  5. schtasks /create /TN faketask /TR "CMD /C" /SC ONCE /SD 2015/12/41 /ST 00:00 /F
  6. 错误: 开始日期不正确。
  7. ECHO %ERRORLEVEL%
  8. -2147467259
复制代码





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