2012-06-20 3 views

ответ

11

Настоящий пакетный пакет, который должен работать в любом регионе. Он использует 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 


Обратите внимание, что это решение имеет ограниченный срок службы. Он перестанет работать в 2038-01-19, когда время Unix превышает максимальное значение подписанного 32-битного целого.

EDIT - Код был отредактирован для поддержки преобразования временной метки строки в командной строке вместо текущего местного времени. Точный диапазон поддерживаемых времен 1901-12-13 20: 45: 52.000000 - 2038-01-19 03: 14: 07.999999 GMT. Времена до 1970-01-01 00: 00: 00.000000 будут давать отрицательные значения.

+0

он не работает, если вы не администратор (иначе root на окнах) – pizza

+0

@pizza - Это новости для меня. Скрипт отлично работает для меня в Windows 7 без админа. Я уверен, что он работает и с другими версиями Windows. Вы действительно протестировали сценарий? И если да, то какая версия Windows? – dbenham

+0

winxp: Не удалось зарегистрировать mof-файл (ы). Только члены группы администраторов могут использовать WMIC.EXE. Причина: Ошибка Win32: доступ запрещен. – pizza

3

Если вы используете «unix time», вы имеете в виду epoch second, тогда Windows не включает в себя инструменты для его создания. Вместо этого вы можете установить сторонние инструменты. Например:

  • Установить Cygwin.
  • Найти date двоичный код (под C:\Cygwin\ или где бы вы его не установили)
  • Используйте его, как в Linux.

С другой стороны, согласно удивительном комментарий на этот ответ, вы можете установить GNU Coreutils, которые также включают в себя команду date. Он включает в себя ряд других инструментов, которые вам могут не понадобиться, но тогда и Cygwin.

+0

Что? Даунвитировать без комментариев? – ghoti

+0

Не нужно устанавливать Cygwin только для того, чтобы получить один инструмент. Большинство (все?) Инструменты GNU можно скачать и использовать без Cygwin –

+0

да, это то, что я имею в виду под Unix-временем. – whoabackoff

3

Вы можете использовать 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 
+0

Это не учитывает различия в часовых поясах. Это повлияет и на летнее время. – dbenham

+0

изменен, чтобы иметь дело с часовыми поясами. – pizza

+0

+1, теперь хорошо выглядит – dbenham

Смежные вопросы