viewtopic.php?f=3&t=3428
The code below contains the ParseDateTime macro which wraps .NET functions in a little PowerShell code. The date and/or time strings to be converted are redirected to the standard input. The current date and time is assumed for an empty string or in case nothing is redirected. The output of the macro is a space-separated string with 10 tokens.
You are able to customize the code by adding specific format patterns.
For more information refer to the description in the code.
Note: Even if all examples in the code below are successfully converted for me, don't assume they can be converted for you as well. They contain localized German strings which are expected to fail on machines where German isn't the default culture. Replace them with the localized strings for your default language settings.
Code: Select all
@echo off &setlocal
:: The ParseDateTime macro reads a string from StdIn and tries to parse it as
:: DateTime value.
:: If an empty string is redirected or if the macro is executed without a
:: redirected string, the current date and time will be assumed.
:: If the macro succeeds to parse the string, it outputs 10 space-separated
:: values with fixed lengths:
:: yyyy MM dd HH mm ss fff n iii ww
:: yyyy year
:: MM month
:: dd day
:: HH hours (00 .. 24)
:: mm minutes
:: ss seconds
:: fff fraction (milliseconds)
:: n day of week (0 for Sunday .. 6 for Saturday)
:: iii day of year (001 .. 365/366)
:: ww ISO 8601 week of year
:: Date values which are not specified in the input string are set to 1.
:: Time values are set to 0, respectively.
::
:: DMTF (CIM_DATETIME), ISO 8601, and RFC1123 formatted datetime strings are
:: supported. Long and short date and time strings are converted as long as
:: they meet the invariant or the local format.
:: Extra spaces in the converted string are automatically ignored.
:: For more information about standard formats refer to:
:: https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings
::
:: The macro can be customized by specifying additional format strings. Right
:: now the list of custom formats in $cfo contains only one string for input
:: from the asctime C function (as used in ROBOCOPY). However, more format
:: strings can be appended, separated by a comma each. E.g.:
:: $cfo=[string[]]('ddd MMM d HH:mm:ss yyyy','HH:mm \h');^
:: For a list of custom format specifiers and syntax refer to:
:: https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings
set ParseDateTime=powershell -nop -ep Bypass -c ^"$s=[string]$input;if(-Not $s){$dt=[DateTime]::Now}else{^
$cfo=[string[]]('ddd MMM d HH:mm:ss yyyy');^
$ic=[Globalization.CultureInfo]::InvariantCulture;^
try{$dt=[DateTime]::ParseExact($s,$cfo,$ic,15)}catch{^
try{$dt=[DateTime]::ParseExact($s,$cfo,$null,15)}catch{^
try{$dt=[Management.ManagementDateTimeConverter]::ToDateTime($s)}catch{^
$s=$s -replace '(\d),(\d)','$1.$2';^
try{$dt=[DateTime]::Parse($s,$ic,143)}catch{^
try{$dt=[DateTime]::Parse($s,$null,143)}catch{^
exit}}}}}}$dow=[int]$dt.DayOfWeek;($dt.toString('yyyy MM dd HH mm ss fff ')+$dow+$dt.DayOfYear.toString(' 000')+^
$(Get-Culture).Calendar.GetWeekOfYear($(if($dow -match '[1-3]'){$dt.AddDays(3)}else{$dt}),2,1).toString(' 00'))^"
:: EXAMPLES:
echo *** no redirected string, leading zeros removed using SET /A ***
for /f "tokens=1-10" %%a in ('%ParseDateTime%') do set /a "year=1%%a-10000,mon=1%%b-100,day=1%%c-100,hh=1%%d-100,mm=1%%e-100,ss=1%%f-100,ms=1%%g-1000,dow=%%h,doy=1%%i-1000,woy=1%%j-100"
echo year %year%
echo month %mon%
echo day %day%
echo hours %hh%
echo minutes %mm%
echo seconds %ss%
echo milliseconds %ms%
echo day of week %dow%
echo day of year %doy%
echo week of year %woy%
echo(
echo *** several tests, beginning with an empty string ***
for %%S in (
"" %= an empty string results in the output of the current date and time =%
"19720126204745.800000+060" %= DMTF formatted (as received from WMI) =%
"26.01.1972 20:47:45,80" %= date and time variables, localized German output (comma as decimal separator) =%
" 26. 01. 1972 20: 47: 45,80 " %= date and time, localized German, extra spaces =%
"26/01/1972 20:47:45.80" %= different date and decimal separators =%
"26.01.1972" %= date only, localized German output =%
"26.01.72" %= date only, localized German, year with 2 digits =%
"1972-01-26" %= different order and separator, ISO 8601 =%
"Januar 1972" %= German month + year =%
"January 1972" %= English month + year =%
"20:47:45,80" %= time only, localized German =%
"08:47:45.80 PM" %= time only, English =%
"20:47:45" %= time without fraction =%
"20:47" %= time without seconds =%
"1972-01-26T20:47:45.8Z" %= RFC3339, ISO 8601 UTC notation =%
"1972-01-26T20:47:45.8+1:00" %= RFC3339, ISO 8601 with offset =%
"Wed Jan 26 20:47:45 1972" %= C asctime()-like (as received from ROBOCOPY) =%
"Mi Jan 26 20:47:45 1972" %= same but localized German =%
"Wed 1972-Jan-26 20:47:45" %= as received from MAKECAB =%
"Wed, 26 Jan 1972 20:47:45 GMT" %= RFC1123 =%
"Mittwoch, 26. Januar 1972 20:47:45" %= long localized German =%
"January, 26 1972 20:47:45" %= long English =%
"Wednesday, January 26, 1972 8:47:45.8 PM" %= another long English =%
) do (
REM Note that the surrounding quotes are removed for the redirection.
echo(%%~S
for /f "tokens=1-10" %%a in ('echo(%%~S^|%ParseDateTime%') do echo -^> y:%%a M:%%b d:%%c H:%%d m:%%e s:%%f ms:%%g DoW:%%h DoY:%%i WoY:%%j
echo(
)
pause
Output on my machine:
Code: Select all
*** no redirected string, leading zeros removed using SET /A ***
year 2021
month 2
day 22
hours 22
minutes 19
seconds 16
milliseconds 486
day of week 1
day of year 53
week of year 8
*** several tests, beginning with an empty string ***
-> y:2021 M:02 d:22 H:22 m:19 s:16 ms:830 DoW:1 DoY:053 WoY:08
19720126204745.800000+060
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:800 DoW:3 DoY:026 WoY:04
26.01.1972 20:47:45,80
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:800 DoW:3 DoY:026 WoY:04
26. 01. 1972 20: 47: 45,80
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:800 DoW:3 DoY:026 WoY:04
26/01/1972 20:47:45.80
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:800 DoW:3 DoY:026 WoY:04
26.01.1972
-> y:1972 M:01 d:26 H:00 m:00 s:00 ms:000 DoW:3 DoY:026 WoY:04
26.01.72
-> y:1972 M:01 d:26 H:00 m:00 s:00 ms:000 DoW:3 DoY:026 WoY:04
1972-01-26
-> y:1972 M:01 d:26 H:00 m:00 s:00 ms:000 DoW:3 DoY:026 WoY:04
Januar 1972
-> y:1972 M:01 d:01 H:00 m:00 s:00 ms:000 DoW:6 DoY:001 WoY:52
January 1972
-> y:1972 M:01 d:01 H:00 m:00 s:00 ms:000 DoW:6 DoY:001 WoY:52
20:47:45,80
-> y:0001 M:01 d:01 H:20 m:47 s:45 ms:800 DoW:1 DoY:001 WoY:01
08:47:45.80 PM
-> y:0001 M:01 d:01 H:20 m:47 s:45 ms:800 DoW:1 DoY:001 WoY:01
20:47:45
-> y:0001 M:01 d:01 H:20 m:47 s:45 ms:000 DoW:1 DoY:001 WoY:01
20:47
-> y:0001 M:01 d:01 H:20 m:47 s:00 ms:000 DoW:1 DoY:001 WoY:01
1972-01-26T20:47:45.8Z
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:800 DoW:3 DoY:026 WoY:04
1972-01-26T20:47:45.8+1:00
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:800 DoW:3 DoY:026 WoY:04
Wed Jan 26 20:47:45 1972
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:000 DoW:3 DoY:026 WoY:04
Mi Jan 26 20:47:45 1972
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:000 DoW:3 DoY:026 WoY:04
Wed 1972-Jan-26 20:47:45
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:000 DoW:3 DoY:026 WoY:04
Wed, 26 Jan 1972 20:47:45 GMT
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:000 DoW:3 DoY:026 WoY:04
Mittwoch, 26. Januar 1972 20:47:45
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:000 DoW:3 DoY:026 WoY:04
January, 26 1972 20:47:45
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:000 DoW:3 DoY:026 WoY:04
Wednesday, January 26, 1972 8:47:45.8 PM
-> y:1972 M:01 d:26 H:20 m:47 s:45 ms:800 DoW:3 DoY:026 WoY:04
Drücken Sie eine beliebige Taste . . .
The 15 passed to the 4th parameter of ParseExact and the 143 passed to the 3rd parameter of Parse are DateTimeStyles AllowWhiteSpaces + NoCurrentDateDefault (+ RoundtripKind).
The 2 passed to the 2nd parameter of GetWeekOfYear is the CalendarWeekRule FirstFourDayWeek, the 1 passed to the 3rd parameter is the DayOfWeek Monday.
Steffen