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

DOS系统中获取并分解系统日期时间的批处理

【方案一】

To All:

      今天,根据网上的一段代码[1]修改出一个可以在MSDOS下获取并分解系统时钟信息(日期、时间)的批处理。在MSDOS6.22/MSDOS7.10下运行通过。显然易见的是,程序的冗余度过高,存在大量的重复代码,所以它需要简化,也必然可以简化。本来是要自己修改的,只是最近还在忙其他的题目,无法分心;同时又感觉论坛讨论纯DOS批处理的主题日趋萎缩,所以将它贴上来,大家讨论一下,看有什么好的简化和改进方案,并对其中涉及到的DOS下的词法分析算法进行讨论和优化。当然,网上的此类代码应该还有许多,大家也可以提供更多的资源链接或者自己的想法。

[1] %time%...DOS vs. Win98
http://groups.google.com/group/a ... 04/7c979271a52e36e7
  1. @echo off
  2. if "%1"=="[(" goto parse
  3. echo.|date|find "Current" > _getdate.bat
  4. echo set _dw=%%3> current.bat
  5. echo set _date=%%4>> current.bat
  6. call _getdate.bat
  7. echo.|date|find "Enter" > _getdfmt.bat
  8. echo set _dfmt=%%3> enter.bat
  9. call _getdfmt.bat
  10. echo.|time|find "Current" > _gettime.bat
  11. echo set _time=%%3> current.bat
  12. call _gettime.bat
  13. echo _|choice /c%_dfmt%%_date%_%_time%_ @%0 > _parse.bat
  14. %comspec% /e:2048 /c _parse.bat
  15. goto end
  16. :parse
  17. set _dt1=_%2%3
  18. set _dt2=_%5%6
  19. set _dt3=_%8%9
  20. for %%t in ([,Y,Y,-,M,M,-,D,D,]) do shift
  21. set _vdt=
  22. :loop1
  23. shift
  24. set _tmp=%_vdt%
  25. for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
  26. if not "%_vdt%"=="%_tmp%" goto loop1
  27. set %_dt1%=%_vdt%
  28. set _vdt=
  29. :loop2
  30. shift
  31. set _tmp=%_vdt%
  32. for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
  33. if not "%_vdt%"=="%_tmp%" goto loop2
  34. set %_dt2%=%_vdt%
  35. set _vdt=
  36. :loop3
  37. shift
  38. set _tmp=%_vdt%
  39. for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
  40. if not "%_vdt%"=="%_tmp%" goto loop3
  41. set %_dt3%=%_vdt%
  42. set _vdt=
  43. :loop4
  44. shift
  45. set _tmp=%_vdt%
  46. for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
  47. if not "%_vdt%"=="%_tmp%" goto loop4
  48. set _HH=%_vdt%
  49. set _vdt=
  50. :loop5
  51. shift
  52. set _tmp=%_vdt%
  53. for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
  54. if not "%_vdt%"=="%_tmp%" goto loop5
  55. set _MN=%_vdt%
  56. set _vdt=
  57. :loop6
  58. shift
  59. set _tmp=%_vdt%
  60. for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
  61. if not "%_vdt%"=="%_tmp%" goto loop6
  62. set _SS=%_vdt%
  63. set _vdt=
  64. :loop7
  65. shift
  66. set _tmp=%_vdt%
  67. for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
  68. if not "%_vdt%"=="%_tmp%" goto loop7
  69. set _CS=%_vdt%
  70. echo DTN:%_YY% %_MM% %_DD% %_HH% %_MN% %_SS% %_CS%
  71. :end
复制代码
【方案二】

我来贴一个,效率没有提高.减少了一些代码
  1. @echo off
  2. if "%1"=="[(" goto parse
  3. echo.|date|find "Current" > _getdate.bat
  4. echo set _dw=%%3> current.bat
  5. echo set _date=%%4>> current.bat
  6. call _getdate.bat
  7. echo.|date|find "Enter" > _getdfmt.bat
  8. echo set _dfmt=%%3> enter.bat
  9. call _getdfmt.bat
  10. echo.|time|find "Current" > _gettime.bat
  11. echo set _time=%%3> current.bat
  12. call _gettime.bat
  13. echo _|choice /c%_dfmt%%_date%_%_time%_ @%0 > _parse.bat
  14. %comspec% /e:2048 /c _parse.bat
  15. goto end
  16. :loop
  17. set _vdt=
  18. :loop1
  19. shift
  20. set _tmp=%_vdt%
  21. for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
  22. if not "%_vdt%"=="%_tmp%" goto loop1
  23. set %_set%=%_vdt%
  24. goto %next%
  25. :parse
  26. set _dt1=_%2%3
  27. set _dt2=_%5%6
  28. set _dt3=_%8%9
  29. set fgf=%4
  30. for %%t in ([,Y,Y,-,M,M,-,D,D,]) do shift
  31. :dt1
  32. set _set=%_dt1%
  33. set next=dt2
  34. goto loop
  35. :dt2
  36. set _set=%_dt2%
  37. set next=dt3
  38. goto loop
  39. :dt3
  40. set _set=%_dt3%
  41. set next=hh
  42. goto loop
  43. :hh
  44. set _set=_hh
  45. set next=MN
  46. goto loop
  47. :mn
  48. set _set=_mn
  49. set next=ss
  50. goto loop
  51. :ss
  52. set _set=_ss
  53. set next=cs
  54. goto loop
  55. :cs
  56. set _set=_cs
  57. set next=echo1
  58. goto loop
  59. :echo1
  60. echo DTN:%_YY% %_MM% %_DD% %_HH% %_MN% %_SS% %_CS%
  61. :end
