返回列表 发帖
实质是变量延迟的问题, 调试代码:
@echo off&setlocal enabledelayedexpansion
set/p a=起始日期,格式20071221
set/p b=终止日期,格式20080310
set m=寒夜312831303130313130313031孤星
if "%a:~4,1%"=="0" (set tm=%a:~5,1%) else set tm=%a:~4,2%
if "%a:~6,1%"=="0" (set td=%a:~7,1%) else set td=%a:~6,2%
set ty=%a:~0,4%&echo.%a%
:hanye
echo n=!n!
set/a n=%tm%*2,y=%ty%%%4,td=%td%+1,e=!m:~%n%,2!
echo n=!n!,e=!e!
pause
if %tm%==2 if %y%==0 set e=29
if %td% gtr %e% set/a tm=%tm%+1,td=1
if %tm%==13 set/a ty=%ty%+1,tm=1
if %tm% lss 10 (set em=0%tm%) else set em=%tm%
if %td% lss 10 (set ed=0%td%) else set ed=%td%
set d=%ty%%em%%ed%
if %d% gtr %b% pause>nul&goto :eof
echo.%d%&goto :hanyeCOPY
测试结果:
起始日期,格式20071221:18991125
终止日期,格式20080310:20000305
18991125
n=
n=22,e=0

我的代码中用的是如下方式来截取的:
(set /a index=m*2-2)& for %%i in (!index!) do set dmax=!days:~%%i,2!COPY

TOP

原帖由 neorobin 于 2010-4-8 00:17 发表
实质是变量延迟的问题, 调试代码echo off&setlocal enabledelayedexpansion
set/p a=起始日期,格式20071221:
set/p b=终止日期,格式20080310:
set m=寒夜312831303130313130313031孤星
if "%a:~4,1%"=="0" ...

谢谢,第一次是分两行写的,结果后来贪图美观就给和并到一行了,忘记了延迟的问题。。。
寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

以下代码同样用 100 年的日期测试, 用时与 7 楼 FOR 的代码极为接近
对输入的日期前后无限制, 可自动将在前的日期作为起始日期
其中 如: if "!_y!!_m!%%d" gtr "!ymde!" (goto :break) 这样的判断语句还可省去, 进一步提高效率, 但未有简洁方案, 太显繁长
@echo off&setlocal enabledelayedexpansion
set /p ymds=请输入起始日期(yyyymmdd),要使用系统当前日期,请直接回车:
set /p ymde=请输入截止日期(yyyymmdd),要使用系统当前日期,请直接回车:
(set t=%time%)&(cd.>outFile.txt)
for /l %%m in (1,1,12) do (set days_%%m=31)
for %%m in (4,6,9,11) do (set days_%%m=30)
if not defined ymds (set ymds=%date:~0,4%%date:~5,2%%date:~8,2%)
if not defined ymde (set ymde=%date:~0,4%%date:~5,2%%date:~8,2%)
if "!ymde!" lss "!ymds!" (set tt=!ymde!)&(set ymde=!ymds!)&(set ymds=!tt!)
echo 起始日期为:!ymds!, 截止日期为:!ymde!
(set /a ys=1!ymds:~0,4!-10000, ye=1!ymde:~0,4!-10000)
(set /a ms=1!ymds:~4,2!-100, me=1!ymde:~4,2!-100)
(set /a ds=1!ymds:~6,2!-100, de=1!ymde:~6,2!-100)
set /a "y_1=ys+1,m_1=ms+1,d_1=ds+1"
for /l %%y in (!ys!,1,!ys!) do (
  (set _y=000%%y)&(set _y=!_y:~-4!)
  for /l %%m in (!ms!,1,!ms!) do (
    (set _m=0%%m)&(set _m=!_m:~-2!)
    if %%m==2 set /a "days_2=28+(^!(%%y%%4)&^!^!(%%y%%100))|^!(%%y%%400)"
    for /l %%d in (!ds!,1,9) do (
      if "!_y!!_m!0%%d" gtr "!ymde!" (goto :break) else echo !_y!!_m!0%%d
    )
    if !ds! geq 10 (set d_2=!ds!) else set d_2=10
    for /l %%d in (!d_2!,1,!days_%%m!) do (
      if "!_y!!_m!%%d" gtr "!ymde!" (goto :break) else echo !_y!!_m!%%d
    )
  )
  for /l %%m in (!m_1!,1,12) do (
    (set _m=0%%m)&(set _m=!_m:~-2!)
    if %%m==2 set /a "days_2=28+(^!(%%y%%4)&^!^!(%%y%%100))|^!(%%y%%400)"
    for /l %%d in (1,1,9) do (
      if "!_y!!_m!0%%d" gtr "!ymde!" (goto :break) else echo !_y!!_m!0%%d
    )
    for /l %%d in (10,1,!days_%%m!) do (
      if "!_y!!_m!%%d" gtr "!ymde!" (goto :break) else echo !_y!!_m!%%d
    )
  )
)>>outFile.txt
for /l %%y in (!y_1!,1,!ye!) do (
  (set _y=000%%y)&(set _y=!_y:~-4!)
  for /l %%m in (1,1,12) do (
    (set _m=0%%m)&(set _m=!_m:~-2!)
    if %%m==2 set /a "days_2=28+(^!(%%y%%4)&^!^!(%%y%%100))|^!(%%y%%400)"
    for /l %%d in (1,1,9) do (
      if "!_y!!_m!0%%d" gtr "!ymde!" (goto :break) else echo !_y!!_m!0%%d
    )  
    for /l %%d in (10,1,!days_%%m!) do (
      if "!_y!!_m!%%d" gtr "!ymde!" (goto :break) else echo !_y!!_m!%%d
    )
  )
)>>outFile.txt
:break
echo 用时: !t! ==^> %time%
start outFile.txt
pause
exit /bCOPY

