无论区域设置如何,在批处理文件中拆分 %date%

Posted

技术标签:

【中文标题】无论区域设置如何,在批处理文件中拆分 %date%【英文标题】:Split %date% in a batch file regardless of Regional Settings 【发布时间】:2013-02-28 23:57:55 【问题描述】:

有没有办法将%date% 拆分为批处理文件(例如,在 3 个环境变量中),但不考虑区域设置?今天的日期将是美国的 3/13/2013,但在我的区域设置中,它是 13.3.2013 - 分隔符已更改,顺序也已更改

【问题讨论】:

这是一个很好的问题。我想用数字分隔,但那行不通……我需要考虑一下。 谢谢。我现在正在互联网上搜索,我想我找到了一些东西,但我不喜欢它如何使用REG QUERY。 forums.techguy.org/dos-other/… 我认为有两种方法可以做到这一点。 1. 您可以创建一堆子字符串并交叉检查它们以确定如何显示它,或者 2. 您可以通过某种方式访问​​区域设置并从那里开始。 啊哈!看here! 一个小问题是 WMIC 不包含在 XP Home... 【参考方案1】:

您可以这样做using wmic(但 WMIC 不包含在 XP Home 中):

@ECHO OFF
:: Check WMIC is available
WMIC.EXE Alias /? >NUL 2>&1 || GOTO s_error

:: Use WMIC to retrieve date and time
FOR /F "skip=1 tokens=1-6" %%G IN ('WMIC Path Win32_LocalTime Get Day^,Hour^,Minute^,Month^,Second^,Year /Format:table') DO (
   IF "%%~L"=="" goto s_done
      Set _yyyy=%%L
      Set _mm=00%%J
      Set _dd=00%%G
      Set _hour=00%%H
      SET _minute=00%%I
)
:s_done

:: Pad digits with leading zeros
      Set _mm=%_mm:~-2%
      Set _dd=%_dd:~-2%
      Set _hour=%_hour:~-2%
      Set _minute=%_minute:~-2%

:: Display the date/time in ISO 8601 format:
Set _isodate=%_yyyy%-%_mm%-%_dd% %_hour%:%_minute%
Echo %_isodate%

GOTO:EOF

:s_error
Echo GetDate.cmd
Echo Displays date and time independent of OS Locale, Language or date format.
Echo Requires Windows XP Professional, Vista or Windows 7
Echo.
Echo Returns 6 environment variables containing isodate,Year,Month,Day,hour and minute.

您可以通过parsing the date command 来查找当前日期格式的要求。

第一个链接表明您可能需要在 Win7 上编辑第二个链接中的代码,以处理短日期/长日期表单周围的一些额外皱纹。

【讨论】:

感谢您提供“解析日期命令”的链接 (robvanderwoude.com/amb_datetime.php)【参考方案2】:

我在http://forums.techguy.org/dos-other/837046-solved-date-format-bat-file.html找到这个

我对其进行了一些修改,将其实际拆分为 3 个环境变量。

缺点是需要查询注册表,大概要查到订单的日月年。

@Echo Off
Set _Date=%date%
If "%_Date%A" LSS "A" (Set _NumTok=1-3) Else (Set _NumTok=2-4)
:: Default Delimiter of TAB and Space are used
For /F "TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v iDate') Do Set _iDate=%%B
For /F "TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v sDate') Do Set _sDate=%%B
IF %_iDate%==0 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%_Date%") Do Set _fdate=%%D%%B%%C
IF %_iDate%==1 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%_Date%") Do Set _fdate=%%D%%C%%B
IF %_iDate%==2 For /F "TOKENS=%_NumTok% DELIMS=%_sDate% " %%B In ("%_Date%") Do Set _fdate=%%B%%C%%D
Set _Month=%_fdate:~4,2%
Set _Day=%_fdate:~6,2%
Set _Year=%_fdate:~0,4%
Echo _Year=%_Year%
Echo _Month=%_Month%
Echo _Day=%_Day%

【讨论】:

【参考方案3】:

REG QUERY 是不够的,如果 sShortDate 设置为类似dd yy。使用REG ADD:

