"date+%s"命令在Windows中的等效命令是什么?

6

我正在编写一个批处理脚本,需要使用Unix时间。在Linux下很容易实现,但是我无法弄清楚如何在Windows下实现。


1
也许这个链接可以帮到你。 - ArtemStorozhuk
3个回答

15

这里有一个本地批处理解决方案,可以在任何语言环境下工作。它使用WMIC以一种与语言环境无关的方式获取当前本地时间。其他所有内容都是“简单”的字符串解析和基本数学运算。

: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


请注意,此解决方案的使用寿命有限。当Unix时间超过32位带符号整数的最大值时,即2038年01月19日,它将停止工作。

编辑 - 代码已被编辑以支持在命令行上转换时间戳字符串而不是当前本地时间。支持的精确时间范围为1901年12月13日20:45:52.000000至2038年01月19日03:14:07.999999 GMT。1970年01月01日00:00:00.000000之前的时间将产生负值。


@pizza - 这对我来说是个好消息。在没有管理员权限的情况下,脚本在我的Windows 7上运行良好。我很确定它也适用于其他版本的Windows。你真的测试过这个脚本吗?如果是,你使用的是哪个版本的Windows? - dbenham
winxp:无法注册mof文件。 只有管理员组成员才能使用WMIC.EXE。 原因:Win32错误:拒绝访问。 - pizza
@pizza - 我确认该代码在Vista和Windows 7上可以不需要管理员权限工作(至少默认情况下)。WMIC可用于XP Professional,但不适用于XP Home。我不确定XP Professional的默认特权要求是什么。 - dbenham
这里有一些相关的帖子:https://dev59.com/0HVC5IYBdhLWcg3w21Eq#4783062 请注意评论。尝试在没有特殊权限的情况下在7 / vista上创建新用户ID,我怀疑也不起作用。 - pizza
1
我刚试了一下7pro,它在普通用户ID上可以运行。但不幸的是,在XP上无法运行。除此之外,这个批处理还是相当不错的。 - pizza

4
你可以在Windows中使用VBScript,解释器已经在你的系统上可用。
'--------------------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

这并未考虑时区差异。它还会受到夏令时的影响。 - dbenham
更改以处理时区。 - pizza

3
如果你所说的“Unix时间”是纪元秒, 那么Windows没有包含生成它的工具。但你可以安装第三方工具,例如:
  • 安装Cygwin
  • 找到date二进制文件(在C:\Cygwin\或其他安装位置下)
  • 像在Linux中一样使用它。

或者,根据这个答案上的精彩评论,你可以安装GNU Coreutils,它也包括一个date命令。 它包括许多其他可能不需要的工具,但Cygwin也是如此。


无需安装Cygwin就可以获得单个工具。大多数(全部?)GNU工具可以在不使用Cygwin的情况下下载和使用。 - user330315
1
+1... 这是正确的答案。还有其他一些针对 Windows 的类 Unix 层,如 UWIN 等,但每个人都使用 Cygwin。另外值得解释的是,Windows 不是 Unix,当然你不能本地获取时期秒数! - ormaaj
我在Windows上尝试使用GnuWin32,但它无法处理1970年之前的日期。在Linux上它可以工作,并返回负数。命令"date +%s --date "31 Dec 1969""应该返回-86400,但是对我来说它返回了"无效日期"。 - Joe Jobs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接