[ 本帖最后由 neorobin 于 2010-4-8 03:46 编辑 ]

TOP

参照日期算法 应该可行 效率没测试

TOP

提速,100 个日期 只需 1.81 秒
@echo off&setlocal enabledelayedexpansion
set t=%time%
echo 请输入8位数的起始日期和结束日期用空格分开
echo 或只输入结束(开始)日期,默认当前日期为起始(结束)日期
echo 输入格式 20080205 21080529&echo.
set xx=19100201
for /f "tokens=1,2" %%i in ("%xx%") do (
   if not "%%j"=="" (set qs=%%i&set js=%%j) else (
      for /f "tokens=1-3 delims=.\-/ " %%a in ("!date!") do (
         if %%a%%b%%c gtr %%i (set/a qs=xx,js=%%a%%b%%c) else (
            set/a qs=%%a%%b%%c,js=%%i
))))
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do set/a n+=1&set/a yue!n!=%%a
set /a qsd=100%qs:~4,2%%%100,qsm=100%qs:~6,2%%%100
set /a yuq=qsd,yuh=12,mq=qsm,mh=yue!qsd!
echo 起始日期 %qs:~0,4%-%qs:~4,2%-%qs:~6,2%
echo 结束日期 %js:~0,4%-%js:~4,2%-%js:~6,2%
for /l %%i in (1 1 31) do set .%%i=0%%i&set ".%%i=!.%%i:~-2!"
(
for /l %%i in (%qs:~0,4% 1 %js:~0,4%) do (
    set /a yue2="^!(%%i%%4)&^!(^!(%%i%%100))|^!(%%i%%400)"+28
    if %%i equ %js:~0,4% set /a yuh=100%js:~4,2%%%100&set flag=a
    for /l %%j in (!yuq! 1 !yuh!) do (
       set /a mh=yue%%j
       if defined flag if %%j equ !yuh! set /a mh=100!js:~-2!%%100
       for /l %%k in (!mq! 1 !mh!) do echo %%i!.%%j!!.%%k!
       set /a mq=1&echo;
     )
     set yuq=1
)
)>c.txt
pauseCOPY

TOP

看楼上各位把for /l用到这境界,羡一个。。。
寒夜孤星:在没有说明的情况下,本人所有代码均运行在 XP SP3 下 (有问题请发贴,QQ临时会话已关闭)

TOP

发现已经迟到一步
@echo off&setlocal enabledelayedexpansion
set "YmdP=19080521"
set "YmdT=20110902"
if "%YmdP%" gtr "%YmdT%" set/a "YmdP=YmdT,YmdT=%YmdP%"
set /a "p1=%YmdP:~,4%,p2=1%YmdP:~4,2%%%100,p3=1%YmdP:~6,2%%%100,T1=%YmdT:~,4%,T2=1%YmdT:~4,2%%%100,T3=1%YmdT:~6,2%%%100"
for /l %%i in (%p1% 1 %t1%) do set /a "i%%i=1,j%%i=12"
set /a "i%p1%=p2,j%t1%=t2"
for %%i in (31 28 31 30 31 30 31 31 30 31 30 31) do set /a n+=1&set "_n!n!=%%i"
for /l %%i in (%p1% 1 %t1%) do (
set /a "_n2=^!(%%i%%4)&^!(^!(%%i%%100))|^!(%%i%%400)+28"
    for /l %%j in (!i%%i! 1 !j%%i!) do (
       set i=1
       if "%%i%%j" equ "!p1!!p2!" set /a "i=p3"
       if "%%i%%j" equ "!t1!!t2!" set /a "_n%%j=t3"
       set "m=0%%j"
       for /l %%k in (!i! 1 !_n%%j!) do (
       set "d=0%%k"
       echo;%%i!m:~-2!!d:~-2!
)))
pauseCOPY