@echo off &setlocal
for /f "tokens=2*" %%a in ('reg query "HKCU\Control Panel\International" /v sShortDate^|find "REG_SZ"') do set "ssShortDate=%%b"
reg add "HKCU\Control Panel\International" /f /v sShortDate /d "dd MM yyyy" >nul
set "cdate=%date%"
reg add "HKCU\Control Panel\International" /f /v sShortDate /d "%ssShortDate%" >nul
for /f "tokens=1-3" %%i in ("%cdate%") do set "day=0%%i"&set "month=0%%j"&set "year=%%k"
set "day=%day:~-2%"
set "month=%month:~-2%"
echo.%day%.%month%.%year%
endlocal

【讨论】:

如果没有外部二进制文件(例如 wmic、robocopy),则无法批量获取有效日期,而是自行设置注册表。 datedircommands 总是从注册表的国际设置中显示 sShortDate【参考方案4】:

我已经重新设计了sashoalm 的版本以处理抑制前导零的情况:

@Echo OFF
SETLOCAL
If "%Date%A" LSS "A" (Set _NumTok=1-3) Else (Set _NumTok=2-4)
:: Default Delimiter of TAB and Space are used
For /F "TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v iDate') Do Set _iDate=%%B
For /F "TOKENS=2*" %%A In ('REG QUERY "HKCU\Control Panel\International" /v sDate') Do Set _sDate=%%B
IF %_iDate%==0 For /F "TOKENS=%_NumTok% DELIMS=%_sdate% " %%F In ("%Date%") Do CALL :procdate %%H %%F %%G
IF %_iDate%==1 For /F "TOKENS=%_NumTok% DELIMS=%_sdate% " %%F In ("%Date%") Do CALL :procdate %%H %%G %%F
IF %_iDate%==2 For /F "TOKENS=%_NumTok% DELIMS=%_sdate% " %%F In ("%Date%") Do CALL :procdate %%F %%G %%H
endlocal&SET YYYYMMDD=%YYYYMMDD%
GOTO :eof

::
:: Date elements are supplied in Y,M,D order but may have a leading zero
::
:procdate
:: if single-digit day then 1%3 will be <100 else 2-digit
IF 1%3 LSS 100 (SET YYYYMMDD=0%3) ELSE (SET YYYYMMDD=%3)
:: if single-digit month then 1%2 will be <100 else 2-digit
IF 1%2 LSS 100 (SET YYYYMMDD=0%2%YYYYMMDD%) ELSE (SET YYYYMMDD=%2%YYYYMMDD%)
:: Similarly for the year - I've never seen a single-digit year
IF 1%1 LSS 100 (SET YYYYMMDD=20%YYYYMMDD%) ELSE (SET YYYYMMDD=%1%YYYYMMDD%)
GOTO :eof

根据您的意愿返回 YYYYMMDD - 子字符串。

有趣的是,在SETLOCAL之后插入

IF NOT "%1"=="" set date=%1

将允许将本地序列中的任何日期(没有日期名称)解码为 YYYYMMDD(但请注意,yy 表单中提供的 19xx 日期将显示为 20xx - 如果您认为有必要,可以轻松补偿)

【讨论】:

这不起作用,如果用户在 Windows 控制面板中将日期格式设置为例如dd yy(您的代码输出为:13130)。 抑制前导零的情况是什么? @mfm4aa 那是因为dd yy 是您可以设置的格式,但没有任何意义。 @sashoalm %date% 变量使用的格式是短日期格式。 Control Panel&gt;Region and Language&gt;Additional Settings&gt;Date tab - 您可以输入将被报告的格式。如果您输入 d,则日期编号将显示为 1..9 的一位数。如果您输入dd,那么将为 1..9 添加一个前导零。 mmm 同上一个月。不同的人使用不同的格式... @mfm4aa 那是因为 mm yy 也是一种格式 - 毫无疑问是众多格式之一 - 您可以设置,但没有意义【参考方案5】:

下面有一个纯批处理解决方案,它只使用 DATE 命令和 %DATE% 变量,因此它适用于任何 Windows 版本。为了使这个程序真正通用,只需添加其他语言的 DATE 命令第二行显示的日期和月份部分的名称,并用斜杠括起来。例如,假设在德语中,日部分显示为 TT,因此您只需修改此值:set DayNames=/dd/tt/ 以便在德语 Windows 中也使用该程序(除了所有使用 DD 表示当天的语言部分)。

@echo off
setlocal EnableDelayedExpansion

