Board logo

标题: [日期时间] 【方案汇总】批处理标准化获取当前系统日期时间(20231002更新) [打印本页]

作者: Batcher    时间: 2009-2-13 21:23     标题: 【方案汇总】批处理标准化获取当前系统日期时间(20231002更新)

操作系统不同,日期格式也可能不同:

星期二 2008-07-29
2008-07-29 星期二
07/29/2008 Tue
Tue 07/29/2008

再考虑到中、英之外的其它语言的操作系统,日期格式的种类实在太多了。要想标准化地获取当前系统日期20080728,以下两个方法都不好:
1. 直接使用系统变量 %date% 进行字符串截取
2. 直接对 date 命令的结果进行字符串截取
实际上日期格式是由注册表 HKEY_CURRENT_USER\Control Panel\International 里面 sShortDate 的值来决定的。

推荐使用其它方法来获取系统日期:

【方案1】BAT + PowerShell
  1. @echo off
  2. REM Win7/Win10/Win11等系统自带PowerShell
  3. for /f %%i in ('powershell -c "Get-Date -uformat '%%Y%%m%%d'"') do (
  4.     set "Today=%%i"
  5. )
  6. echo,%Today%
  7. pause
  8. for /f "delims=" %%i in ('powershell -c "Get-Date -UFormat '%%Y-%%m-%%d %%H:%%M:%%S'"') do (
  9.     set "SysTS=%%i"
  10. )
  11. echo %SysTS%
  12. pause
复制代码
【方案2】BAT + WMIC
  1. @echo off
  2. for /f "tokens=2 delims==" %%i in ('wmic path win32_operatingsystem get LocalDateTime /value ^| findstr "="') do (
  3.     set "strDate=%%i"
  4. )
  5. set "Today=%strDate:~0,4%%strDate:~4,2%%strDate:~6,2%"
  6. echo,%Today%
  7. pause
  8. set "Now=%strDate:~0,4%-%strDate:~4,2%-%strDate:~6,2% %strDate:~8,2%:%strDate:~10,2%:%strDate:~12,2%"
  9. echo %Now%
  10. pause
复制代码
【方案3】BAT + mshta
  1. @echo off
  2. for /f %%i in ('mshta "vbscript:CreateObject("Scripting.FileSystemObject").GetStandardStream(1).WriteLine(Right(Year(Now),4)&Right("0"&Month(Now),2)&Right("0"&Day(Now),2))(Window.Close)"') do (
  3.     set "Today=%%i"
  4. )
  5. echo,%Today%
  6. pause
复制代码
【方案4】BAT + VBS
  1. @echo off
  2. >"%temp%\DateCalculate.vbs" echo dt=date()
  3. >>"%temp%\DateCalculate.vbs" echo s=right(year(dt),4) ^& "-" ^& right("0" ^& month(dt),2) ^& "-" ^& right("0" ^& day(dt),2)
  4. >>"%temp%\DateCalculate.vbs" echo wscript.echo s
  5. for /f %%a in ('cscript /nologo "%temp%\DateCalculate.vbs"') do (
  6.     set Today=%%a
  7. )
  8. echo,%Today%
  9. pause
复制代码
【方案5】BAT + REG
  1. @echo off
  2. REM 无法保证在中、英之外的其它语言的操作系统上得到正确结果
  3. for /f "delims=" %%a in ('reg query "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate') do (
  4.     set "RegDateOld=%%a"
  5. )
  6. set RegDateOld=%RegDateOld:~-8%
  7. reg add "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate /t REG_SZ /d yyyy-M-d /f>nul
  8. set Today=%date: =%
  9. reg add "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate /t REG_SZ /d %RegDateOld% /f>nul
  10. set "Week=Mon Tue Wed Thu Fri Sat Sun 星期一 星期二 星期三 星期四 星期五 星期六 星期日"
  11. for %%a in (%Week%) do (
  12.     call set "Today=%%Today:%%a=%%"
  13. )
  14. echo,%Today%
  15. pause
