The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 4,261 other subscribers

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:

  1. The echo:|date command would use yy as year token
  2. 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:

  1. The tokens will be returned as the last three tokens on the second line
  2. The first line will have numbers in the last three tokens
  3. 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)
  4. The last token on the second line will always be the year

Finally the assumptions of date /t in relation to the tokens:

  1. The order of the values in date /t are the same as the tokens in echo:^|date
  2. 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

4 Responses to “batch file scripts to get current date and current time in sortable ISO 8601 format”

  1. […] 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 […]

  2. […] wrote about using ISO 8601 in batch-files and with Google Calendar […]

  3. 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.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.