rem GetStdDate.bat: Get date in standard format independently of Regional Settings
rem Antonio Perez Ayala

rem Set Day and Month names shown by second line of DATE command, enclosed in slashes (add any missing language):
set DayNames=/dd/
set MonthNames=/mm/

rem Get date NAMES from second line of date COMMAND, enclosed in parentheses
for /F "skip=1 tokens=2 delims=()" %%n in ('date ^< NUL') do (
   rem Separate and store date names
   for /F "tokens=1-3 delims=/-.:" %%a in ("%%n") do (
      set one=%%a& set two=%%b& set three=%%c
      rem Get date VALUES from %date% VARIABLE
      for /F "tokens=1-3 delims=/-.:" %%x in ("%date%") do (
         rem Assign date values to date names
         set %%a=%%x& set %%b=%%y& set %%c=%%z
      )
   )
)

rem Identify locale date format and assemble StdDate=YYYY/MM/DD
if "!DayNames:/%one%/=!" neq "%DayNames%" (
   rem Locale format is DD/MM/YYYY
   set StdDate=!%three%!/!%two%!/!%one%!
) else if "!MonthNames:/%one%/=!" neq "%MonthNames%" (
   rem Locale format is MM/DD/YYYY
   set StdDate=!%three%!/!%one%!/!%two%!
) else (
   rem Locale format is YYYY/MM/DD
   set StdDate=!%one%!/!%two%!/!%three%!
)

echo Standard date: %StdDate%

【讨论】:

感谢您的回答。不过,你能描述一下你的方法吗?例如,是否使用外部实用程序等。 请将windows控制面板中的日期格式设置为dd yy,你会看到,这不起作用(输出:Standard date: 13 03//)。每个用户都可以将日期格式设置为任何他想要的。 date 命令取决于该设置(也在重定向中)。 好吧,nearly 有效。它在 %date% 中存在日期名称的默认情况下不起作用。它也不能作为通用格式正常工作,其中当地年份格式为 yy 而不是 yyyy 或月份 m 不是 mm 或日 d 不是 dd 例如例程的结果“13/3 /12" 表示 2013/03/12 或 2012/3/13 由人类解释时?现在 - 这些问题中的每一个都可以解决 - 例如,for/f "tokens=1-4"...%date%... 将仅在存在日期名称(并且可能是第一个)时分配第四个元变量,并且可以使用一些数学/子字符串应用前导零跨度> 【参考方案6】:

我对 robocopy 有一个额外的建议:

@echo off &setlocal enabledelayedexpansion
set "day="
for /f "tokens=3,4,8skip=4delims=: " %%i in ('robocopy') do if not defined day (
    set "month=%%i"
    set "day=0%%j"
    set "year=%%k"
)
set /a cnt=0
for %%i in (Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) do (
    set /a cnt+=1
    if "%%i"=="%month%" set "month=0!cnt!"
)
set "day=%day:~-2%"
set "month=%month:~-2%"
echo.%day%.%month%.%year%
endlocal

【讨论】:

【参考方案7】:

试试这个:Set_date.cm

@echo off&goto :start
:Set_Date DateEnv [Date] or [/p="Prompt for Date: "] [/r]
echo.
echo.Usage: Set_Date.cmd DateEnv [Date] or [/p="Prompt for Date: "]
echo.Populates date variables labeled: 'DateEnv_???', see below
echo.Accepted date formats:
echo.        m-d-y, m/d/y, yyyymmdd, dd-Mon-yy or 7 digit julian date
echo.        If "%%date%%" is passed as the 2nd arg it will be interpreted
echo.        according to the current regional date setting ie. day dd/mm/yyyy
echo.        If /r is passed then the date contained in the DateEnv variable
echo.        and/or the [Date] argument will be interpreted in regional format
echo.        The /r option should be placed at the end of the list if used
echo.        The /r option should only be used if date input is not included
echo.        in one of the default listed formats or unexpected consequences...
echo.
echo.DateEnv, if passed alone may be a valid defined date variable or if
echo.undefined then todays date will be used to populate the variables
echo.Two digit years input 'XX' are interpreted as the year '20XX'
echo.Valid dates must be in the year 1601 or greater for the validity check
echo.Returns 0 in errorlevel if the date is valid, else non-zero
echo.
echo.If DateEnv is valid or if [Date] is passed DateEnv_??? will be set to:
echo.DateEnv_mdy will be set to mm-dd-yyyy
echo.DateEnv_ymd will be set to yyyymmdd
echo.DateEnv_y.m.d will be set to yyyy.mm.dd
echo.DateEnv_dte will be set to the current active regional date format
echo.DateEnv_jul will be set to the 7 digit Julian date
echo.DateEnv_dow will be set to day of week, ie. Monday, Tuesday, etc.
echo.DateEnv_vrb will be set to Verbose Date, ie. Saturday, August 20th, 2011
echo.DateEnv_dd will be set to the 2 digit day
echo.DateEnv_mm will be set to the 2 digit month
echo.DateEnv_yyyy will be set to the 4 digit year
echo.DateEnv_month will be set to the month, ie. February or December
echo.DateEnv_mon will be set to the 3 letter month, ie. Jan or Aug
echo.
echo.DateEnv itself will not be changed regardless if its a valid date or not
echo.Also formats yyyymmdd or 7 digit julian date input to desired output
echo.Example: Set_Date today "%%date%%" or Set_Date newyear99 01-Jan-99
echo.
echo.Finally:
echo.If DateEnv is not defined and there is no second argument then %%date%% in
echo.the current regional format will be used to populate the variables
echo.If /p is passed as 2nd argument then quoted 3rd argument will prompt for date
echo.
echo.Examples:
echo.         set "AprilsFools=4/1/1"
echo.         set_date AprilFools
echo.         echo Aprils fools date for 2001 in Julian format is: %%AprilFools_jul%%
echo.         echo Aprils fools date in 2001 was on a %AprilFools_dow% ^(Sunday^)
echo.         Set_Date birthday /p="Enter your birth date: "
echo.         ECHO You were born on a %%birthday_dow%%
echo.         set "today="
echo.         Set_Date today
echo.         echo today is %%today_dte%% or %%today_jul%% in Julian format
echo.
echo.If the '/p' option is used then the _GetString.cmd routine must be in the PATH
echo.         or else set/p routine will ask for date with no validity checking
exit /b 1

:start
set "jul="&set "Format="&set "Sep="&set "reg="
if "%~1"=="" exit /b 255
if /i "%~1" equ "/?" goto :Set_Date Syntax
SetLocal EnableDelayedExpansion
echo %*|find /i "/r">nul
if %errorlevel% equ 0 set/a reg=1&if /i "%~1" equ "/r" shift
if defined %~1 (call set jul=%%%~1%%) else (
  if "%~2"=="" set "jul=%date%"
)
if not "%~2"=="" (
  if /i "%~2" neq "/r" (
    set "jul=%~2"&set "args=%~3"
  )
) else (if not defined %~1 set/a reg=1)
call :RegDateFmt Format Separator yy mm dd jul
if %errorlevel% neq 0 goto :BadDate
if /i "%~2" equ "%date%" set/a reg=1
if defined reg (
  set "jul=!mm!-!dd!-!yy!"
)
if /i "%jul%" equ "/p" (
  call :_GetString.cmd "%args%" jul /d
  if !errorlevel! gtr 0 goto :BadDate
) else if /i "%jul:~0,1%" gtr "9" (
  if defined args set "jul=%jul% %args%"
  set "jul=!jul:* =!"
) else if /i "%jul:~3,1%" gtr "9" (
  set "Mon=%jul:~3,3%"
  call :month_convert Mon
  if !errorlevel! gtr 0 goto :BadDate
  set "jul=!Mon!-%jul:~0,2%-%jul:~-2%"
)
set mdy=%jul:/=%
set mdy=%mdy:-=%
if /i %mdy% equ %jul% (
  call :strlen %mdy%
  if /i !errorlevel! equ 7 ( 
    call :date_cvt mdy /j
  ) else (call :date_cvt jul /j)
) else (call :date_cvt jul /j)
if /i %errorlevel% equ 0 (
  set/a mdy=%jul%
  set/a dow=%jul% %% 7&call :set_day dow
) else (goto :BadDate)
call :date_cvt mdy /j
set "vrb=%mdy%"
call :format_verbose vrb dow month
set/a ymd=%errorlevel%
set "mon=%month:~0,3%"
set/a dte=%ymd%
call :setRegDate dte Format Separator dow mon
if /i %errorlevel% gtr 0 goto :BadDate
Endlocal&(
  call set "%~1_mdy=%mdy%"&call set "%~1_ymd=%ymd%"&call set "%~1_jul=%jul%"
  call set "%~1_vrb=%vrb%"&call set "%~1_dow=%dow%"&call set "%~1_dd=%ymd:~-2%"
  call set "%~1_mm=%mdy:~0,2%"&call set "%~1_yyyy=%ymd:~0,4%"
  call set "%~1_mon=%mon%"&call set "%~1_yy=%ymd:~2,2%"&call set "%~1_dte=%dte%"
  call set "%~1_y.m.d=%ymd:~0,4%.%mdy:~0,2%.%ymd:~-2%"&call set "%~1_month=%month%"
  exit /b 0
)
:BadDate
Endlocal&(
  call set "%~1_mdy="&call set "%~1_ymd="&call set "%~1_dte="&call set "%~1_jul="
  call set "%~1_vrb="&call set "%~1_dow="&call set "%~1_vrb="&call set "%~1_y.m.d="
  call set "%~1_month="
)&exit /b %errorlevel%

::**********************************::
::*******||  SUBROUTINES   ||*******::
::**********************************::

:set_day
SetLocal&call set/a tkn=%%%~1%%+1
for /f "tokens=%tkn%" %%a in ("Monday Tuesday Wednesday Thursday Friday Saturday Sunday") do (
  set "dayofwk=%%a"
)
EndLocal&call set %~1=%dayofwk%&exit /b 1

:Date_Cvt DateEnv [/Julian] Date_env is converted
if "%~1"=="" exit /b 1
SetLocal&call set "mdy=%%%~1%%"
set ech=&set "arg="
if not "%~2"=="" (set arg=%~2&set arg=!arg:~0,2!)
xcopy /d:%mdy% /h /l "%~f0" "%~f0\">nul 2>&1
if /i %errorlevel% equ 0 (
  for /f "tokens=1-3 delims=/- " %%a in ("%mdy%") do (
    set m=%%a&set d=%%b&set "y=%%c"
    if /i 1!m! lss 20 set "m=0!m!"
    if /i 1!d! lss 20 set "d=0!d!"
    if /i 1!y! lss 20 set "y=0!y!"
    if /i !y! lss 80 (set y=20!y!) else (if !y! lss 100 set y=19!y!)
    set "mdy=!m!-!d!-!y!"
  )
) else (
  set /a rc=1
  for /f "tokens=1-3 delims=0123456789" %%a in ("%mdy%") do set "rc=%%a"
  if /i !rc! neq 1 set /a err=2&goto :end
  call :strlen %mdy%
  if /i !errorlevel! gtr 8 set /a err=3&goto :end
)
set "mdy=%mdy:/=-%"
set "ymd=%mdy:-=%"
if %ymd%==%mdy% (
  call :strlen %ymd%
  set /a err=!errorlevel!
  if /i !err! equ 7 if /i "%arg%" equ "/j" (
    call :gdate %ymd%
    set /a ymd=!errorlevel!
    set /a err=8&set "arg="
  )
  if /i !err! neq 8 goto :end
  set mdy=!ymd:~4,2!-!ymd:~6,2!-!ymd:~0,4!&set "ech=!mdy!"
) else (
  set ymd=%ymd:~4,4%%ymd:~0,4%&set "ech=!ymd!"
)
xcopy /d:%mdy% /h /l "%~f0" "%~f0\">nul 2>&1
set /a err=%errorlevel%
if /i %err% neq 0 (set ech=)
if /i %err% equ 0 if /i "%arg%" equ "/j" (
  call :jdate %ymd%
  set /a ech=!errorlevel!
)
:end
EndLocal&call set "%~1=%ech%"&exit /b %err%

:Strlen Returns length of string in errorlevel
setlocal&set "#=%*"
if not defined # exit /b 0
set/a len=0
:loop
set/a len+=1
set "#=!#:~1!"&if not defined # endlocal&exit/b %len%
goto :loop

:jdate
SetLocal
set "yyyymmdd=%~1"
set "yyyy=%yyyymmdd:~0,4%"
set "mm=%yyyymmdd:~4,2%"
set "dd=%yyyymmdd:~6,2%"
if %mm:~0,1% equ 0 set "mm=%mm:~1%"
if %dd:~0,1% equ 0 set "dd=%dd:~1%"
set /a Month1=(%mm%-14)/12
set /a Year1=%yyyy%+4800
set /a JDate=1461*(%Year1%+%Month1%)/4+367*(%mm%-2-12*%Month1%)^
             /12-(3*((%Year1%+%Month1%+100)/100))/4+%dd%-32075
EndLocal&exit /b %JDate%

:gdate
SetLocal
set /a p      = %1 + 68569
set /a q      = 4 * %p% / 146097
set /a r      = %p% - ( 146097 * %q% +3 ) / 4
set /a s      = 4000 * ( %r% + 1 ) / 1461001
set /a t      = %r% - 1461 * %s% / 4 + 31
set /a u      = 80 * %t% / 2447
set /a v      = %u% / 11
set /a GYear  = 100 * ( %q% - 49 ) + %s% + %v%
set /a GMonth = %u% + 2 - 12 * %v%
set /a GDay   = %t% - 2447 * %u% / 80
if /i 1%GMonth% lss 20 set "GMonth=0%GMonth%"
if /i 1%GDay%   lss 20 set "GDay=0%GDay%"
set "GDate=%GYear%%GMonth%%GDay%"
EndLocal&exit /b %GDate%

:Format_Verbose M/D/Y dayofweek to verbose date
SetLocal&call set "dte=%%%~1%%"
set "dow=%%%~2%%"
set "st="
set "day=%dte:~3,2%"
set "mon=%dte:~0,2%"
set "year=%dte:~6,4%"
set "ymd=%year%%mon%%day%"
set "dy=%day:~1%"
if %day:~0,1% equ 0 set "day=%day:~1%"
if %mon:~0,1% equ 0 set "mon=%mon:~1%"
set months=January February March April May June^
 July August September October November December
for /f "tokens=%mon%" %%a in ("%months%") do set "month=%%a"
if /i %dy% equ 0 set "st=th"
if /i %dy% gtr 3 set "st=th"
if /i %day% geq 11 if /i %day% leq 13 set "st=th"
if defined st goto :end
set/a rst=%day% %% 10
for /f "tokens=%rst%" %%s in ("st nd rd") do set "st=%%s"
:end
set "dow=%dow%, %month% %day%%st%, %year%"
EndLocal&call set %~1=%dow%&call set %~3=%month%&exit /b %ymd%

:_GetString.cmd
set p0=%0&set "p0=!p0:~1!"
if not exist _GetString.cmd (
  call :checkpath %p0%
  if !errorlevel! neq 0 (
    set/p %~2="%~1"
    exit/b 0
  )
)
call _GetString.cmd "%~1" %~2 %~3
exit/b %errorlevel%

:checkpath
if exist "%~$PATH:1" exit/b 0
exit/b 1

:RegDateFmt Format Separator y m d dte
if "%~2"=="" exit/b 1
setlocal EnabledelayedExpansion
set "Day="&set "Mon="&set "dte="
if not "%~6"=="" set "dte=!%~6!"
if not defined dte set "dte=%date%"
for /f "tokens=2 delims=:" %%A in ('date^<nul') do set Format=%%A&goto :next
:next
set "Format=%Format: =%"
for %%A in (/ - . ,) do (
  echo %Format%|find "%%A">nul&if !errorlevel! equ 0 set "Separator=%%A"
)
if /i %Format:~0,1% gtr 9 set "Day=Day "
for /f "skip=1 tokens=2-4 delims=(-)" %%a in ('date^<nul') do (
  set "Format=%Day%%%a%Separator%%%b%Separator%%%c"
  for /f "tokens=1-3 delims=.-/ " %%d in ("%dte:* =%") do (
    set %%a=%%d&set %%b=%%e&set "%%c=%%f"
    echo !yy:~3!|find "ECHO">nul
    if /i "!errorlevel!" neq "0" set "Format=!Format:yy=yyyy!"
    if /i "!mm:~0,1!" gtr "9" (
      set "Format=!Format:mm=Mon!"
      call :month_convert mm
      if /i "!errorlevel!" neq "0" endlocal&exit/b 1
    )
  )
)
endlocal&(
  call set "%~1=%Format%"
  call set "%~2=%Separator%"
  if not "%~3"=="" call set "%~3=%yy%"
  if not "%~4"=="" call set "%~4=%mm%"
  if not "%~5"=="" call set "%~5=%dd%"
)&exit/b 0

:month_convert
set "months=Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
call set "month=%%%~1%%"
set/a mnum=0
for %%m in (%months%) do set/a mnum+=1&if /i %month% equ %%m call set "%~1=!mnum!"&exit /b 0
exit/b 1

:setRegDate dte format sep dow mon
setlocal EnableDelayedExpansion
if /i "%~5"=="" exit/b 1
set mon=!%~5!&set dow=!%~4!&set "dow=!dow:~0,3! "
set sep=!%~3!&set "format=!%~2!"&set "dte=!%~1!"
set yyyy=%dte:~0,4%&set yy=%dte:~2,2%&set mm=%dte:~4,2%&set "dd=%dte:~-2%"
set "toks=2-4"
echo %format%|find " ">nul
if %errorlevel% equ 1 set "dow="& set "toks=1-3"
for /f "tokens=%toks% delims=%sep% " %%a in ("%format%") do (
  set "dte=%dow%!%%a!%sep%!%%b!%sep%!%%c!"
)
endlocal&call set "%~1=%dte%"&exit/b 0 

【讨论】:

【参考方案8】:

此功能应适用于所有地区。

备注:

以文本格式返回 MMM 区域的月份

@echo off
  call :GetDateIntl year month day 
  echo/Using GetDateIntl you get: %year%-%month%-%day%
goto:eof

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:GetDateIntl yy mm dd [/A]
:: Returns the current date on any machine with regional-independent settings
:: Arguments:
::   yy = variable name for the year output
::   mm = variable name for the month output
::   dd = variable name for the day output
::   /A = OPTIONAL, removes leading 0 on days/months smaller than 10 (example: 01 becomes 1)
:: Remarks:
::  Will return month in text format in regions with MMM month
::
SETLOCAL ENABLEEXTENSIONS
if "%date%A" LSS "A" (set toks=1-3) else (set toks=2-4)
for /f "tokens=2-4 delims=(-)" %%a in ('echo:^|date') do (
  for /f "tokens=%toks% delims=.-/ " %%i in ('date/t') do (
    set '%%a'=%%i
    set '%%b'=%%j
    set '%%c'=%%k
  )
)
if /I "%'yy'%"=="" set "'yy'=%'aa'%"
if /I "%'yy'%"=="" ( set "'yy'=%'jj'%" & set "'dd'=%'tt'%" )
if %'yy'% LSS 100 set 'yy'=20%'yy'%
endlocal&set %1=%'yy'%&set %4 %2=%'mm'%&set %4 %3=%'dd'%&goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

【讨论】:

如果这在您的系统上不起作用,请告诉我 echo:|date 的输出,以便我更新代码。谢谢! 如果这对所有方面都有效,那么响应被低估了。在这里工作,但是我一年得到 4 位数。【参考方案9】:

四年过去了,但这个问题并没有变老,我认为现在有一个比使用 wmic 更好的答案(从 win7 开始)。

for /F "tokens=1,2,3 delims=_" %%i in ('PowerShell -Command "& Get-Date -format "MM_dd_yyyy""') do (
    set MONTH=%%i
    set DAY=%%j
    set YEAR=%%k
)
echo %MONTH% %DAY% %YEAR%

使用 powershell Get-Date,您可以微调所需的格式(短、长、数字、名称等)。在此示例中,“MM_dd_yyyy”将为您提供一个带有前导零的数字日期,以防单个数字月或日

【讨论】:

那么干净。非常有用。 这会改变我的命令提示符窗口的大小和字体。我怎样才能避免这种情况? @Bricktop 您的问题可能与此superuser.com/questions/706562/… 有关

以上是关于无论区域设置如何,在批处理文件中拆分 %date%的主要内容,如果未能解决你的问题,请参考以下文章

Matlab中如何只把figure中的图像区域保存为图片文件

如何使用字符串中的单词在批处理文件中拆分字符串

如何在 Swift 中从文件扩展名中拆分文件名?

拆分 WIX 文件

有没有办法在 Thymeleaf 中使用 #dates 来仅包含日、月和年,同时保持区域设置格式?

如何根据行的内容拆分pyspark数据框