【问题标题】:Safe way to get current day month and year in batch批量获取当前日期月份和年份的安全方法
【发布时间】:2012-09-28 07:30:51
【问题描述】:

我正在尝试编写一个批处理脚本,该脚本将以安全的方式获取当前的日期、月份和年份(即独立于日期格式)。不幸的是,我发现的所有互联网资源都提出了类似的建议:

   SET CURRENT_DATE=%DATE: =0%
   SET YEAR=%DATE:~-4%
   SET MONTH=%DATE:~3,2%
   SET DAY=%DATE:~5,2%

如果我的日期格式为 yyyy/mm/dd 或 yyyy-mm-dd,这将有效,但如果它的格式为 yy-mm-dd 或其他格式,则无效。有没有一种安全的方法来获取年月日?

还有一个问题 - 是否有可能知道日期分隔符是什么(在第一种情况下是/,在其他情况下是-)。

【问题讨论】:

标签: windows date batch-file


【解决方案1】:

此代码的前四行将在 XP Pro 及更高版本中为您提供可靠的 YY DD MM YYYY HH Min Sec 变量。

@echo off
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"

set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%"
set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
pause

这是一个 VBS 解决方案:

  :: date time using WSH/VBS
  :: datetime.bat V4.2
  ::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  ::
  :: This uses Windows Scripting Host to set variables to
  :: the current date/time/day/day_number/week_of_year etc
  :: for Win9x/ME/NT/W2K/XP/Vista/Win7/Win8 etc
  :: Thanks go to Todd Vargo for his scripting
  ::
  ::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  @echo off
  set TmpFile="%temp%.\tmp.vbs"
  echo> %TmpFile% n=Now
  echo>>%TmpFile% With WScript
  echo>>%TmpFile% .Echo "set m1="   + monthname(month(n), true)
  echo>>%TmpFile% .Echo "set m2="   + monthname(month(n), false)
  echo>>%TmpFile% .Echo "set woy="  + CStr(datepart("ww", n))
  echo>>%TmpFile% .Echo "set year=" + CStr(Year(n))
  echo>>%TmpFile% .Echo "set yr="   + Right(Year(n),2)
  echo>>%TmpFile% .Echo "set month="+ Right(100+Month(n),2)
  echo>>%TmpFile% .Echo "set day="  + Right(100+Day(n),2)
  echo>>%TmpFile% .Echo "set hour=" + Right(100+Hour(n),2)
  echo>>%TmpFile% .Echo "set min="  + Right(100+Minute(n),2)
  echo>>%TmpFile% .Echo "set sec="  + Right(100+Second(n),2)
  echo>>%TmpFile% .Echo "set dow="  + WeekDayName(Weekday(n),1)
  echo>>%TmpFile% .Echo "set dow2=" + WeekDayName(Weekday(n))
  echo>>%TmpFile% .Echo "set iso="  + CStr(1 + Int(n-2) mod 7)
  echo>>%TmpFile% .Echo "set iso2=" + CStr(Weekday(n,2))
  echo>>%TmpFile% End With
  cscript //nologo "%temp%.\tmp.vbs" > "%temp%.\tmp.bat"
  call "%temp%.\tmp.bat"
  del  "%temp%.\tmp.bat"
  del  %TmpFile%
  set TmpFile=
  set stamp=%year%-%month%-%day%.%hour%_%min%_%sec%

  if not "%~1"=="" goto :EOF

  echo The year  is "%year%" or "%yr%"
  echo The month is "%month%" "%m1%" "%m2%"
  echo The day   is "%day%" "%dow%" "%dow2%"
  echo.
  echo ISO8601 Day-Of-Week number is "%iso%" and week of year is: "%woy%"

  echo.
  echo The time in hh:mm:ss is "%hour%:%min%:%sec%"
  echo The hour   is "%hour%"
  echo The minute is "%min%"
  echo The second is "%sec%"
  echo.

  echo The date and time stamp is "%stamp%"
  echo.
  echo date A yyyymmdd "%year%%month%%day%"
  echo date B mmddyyyy "%month%%day%%year%"
  echo date C ddmmyyyy "%day%%month%%year%"
  echo date D yymmdd   "%yr%%month%%day%"
  echo date E mmddyy   "%month%%day%%yr%"
  echo date F ddmmyy   "%day%%month%%yr%"
  pause
  :: datetime.bat
  ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