复制代码
【方案6】BAT + REG
  1. @echo off
  2. for /f "delims=" %%a in ('reg query "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate') do (
  3.     set "RegDateOld=%%a"
  4. )
  5. set RegDateOld=%RegDateOld:~-8%
  6. reg add "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate /t REG_SZ /d yyyy-M-d /f>nul
  7. set Today=%date: =%
  8. reg add "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate /t REG_SZ /d %RegDateOld% /f>nul
  9. if "%Today:~0,1%" gtr "9" (
  10.     set Today=%Today:~-10%
  11. ) else (
  12.     set Today=%Today:~0,10%
  13. )
  14. echo,%Today%
  15. pause
复制代码
【方案7】BAT + REG
  1. @echo off
  2. for /f "delims=" %%a in ('reg query "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate') do (
  3.     set "RegDateOld=%%a"
  4. )
  5. set RegDateOld=%RegDateOld:~-8%
  6. reg add "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate /t REG_SZ /d yyyy-M-d /f>nul
  7. type nul>"%temp%\MyFile.tmp"
  8. for /f %%a in ('dir "%temp%\MyFile.tmp" ^| findstr /i "MyFile.tmp"') do (
  9.     set Today=%%a
  10. )
  11. reg add "HKEY_CURRENT_USER\Control Panel\International" /v sShortDate /t REG_SZ /d %RegDateOld% /f>nul
  12. echo,%Today%
  13. pause
复制代码
【方案8】BAT + REGEDIT
  1. @echo off
  2. REM 需要保证注册表编辑器没有处于锁定状态
  3. regedit /e "%temp%\bak.reg" "HKEY_CURRENT_USER\Control Panel\International"
  4. >"%temp%\new.reg" echo REGEDIT4
  5. >>"%temp%\new.reg" echo,
  6. >>"%temp%\new.reg" echo [HKEY_CURRENT_USER\Control Panel\International]
  7. >>"%temp%\new.reg" echo "sShortDate"="yyyy-MM-dd"
  8. regedit /s "%temp%\new.reg"
  9. set Today=%date: =%
  10. regedit /s "%temp%\bak.reg"
  11. if "%Today:~0,1%" gtr "9" (
  12.     set Today=%Today:~-10%
  13. ) else (
  14.     set Today=%Today:~0,10%
  15. )
  16. echo,%Today%
  17. pause
复制代码
【方案9】BAT + DEBUG
  1. @echo off
  2. for /f "tokens=6,8 delims== " %%a in ('^(echo a100^&echo mov ah^,2a^&echo int 21^&echo.^&echo p 2^&echo q^)^|debug^|find "CX"') do (
  3.     set /a y=0x%%a
  4.     set md=%%b
  5. )
  6. set /a m=0x%md:~,2%
  7. set /a d=0x%md:~-2%
  8. set m=0%m%
  9. set d=0%d%
  10. set Today=%y%-%m:~-2%-%d:~-2%
  11. echo,%Today%
  12. pause
复制代码
以下转载两个在DOS系统(不是Windows系统的CMD)里面获取日期、时间的代码:
原文:http://www.cn-dos.net/forum/viewthread.php?tid=19756
【willsort原始版】
  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
复制代码
【willsort简化版】
  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)
复制代码

作者: defanive    时间: 2009-2-13 23:04

作为个人作品,在小范围内流通不需要考虑这么多。。。

当然,鼓励LZ。。。
作者: zqz0012005    时间: 2009-2-13 23:42

不错的总结。
  1. wmic path win32_operatingsystem get LocalDateTime
  2. wmic os get LocalDateTime
复制代码
纯P的话,这个我常用
作者: Batcher    时间: 2009-2-25 16:36     标题: 回复 2楼 的帖子

确实如此。
不过等你参加工作以后,可能会发现自己的代码需要兼容各种各样的环境。
^_^
作者: pumahxh    时间: 2009-11-7 10:40     标题: 回复 4楼 的帖子

我在win98 MS-DOS4.10下,就不能使用%time%来引用当前时间,echo %time%的结果还是%time%。这就是环境不同的结果吧。能告诉我为什么会这样呢?
作者: Batcher    时间: 2009-11-7 11:11     标题: 回复 5楼 的帖子

