5

I'm writing a batch script and I need the unix time. It's easy under linux, but I can't figure out how to do this in windows.

whoabackoff
  • 1,603
  • 4
  • 17
  • 32
  • 1
    Maybe [this](http://stackoverflow.com/questions/203090/how-to-get-current-datetime-on-windows-command-line-in-a-suitable-format-for-us) will help. – ArtemStorozhuk Jun 20 '12 at 17:17

3 Answers3

15

Here is a native batch solution that should work in any locale. It uses WMIC to get the current local time in a locale independent manner. Everything else is a "simple" matter of string parsing and basic math.

:UnixTime  [ReturnVar]  [TimeStamp]
::
:: Computes the Unix time from the current local time as reported by the
:: operating system. The Unix time is the number of seconds that have elapsed
:: since midnight Coordinated Universal Time (UTC), January 1, 1970, not
:: counting leap seconds.
::
:: The result is returned in variable ReturnVar,
:: or the result is echoed if ReturnVar is not specified
::
:: If the TimeStamp is provided in the 2nd parameter, then the Unix time for
:: the TimeStamp is computed, rather then for the current time.
::
:: The TimeStamp must have the same format as used by WMIC:
::
::   YYYYMMDDhhmmss.ffffffSzzz
::
:: where:
::
::   YYYY   = gregorian year
::   MM     = month
::   DD     = day
::   hh     = hour in 24 hour format
::   mm     = minute
::   ss     = seconds
::   ffffff = fractional seconds (microseconds)
::   S      = timezone sign: + or -
::   zzz    = timezone: minutes difference from GMT
::
:: Each component must be zero prefixed as needed to maintain the proper width.
::
:: The ReturnVar parameter must be provided in order to use the TimeStamp.
:: A ReturnVar of "" will function the same as no ReturnVar. This enables the
:: specification of a TimeStamp without an actual ReturnVar.
::
@echo off
setlocal
set "ts=%~2"
if not defined ts for /f "skip=1 delims=" %%A in ('wmic os get localdatetime') do if not defined ts set "ts=%%A"
set /a "yy=10000%ts:~0,4% %% 10000, mm=100%ts:~4,2% %% 100, dd=100%ts:~6,2% %% 100"
set /a "dd=dd-2472663+1461*(yy+4800+(mm-14)/12)/4+367*(mm-2-(mm-14)/12*12)/12-3*((yy+4900+(mm-14)/12)/100)/4"
set /a ss=(((1%ts:~8,2%*60)+1%ts:~10,2%)*60)+1%ts:~12,2%-366100-%ts:~21,1%((1%ts:~22,3%*60)-60000)
set /a ss+=dd*86400
endlocal & if "%~1" neq "" (set %~1=%ss%) else echo %ss%
exit /b


Note that this solution has a limited life span. It will cease to work on 2038-01-19 when the Unix time exceeds the maximum value of a signed 32 bit integer.

EDIT - The code has been edited to support conversion of a timestamp string on the command line instead of the current local time. The precise range of times supported is 1901-12-13 20:45:52.000000 through 2038-01-19 03:14:07.999999 GMT. Times prior to 1970-01-01 00:00:00.000000 will yield negative values.

dbenham
  • 127,446
  • 28
  • 251
  • 390
  • @pizza - That is news to me. The script works fine for me on Windows 7 without admin privs. I'm pretty sure it works on other Windows versions as well. Did you actually test the script? And if so, what Windows version? – dbenham Jun 20 '12 at 22:49
  • winxp: Failed to register mof file(s). Only the administrator group members can use WMIC.EXE. Reason:Win32 Error: Access is denied. – pizza Jun 20 '12 at 22:51
  • @pizza - I confirmed the code works on Vista and Windows 7 without admin rights (at least by default). WMIC is available on XP Professional, but not XP Home. I'm not sure what the default privilege requirements are on XP Professional. – dbenham Jun 21 '12 at 02:57
  • There is a somewhat related posts here: http://stackoverflow.com/a/4783062/1276280 note the comments. Try create a new user id on 7/vista without special authority, I suspect it does not work either. – pizza Jun 21 '12 at 04:33
  • 1
    I just tried on 7pro, it does work on a normal user id. Just not XP unfortunately. Otherwise the batch is pretty cool. – pizza Jun 21 '12 at 04:42
3

If by "unix time" you mean the epoch second, then Windows doesn't include tools to produce that. Instead, you can install third-party tools. For example:

  • Install Cygwin.
  • Find the date binary (under C:\Cygwin\ or wherever you installed it)
  • Use it as you would in Linux.

Alternately, per the awesome comment on this answer, you could install GNU Coreutils which also include a date command. It includes a number of other tools that you may not need, but then, so does Cygwin.

ghoti
  • 45,319
  • 8
  • 65
  • 104
  • No need to install Cygwin just to get a single tool. Most (all?) GNU tools can be downloaded and used without Cygwin –  Jun 20 '12 at 17:20
  • 1
    +1... it's the right answer. There are a number of other Unixy layers for Windoze, UWIN etc, but everybody uses Cygwin. Also might be worth explaining that Windows ain't Unix, of course you can't get epoch seconds (natively)! – ormaaj Jun 20 '12 at 17:35
  • I tried GnuWin32 on Windows and it doesn't work for dates before 1970. On Linux it works and it returns negative numbers. date +%s --date "31 Dec 1969" should return -86400 but it returns "invalid date" to me – Joe Jobs Jan 06 '21 at 16:40
3

You can use vbscript in windows, the interpreter is available on your system.

'--------------------epoch.vbs----------------------- 
option explicit
dim s,o,z
for each o in GetObject("winmgmts:").InstancesOf ("Win32_OperatingSystem")
z=o.CurrentTimeZone
next
s=DateDiff("s", "01/01/1970 00:00:00", Now())-(60*z)
wscript.echo(s)
wscript.quit
pizza
  • 7,296
  • 1
  • 25
  • 22