views:

435

answers:

4

From the windows command line, I need to echo out either the local or utc date and time of the system, but with the parts of the datetime in the order I want, regardless of the current internationalization setting of the pc.

I've seen this related question:
http://stackoverflow.com/questions/203090/how-to-get-current-datetime-on-windows-command-line-in-a-suitable-format-for-usi

Thanks.

A: 

Hey Scott, try this

echo off
for /F "tokens=1,2*" %%a in ('date /T') do set date=%%a %%b
echo %date%
set strMonth=%date:~0,2%
set strDay=%date:~3,2%
set strYear=%date:~6,4%
set strMonth
set strDay
set strYear

BTW: took some code from here... http://www.computing.net/answers/dos/system-date-to-variable/3874.html

Keng
Thanks for the try! That works on a US system, but not many other place. Eg, on a UK system it produces:01/04/2009strMonth=01strDay=04strYear=2009With the month and day the wrong way around.
Scott Langham
oh, and THAT's the part that is the unknown....gottcha...didn't understand the depth of the issue.
Keng
yes, i should have made that a bit clearer
Scott Langham
+2  A: 

If you don't mind using a little VBScript you can use something like this:

' http://classicasp.aspfaq.com/date-time-routines-manipulation/can-i-make-vbscript-format-dates-for-me.html
' Use MSSTDFMT to mimic VB's Format() function. Provides more flexibility in
' formatting dates than the VBScript FormatDateTime() function.
On Error Resume Next
    dim fmt
    dim rs

    set fmt = WScript.CreateObject("MSSTDFMT.StdDataFormat") 
    set rs = WScript.CreateObject("ADODB.Recordset") 

    rs.Fields.Append "fldExpression", 12 ' adVariant 
    rs.Open 
    rs.AddNew 


    fmt.Format = WScript.Arguments(0)

    rs("fldExpression").DataFormat = fmt 
    rs("fldExpression").Value = Now() 

    WScript.Echo rs("fldExpression").Value 

    rs.close
    set fmt = nothing
    set rs = nothing

    WScript.Quit(0)

I put this in a file called formatDate.vbs. You can then call from the command line, passing in the format you want:

C:>cscript //nologo formatDate.vbs "mm-dd-yyyy" 
04-02-2009 
C:>cscript //nologo formatDate.vbs "dd-mm-yyyy"
02-04-2009 
C:>cscript //nologo formatDate.vbs "dd-MMM-yy" 
02-Apr-09
C:>cscript //nologo formatDate.vbs "mm/dd/yyyy hh:mm"
04/02/2009 10:10
C:>cscript //nologo formatDate.vbs "dddddd ttttt"
Friday, April 03, 2009 6:48:57 AM
C:>cscript //nologo formatDate.vbs "General Date"
4/3/2009 6:49:53 AM

See Predefined Date/Time Formats and User-Defined Date/Time Formats in the MSDN for a complete list of formats you can use.

NOTE: The MSSTDFMT object depends on the availability of MSSTDFMT.dll, which is installed by Visual Studio 6.0.

The MSSTDFMT.dll appears to be available on Windows XP and Windows 2003 servers; I checked a few machines that have never had MS Visual Studio installed and the DLL was present.

Patrick Cuff
+1  A: 

Put the following in a file called something like "GetLocalTime.vbs".

Function Pad( strText, intLen )
    Pad = Right( String( intLen, "0" ) & strText, intLen )
End Function

Dim d
d = Now
wscript.echo Pad(Year(d),4) & "-" & Pad(Month(d),2) & "-" & Pad(Day(d),2) & "T" & Pad(Hour(d),2) & ":" & Pad(Minute(d),2) & ":" & Pad(Second(d),2)

Run with:

cscript GetLocalTime.vbs //Nologo

This outputs:

2009-04-02 14:22

And can be adapted to write out the date-time parts in any order.

Scott Langham
I couldn't find a solution that didn't require script from outside the pure windows command line world. I'd still prefer something that doesn't depend on an external file so only one batch file needs to be copied around.
Scott Langham
I suppose the batch file could pipe out the vbs to a file in the temp folder and run that.
Scott Langham
There's a very minor risk if this code is called during a midnight transition at the end of month/year, that, e.g. your call to Month will get the old value, but your call to Day gets the new value
Damien_The_Unbeliever
Thanks, fixed and updated the answer.
Scott Langham
Do you believe now?
Scott Langham
That looks better.
Damien_The_Unbeliever
+1  A: 

I use a small variation of the GetDate.cmd script to get only the date:

@SETLOCAL
@ECHO OFF
GOTO :begin
:fixdate
IF "%1:~0,1%" GTR "9" SHIFT
FOR /f "skip=1 tokens=2-4 delims=(-)" %%g IN ('echo.^|date') DO (SET %%g=%1& SET %%h=%2& SET %%i=%3)
GOTO :eof
:begin
FOR /f "tokens=1-4 delims=/-. " %%g IN ('date /t') DO (CALL :fixdate %%g %%h %%i %%j)
ECHO %aa%%yy%%mm%%dd%
ENDLOCAL

It takes advantage of the format output by date and deals with the case when date /t prints the weekday name before the year/month/day information. The original script, however, doesn't behave correctly when the format strings aren't yy, mm and dd. I've added a workaround which makes the script work for both English and Portuguese systems: in Portuguese the year format is aa; so the statement %aa%%yy% will print the year at %aa% and blank at %yy%, but the opposite happens on English systems.

There are, however, safer techniques which involve parsing the date format from the Registry.

Romulo A. Ceccon