复制代码
【方案三】

      今天有闲可以回顾修改这个程序了,解决这个代码的冗余性问题,其实最主要的就是如何实现一系列变量连续性的取值和赋值。本来打算使用for对变量进行循环探测,遇到未赋值的变量即跳出赋值,但是此算法实现起来较为复杂,而且对最初变量的重复探测问题也是代码冗余性的一种表现。现在,看到兄的代码,联想起可以使用数据结构中的链表结构,而它正可通过命令行参数来实现,所以写下了这个修改版本。

      这个版本,同时解决了变量没有被“传出”的问题,也增加了退出前清扫现场的语句。但是这个程序还存在许多缺陷,最致命的是,程序中的词法分析核心 choice 无法正确分析以/作为分隔符的字符串,而诸如国家代码为001(United States)的日期信息恰是以/作为分隔符,而代码中的所有语句都是以不依赖于“国家或区域代码”的通用性为设计目标,而这个缺陷完全架空了其他语句所作的努力。

      另外,它还无法处理时间信息中的12小时制时间。
  1. @echo off
  2. if "%1"==":" goto %2
  3. echo.|date|find "Current" > _getdate.bat
  4. echo set _dw=%%3> current.bat
  5. echo set _date=%%4>> current.bat
  6. call _getdate.bat
  7. echo.|date|find "Enter" > _getdfmt.bat
  8. echo set _dfmt=%%3> enter.bat
  9. call _getdfmt.bat
  10. echo.|time|find "Current" > _gettime.bat
  11. echo set _time=%%3> current.bat
  12. call _gettime.bat
  13. echo _|choice /c"%_dfmt%%_date%_%_time%" @%0 : parse > _parse.bat
  14. %comspec% /e:2048 /c _parse.bat
  15. call _setdt.bat
  16. for %%e in (_date _dfmt _time) do set %%e=
  17. for %%f in (_*.bat enter.bat* current.bat*) do del %%f
  18. echo DTN:%_YY%-%_MM%-%_DD% %_HH%:%_MN%:%_SS%.%_CS%
  19. goto end
  20. :parse
  21. set _me=%0
  22. shift
  23. shift
  24. set _tok=%2%3 %5%6 %8%9 HH MN SS CS
  25. for %%t in ([,Y,Y,-,M,M,-,D,D,]) do shift
  26. :NextToken
  27. set _vdt=
  28. :GetToken
  29. shift
  30. set _tmp=%_vdt%
  31. for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
  32. if not "%_vdt%"=="%_tmp%" goto GetToken
  33. if "%1"=="" goto end
  34. call %_me% : SetToken %_tok%
  35. goto NextToken
  36. :SetToken
  37. set _tok=%4 %5 %6 %7 %8 %9
  38. echo set _%3=%_vdt%>> _setdt.bat
  39. goto end
  40. :end
复制代码
【方案四】

      在[1]找到了解决choice对/的兼容性问题,可以支持001的时钟信息了;而prompt的选择不仅简化了代码,同时还使时间保持为24小时制。对帖中代码进行了简单的修改得到以下代码,未进行日期变量名的匹配。

[1] alt.msdos.batch > Documentation of CHOICE streaming parser
http://groups.google.com/group/a ... sg/5e1d0f360f172118
  1. @echo off
  2. if "%1"==":" goto %2 (subroutine handler at %2)
  3. echo.exit|%comspec%/e:4096/k prompt set v=$d $t$_:>_tm.bat
  4. call _tm.bat
  5. echo.%v%&|%comspec%/e:4096/c %0 : Parse>_tm.bat
  6. for %%p in (_tm.bat* _tmset.bat*) do call %%p
  7. echo.Note that d1 d2 and d3 are in your system date order
  8. echo.DTN:d1=%d1% d2=%d2% d3=%d3% hh=%hh% mm=%mm% ss=%ss% cs=%cs%.
  9. for %%e in (v d1 d2 d3 hh mm ss cs) do set %%e=
  10. for %%f in (_tm.bat* _tm.tmp* _tmset.bat*) do del %%f
  11. goto end
  12. :Parse (usage: call %0 : Parse +input redirect date/time)
  13. set me=%0
  14. set tok=d1 d2 d3 hh mm ss cs
  15. set d1=
  16. :NextToken
  17. for %%v in (v1 v) do set %%v=
  18. choice /c&0123456789 /n>_tm.tmp
  19. for %%n in (0 1 2 3 4 5 6 7 8 9) do if errorlevel 77%%n set v=%%n
  20. if not errorlevel 2 %me% : SetToken %tok%
  21. find ""<_tm.tmp>nul
  22. if not errorlevel 1 if not "%d1%"=="" call %me% : SetToken %tok%
  23. set d1=%d1%%v%
  24. goto NextToken
  25. :SetToken
  26. set tok=%4 %5 %6 %7 %8 %9
  27. echo set %3=%d1%>> _tmset.bat
  28. set d1=
  29. goto end
  30. :end (end-of-file)
复制代码
转自:http://www.cn-dos.net/forum/viewthread.php?tid=19756

返回列表