DOS系统里面没有%date%、%time%等环境变量,顶楼添加了两种在DOS系统里面的解决方案。
作者: lky216    时间: 2012-5-19 09:25

很多种方法,研究一下
作者: starifly    时间: 2013-1-29 23:08

mark一下,明日再研究
作者: victory610    时间: 2013-1-31 17:01

学习了,感谢楼主。
作者: fsxt    时间: 2017-5-25 11:21

感谢分享!!!
作者: ai20110304    时间: 2019-3-15 19:24

不错的分享
作者: Aloha    时间: 2020-12-29 08:25

厉害&#128077;&#127995;
作者: swanseabrian    时间: 2021-7-29 20:16

回复 4# Batcher


    主管,我想请问下关于日期的,下面这个代码是啥意思呀,可以解释一下吗
set yy=%1&set mm=%2&set dd=%3
if 1%yy% LSS 200 if 1%yy% LSS 170 (set yy=20%yy%) else (set yy=19%yy%)


这个yy我计算出来是2021,搞不懂这一句,谢谢
作者: jave000    时间: 2021-10-21 16:20

回复 1# Batcher


  请问方案一里的today获取的是211021,如何才能获取20211021?
谢谢
作者: idwma    时间: 2021-10-21 18:30

回复 14# jave000
  1. powershell -c "'{0:yyyyMMdd}' -f (get-date)"
复制代码

作者: jave000    时间: 2021-10-22 14:27

回复 15# idwma


    谢谢:)
作者: Echo11    时间: 2022-2-23 08:18     标题: BAT+WMIC获取任意格式日期时间timestamp、时区timezone

本帖最后由 Echo11 于 2022-2-23 08:22 编辑

该方案限制于WMIC,目前在win 11 22000.469 中测试。
据说未来win 11 会因安全问题去掉WMIC。
到时候想继续用WMIC,就需要在含有WMIC的系统版本中备份以下文件(不同语言需要备份对应语言的WMIC.exe.mui):
C:\Windows\System32\wbem\WMIC.exe
C:\Windows\System32\wbem\zh-CN\WMIC.exe.mui
然后按原路径还原到不含WMIC的win XX系统。
  1. :Solu9
  2. REM 学习以下两个链接以及子链接中内容后融合Timezone数据编写,方便任意拼接
  3. REM 【方案2】BAT + WMIC http://bbs.bathome.net/thread-3328-2-1.html
  4. REM stackoverflow链接 https://stackoverflow.com/questions/11037831/filename-timestamp-in-windows-cmd-batch-script-getting-truncated
  5. @echo off
  6. for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
  7. set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
  8. set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%" & set "Ms=%dt:~15,3%"
  9. REM Ms 毫秒,这里我取了3位,按实际需求也可以取2位或1位
  10. set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%"
  11. set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%.%Ms%"
  12. echo datestamp: "%datestamp%"
  13. echo timestamp: "%timestamp%"
  14. echo fullstamp: "%fullstamp%"
  15. REM 时区 方法1 继续从dt变量获取定位时区的相关值 Bias
  16. REM UTC 偏移 +480分钟=+08小时
  17. set "sign=%dt:~21,1%" & set "bias=%dt:~22,3%"
  18. set /a "bias=bias/60+100"
  19. echo timezone: "UTC%sign%%bias:~1,2%:00"
  20. REM 时区 方法2 直接从 wmic TimeZone get Caption /value 提取时区信息
  21. for /f "tokens=2 delims=^(^)" %%t in ('wmic TimeZone get Caption /value') do set "timezone=%%t"
  22. echo timezone: "%timezone%"
  23. pause
  24. EXIT /B 0
复制代码

作者: Echo11    时间: 2022-2-23 12:43     标题: [日期时间]批处理生成邮件头里的日期格式 (更新时间: 23 Feb 2022)

本帖最后由 Echo11 于 2022-2-23 13:08 编辑