TOP

继续提速,减少for循环内代码运行的次数,效率略有提高,测试100个日期耗时1.66秒左右

@echo off&setlocal enabledelayedexpansion
set t=%time%
echo 请输入8位数的起始日期和结束日期用空格分开
echo 或只输入结束(开始)日期,默认当前日期为起始(结束)日期
echo 输入格式 20080205 21080529&echo.
set xx=19100201
for /f "tokens=1,2" %%i in ("%xx%") do (
   if not "%%j"=="" (set qs=%%i&set js=%%j) else (
      for /f "tokens=1-3 delims=.\-/ " %%a in ("!date!") do (
         if %%a%%b%%c gtr %%i (set/a qs=xx,js=%%a%%b%%c) else (
            set/a qs=%%a%%b%%c,js=%%i
))))
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do set/a n+=1&set/a yue!n!=%%a
set /a qsd=100%qs:~4,2%%%100,qsm=100%qs:~6,2%%%100
set /a yuq=qsd,yuh=12,mq=qsm,mh=yue!qsd!
for /l %%i in (1 1 31) do set .%%i=0%%i&set ".%%i=!.%%i:~-2!"
set /a a=100!js:~4,2!%%100,b=100!js:~-2!%%100
set #2010!a!=!js:~0,4!&set yue!js:~0,4!!a!=!b!
set _!js:~0,4!=!a!&set yuh!a!=!a!
echo 起始日期 %qs:~0,4%-%qs:~4,2%-%qs:~6,2%
echo 结束日期 %js:~0,4%-%js:~4,2%-%js:~6,2%
(for /l %%i in (%qs:~0,4% 1 %js:~0,4%) do (
    set /a yue2="^!(%%i%%4)&^!(^!(%%i%%100))|^!(%%i%%400)"+28,yuh=yuh!_%%i!
    for /l %%j in (!yuq! 1 !yuh!) do (
       set /a mh=yue!#%%i%%j!%%j
       for /l %%k in (!mq! 1 !mh!) do echo %%i!.%%j!!.%%k!
       set mq=1
     )
     set yuq=1
))>c.txt
pauseCOPY

[ 本帖最后由 FOR 于 2010-4-8 15:06 编辑 ]
1

评分人数

TOP

借鉴各位的技巧和思路,特别是 FOR 的, 再发一个:
@echo off&setlocal enabledelayedexpansion
set /p ymds=请输入起始日期(yyyymmdd),要使用系统当前日期,请直接回车:
set /p ymde=请输入截止日期(yyyymmdd),要使用系统当前日期,请直接回车:
if not defined ymds (set ymds=%date:~0,4%%date:~5,2%%date:~8,2%)
if not defined ymde (set ymde=%date:~0,4%%date:~5,2%%date:~8,2%)
if "!ymde!" lss "!ymds!" (set tt=!ymde!&set ymde=!ymds!&set ymds=!tt!)
echo 起始日期为:!ymds!, 截止日期为:!ymde!
set /p=%time% ==^><nul
for /l %%i in (0 1 31) do set _%%i=0%%i&set "_%%i=!_%%i:~-2!"
(for /l %%m in (1,1,12) do set SD_%%m=31)&for %%m in (4,6,9,11) do set SD_%%m=30
set /a ys=1!ymds:~0,4!-10000, ye=1!ymde:~0,4!-10000
set /a ms=1!ymds:~4,2!-100, me=1!ymde:~4,2!-100
set /a ds_diff=1!ymds:~6,2!-101, dEnd=1!ymde:~6,2!-100
(for /l %%y in (%ymds:~0,4% 1 %ymde:~0,4%) do (
  set /a "SD_2=28+(^!(%%y%%4)&^!^!(%%y%%100))|^!(%%y%%400)"
  if %%y gtr !ys! (set ms=1)
  if %%y lss !ye! (
    for /l %%m in (!ms!,1,12) do (
      set /a "ds=1+(^!(%%y^^ys)&^!(%%m^^ms))*ds_diff"
      for /l %%d in (!ds!,1,!SD_%%m!) do echo %%y!_%%m!!_%%d!
    )
  ) else for /l %%m in (!ms!,1,!me!) do (
      set /a "ds=1+(^!(%%y^^ys)&^!(%%m^^ms))*ds_diff"
      if %%m geq !me! (set de=!dEnd!) else (set de=!SD_%%m!)
      for /l %%d in (!ds!,1,!de!) do echo %%y!_%%m!!_%%d!
  )
))>out.txt
echo %time%&start out.txt&pauseCOPY

TOP

返回列表