【讨论】:

    【解决方案2】:

    提取日、月和年(与区域无关)

    我不会使用 WMIC,因为它占用大量资源并且需要一段时间才能完成,尤其是在速度较慢的计算机上。以下脚本从注册表中获取用户的本地化信息,这与语言环境无关。据我所知,是唯一有效的批处理解决方案。当然,您也可以调用 VBScript,但对我来说这是题外话。

    @echo off
    
    ::: Begin set date
    setlocal EnableExtensions EnableDelayedExpansion
    
    :: Determine short date format (independent from localization) from registry
    for /f "skip=1 tokens=3-5 delims=- " %%L in ( '2^>nul reg query "HKCU\Control Panel\International" /v "sShortDate"' ) do ( 
    
        :: Since we can have multiple (short) date formats we only use the first char from the format in a new variable
        set "_L=%%L" && set "_L=!_L:~0,1!" && set "_M=%%M" && set "_M=!_M:~0,1!" && set "_N=%%N" && set "_N=!_N:~0,1!"
    
        :: Now assign the date values to the new vars
        for /f "tokens=2-4 delims=/-. " %%D in ( "%date%" ) do ( set "!_L!=%%D" && set "!_M!=%%E" && set "!_N!=%%F" )
    )
    
    
    :: Print the values as is
    echo.
    echo This is the original date string --^> %date%
    echo These are the splitted values    --^> Day: %d%, Month:%m%, Year: %y%.
    echo.
    
    endlocal
    

    只提取年份

    对于我编写的脚本,我只想提取年份(与语言环境无关),所以我想出了这个 oneliner,因为我找不到任何解决方案。它使用“DATE”变量、多个分隔符并检查大于 31 的数字。那将是当前年份。与其他一些解决方案相比,它的资源较少。

    @echo off
    
    setlocal EnableExtensions
    
    for /f " tokens=2-4 delims=-./ " %%D in ( "%date%" ) do ( if %%D gtr 31 ( set "_YEAR=%%D" ) else ( if %%E gtr 31 ( set "_YEAR=%%E" ) else ( if %%F gtr 31 ( set "_YEAR=%%F" ) ) ) )
    
    echo And the year is... %_YEAR%.
    echo.
    
    endlocal
    

    【讨论】:

      【解决方案3】:

      首先,您可以从注册表(某处)检索当前设置。
      格式和分隔符。

      但是改用wmic 会更容易,它的格式始终相同,唯一的缺点是,每次启动都需要一些时间。

      来自SO: Log Date/Time的修改样本

      @echo off
      setlocal EnableDelayedExpansion
      FOR /F "skip=1 tokens=1-6" %%A IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
          if "%%B" NEQ "" (
              SET /A FDATE=%%F*10000+%%D*100+%%A
              SET /A FTIME=%%B*10000+%%C*100+%%E
          )
      )
      ECHO !FDATE! - !FTIME!
      

      【讨论】:

      • setlocal EnableDelayedExpansion 做了什么,为什么在这个例子中需要它?
      • 它启用了延迟扩展(哇!),最好阅读set /?的帮助。说实话:这里没有必要 :-),您可以简单地将 echo 更改为 echo %FDATE% - %FTIME%
      猜你喜欢
      • 2013-02-15
      • 2021-12-16
      • 2016-03-13
      • 1970-01-01
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 2021-07-17
      • 2016-03-12
      相关资源
      最近更新 更多