(由于没有权限单独发帖。在此回复了。)
[日期时间]批处理生成邮件头里的日期格式 (更新时间:Wed, 23 Feb 2022 12:29:34 +0800)
如:Date: Wed, 23 Feb 2022 12:29:34 +0800

在用批处理发送邮件前需要生成“mail”本身,而mail包含mail header 和 mail content。mail header 遵从RFC 5322标准。
Win系统中无法直接获取这种格式的日期时间,因此我写了这个批处理来干这件事。



一、RFC 5322中关于日期的格式要求如下(非标准原文):
## Mail Date Reference
  date            =   day month year                 ; 应当表示本地时间
  time            =   time-of-day zone
----------------------------------------------------------------------------------------------
  day-name        =   "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"
  day             =   ([FWS] 1*2DIGIT FWS) / obs-day ; 一个月的第几天
  month           =   "Jan" / "Feb" / "Mar" / "Apr" /
                      "May" / "Jun" / "Jul" / "Aug" /
                      "Sep" / "Oct" / "Nov" / "Dec"
  year            =   (FWS 4*DIGIT FWS) / obs-year  ; 四位数字
----------------------------------------------------------------------------------------------
  time-of-day     =   hour ":" minute [ ":" second ] ; 应当表示本地时间, 一天中的时:分[:秒],
                                                     ; 范围00:00:00 - 23:59:60

   hour            =   2DIGIT / obs-hour

   minute          =   2DIGIT / obs-minute

   second          =   2DIGIT / obs-second

   zone            =   (FWS ( "+" / "-" ) 4DIGIT) / obs-zone
                       ; date与time-of-day偏离UTC或GMT的偏差\
                       ; +表示ahead of(即east of)UTC, -表示behind(即west of) UTC
                       ; 前两个数字表示hours偏差, 后两个数字表示minutes偏差
                       ; +hhmm表示 +(hh * 60 + mm) 分钟, -hhmm表示 -(hh * 60 + mm) 分钟
                       ; "+0000"用于表示UTC的时区
                       ; "-0000"用于表示本地时区生成的时间, date-time不包含本地时区的信息

sample:
Date: Wed, 23 Feb 2022 12:29:34 +0800



二、我的批处理
  1. :MailDate
  2. REM 获取以下邮件头中的日期时间
  3. REM Date: Wed, 23 Feb 2022 12:29:34 +0800
  4. @echo off
  5. for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
  6. set "year=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "day=%dt:~6,2%" & set "time-of-day=%dt:~8,2%:%dt:~10,2%:%dt:~12,2%"
  7. set "dn1=Mon" & set "dn2=Tue" & set "dn3=Wed" & set "dn4=Thu" & set "dn5=Fri" & set "dn6=Sat" & set "dn7=Sun"
  8. set "mon01=Jan" & set "mon02=Feb" & set "mon03=Mar" & set "mon04=Apr" & set "mon05=May" & set "mon06=Jun" & set "mon07=Jul" & set "mon08=Aug" & set "mon09=Sep" & set "mon10=Oct" & set "mon11=Nov" & set "mon12=Dec"
  9. setlocal enabledelayedexpansion
  10. for /f "tokens=2 delims==" %%b in ('wmic path win32_localtime Get DayOfWeek /value') do set "dow=%%b"
  11. set "day-name=!dn%dow%!" & set month=!mon%MM%!
  12. for /f "tokens=2 delims=^(^)" %%t in ('wmic TimeZone Get Caption /value') do set "zone=%%t"
  13. set "zone=!zone:U=!" & set "zone=!zone:T=!" & set "zone=!zone:C=!" & set "zone=!zone::=!"
  14. echo.Mail Date:
  15. echo.Date: %day-name%, %day% %month% %year% %time-of-day% %zone%
  16. endlocal
  17. pause>nul
  18. EXIT /B 0
复制代码
三、执行结果如下:
  1. Mail Date:
  2. Date: Wed, 23 Feb 2022 12:43:00 +0800
复制代码

作者: alredstone    时间: 2022-4-23 13:28

感谢分享。最近正好需要在英文版系统和中文版系统间切换




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