batch file scripts to get current date and current time in sortable ISO 8601 format
Posted by jpluimers on 2011/01/10
ISO 8601 is a great format for date and time (and combined) values.
It allows for both interchange of information, and ease of sorting values.
Recently, I had to create some backup and logging scripts for a 3rd party turn-key installation at a client.
You know: the kind of installation where the 3rd party manages to break their own scripts, but at the mean time close the system so much, that you cannot do anything but standard batch-file scripts.
The system runs partially on a Workstation that is based on a Dutch version of Windows XP, and a server that runs an English version of Windows Server 2008.
Recipe for some twiddling in order to keep the scripts working on both systems, and not to get bitten by localization.
This answer to a StackOverflow question got me a nice head-start: it was said to work in both the English and Portugese versions of Windows.
This post is the process to get correctly function batch-files towards the end of the post.
Of course, we Dutch are persistent enough to have yet different output for the %date% pseudo variable and the date and date /t commands.
The same holds for the %time% pseudo variable and the time and time /t commands.
Another peculiarity, is the discrepancy between documentation and reality.
According to the Microsoft Windows XP commandline shell overview documentation, %date% uses the same format as the date /t command, the same should hold for %time% and time /t.
For %date% and date /t, this is in fact true for both English and Dutch:
C:\temp>echo:|date Huidige datum: ma 03-01-2011 Voer de nieuwe datum in: (dd-mm-jj) C:\temp>date /t ma 03-01-2011 C:\temp>echo %date% ma 03-01-2011 C:\temp>echo:|date The current date is: Mon 01/03/2011 Enter the new date: (mm-dd-yy) C:\temp>date /t Mon 01/03/2011 C:\temp>echo %date% Mon 01/03/2011
But for %time% and time /t, this is false:
C:\temp>echo:|time Huidige tijd: 22:37:15,91 Voer de nieuwe tijd in: C:\temp>time /t 22:37 C:\temp>echo %time% 22:37:15,91 C:\temp>echo:|time The current time is: 22:39:11.87 Enter the new time: C:\temp>time /t 10:39 PM C:\temp>echo %time% 22:39:11.87
Actually, this is a good thing, as with %temp%, you can get the fractions of seconds, if you take into account the decimal separator (, or .).
Finally, the original batch file assumed two things would stay constant for localized versions of the commandline shell:
- The echo:|date command would use yy as year token
- The echo:|date command would use non-hyphens displaying the date, and hyphens when entering the date.
Both were false for the Dutch language, so that needs adoption too.
So I did some work, and posted a new answer with an adapted date batch file, and a new answer with a time batch file on StackOverflow.
If you have a system different from English or Dutch, please test the results, and see if they look like this:
C:\temp>set-time-cmd.bat Now is Hour: [22] Minute: [04] Second: [25] Fraction: [04] 220425.04 C:\temp>set-date-cmd.bat Today is Year: [2011] Month: [01] Day: [03] 20110103 C:\temp>
First the time batch file, as this is the easiest one.
It consists of a loop with parenthesis so that you can run multiple set statements inside the loop.
We take the output of %time%, which we get by sending it through the echo command (otherwise the for loop wants to find a file).
The token delimiters :,.-/ split the time in four tokens, based on the various time separators that can be used in different locales.
Luckily the oder of the tokens is always hh, mm, ss and ff.
Command Extensions are needed because of the for /F syntax.
@ECHO off SETLOCAL ENABLEEXTENSIONS for /f "tokens=1-4 delims=:,.-/ " %%i in ('echo %time%') do ( set 'hh'=%%i set 'mm'=%%j set 'ss'=%%k set 'ff'=%%l) ENDLOCAL & SET v_Hour=%'hh'%& SET v_Minute=%'mm'%& SET v_Second=%'ss'%& SET v_Fraction=%'ff'% ECHO Now is Hour: [%V_Hour%] Minute: [%V_Minute%] Second: [%v_Second%] Fraction: [%v_Fraction%] set timestring=%V_Hour%%V_Minute%%v_Second%.%v_Fraction% echo %timestring% :EOF
Then the date batch file, which is much more complex.
Adoption means taking these differences into account:
- The English version uses yy for the year (even if you want a four-digit year), the Dutch windows version uses jj.
All locales however seem to have the year at the end, hence the change from set ‘%%c’=%%k into set ‘yy’=%%k - The English version of echo:|date emits the date using the native delimters (slashes) and the mask using dashes.
The Dutch version will use dashes for both, so the original code will execute the inner loop twice.
The solution is a check just before the inner loop: otherwise you end up with temporary variables like ”.
This is the check: if “%%a” GEQ “A” ( - Finally, the Dutch
Then, the assumptions of echo:^|date in this batch file, which were not phrased in the original one:
- The tokens will be returned as the last three tokens on the second line
- The first line will have numbers in the last three tokens
- Of the last three tokens on the second line, the first two will be always called mm and dd (and can be in the order mm/dd or dd/mm)
- The last token on the second line will always be the year
Finally the assumptions of date /t in relation to the tokens:
- The order of the values in date /t are the same as the tokens in echo:^|date
- The values of the tokens mm and dd will always be 2 digits
So here is the date batch-file:
@ECHO off SETLOCAL ENABLEEXTENSIONS if "%date%A" LSS "A" (set toks=1-3) else (set toks=2-4) ::DEBUG echo toks=%toks% for /f "tokens=2-4 delims=(-)" %%a in ('echo:^|date') do ( ::DEBUG echo first token=%%a if "%%a" GEQ "A" ( for /f "tokens=%toks% delims=.-/ " %%i in ('date/t') do ( set '%%a'=%%i set '%%b'=%%j set 'yy'=%%k ) ) ) if %'yy'% LSS 100 set 'yy'=20%'yy'% set Today=%'yy'%-%'mm'%-%'dd'% ENDLOCAL & SET v_year=%'yy'%& SET v_month=%'mm'%& SET v_day=%'dd'% ECHO Today is Year: [%V_Year%] Month: [%V_Month%] Day: [%V_Day%] set datestring=%V_Year%%V_Month%%V_Day% echo %datestring% :EOF
Finally a link to all the commandline shell commands in alphabetical order.
Have fun with this batch file!
–jeroen
ISO 8601 Date, Time and DateTime in Delphi (was: Simple example to show DateTime.Now in ISO 8601 format on ideone.com | Online C# Compiler & Debugging Tool) « The Wiert Corner – irregular stream of Wiert stuff said
[…] to show DateTime.Now in ISO 8601 format on ideone.com | Online C# Compiler & Debugging Tool , using ISO 8601 in batch-files, and how ISO 8601 is used in Google Calendar […]
Simple example to show DateTime.Now in ISO 8601 format on ideone.com | Online C# Compiler & Debugging Tool « The Wiert Corner – irregular stream of Wiert stuff said
[…] wrote about using ISO 8601 in batch-files and with Google Calendar […]
Roger said
You could easily write the same with Dr.Batcher ( http://www.drbatcher.com ), a tool designed especially for writing batch scripts without programming. It seems to me that it would be easier than writing all this code.
jpluimers said
I know, but at some clients you don’t have the luxury of using the tools of your choice.