CyberMuesli |
29-05-2012 04:00 1924242 |
Цитата:
Цитата Anonymоus
:: Если счетчик переходит границу суток, число дней возрастает на 1
:: Дни выводятся в переменную ED (и накапливаются) // да, знаю, что костыль и быдлокод »
|
Цитата:
Цитата Anonymоus
:TMinus
:: Функция вычитания для сериализованного времени »
|
Не знаю, насколько это для Вас применимо, но похоже, что да. Вот фрагменты моего рабочего кода для определения актуальности бэкапов. Дата-время переводятся в секунды (с учетом високосных годов), секунды легко вычитаются друг из друга, даже если между вычитаемыми моментами времени полночь, новый год или сами моменты отстоят друг от друга на несколько лет.
В демке функцией :GetFleInfo[] в переменные ArcFile.* записывается информация о данном bat-файле, которая затем выводится на экран. Нас интересуют ArcFile.DTSec (дата-время файла в секундах), ArcFile.ModifyedSecAgo (сколько секунд назад файл был модифицирован, получается вычитанием "текущая дата-время в секундах" - "дата-время модифицирования файла в секундах"). Собственно перевод в секунды - :DateTime2Seconds[]
Ограничения. 32х битов достаточно для представления в секундах даты-времени в диапазоне 1980....2048, при острой необходимости можно переделать на двухсекундные кванты и так далее. В даном варианте секунды в дате-времени файла всегда равны 00 (для меня это некритично), файлы до 1980 года будут иметь дату-время в секундах ноль, старше 2048 - максимальное положительное 32битное со знаком. (что для меня тоже приемлемо, как "МНОГО" для папуаса для обозначения количества, большего десяти)
Код:
@echo off
:: (C) CyberMuesli, 2012
:demo
setlocal enabledelayedexpansion
if not %errorlevel%==0 (
echo ERROR: setlocal enabledelayedexpansion
exit /b 1
)
call :GetFileInfo[] .\%~nx0 ArcFile
call :DisplayFileInfo[] ArcFile
goto :eof
::===========================================================================
:DateTime2Seconds[]
::===========================================================================
:: %1="DD.MM.YYYY HH:MM:SS" %2=VarName
set dt2s.Param=%~1
set dt2s.Year=!dt2s.Param:~6,4!
set dt2s.Month=!dt2s.Param:~3,2!
set dt2s.Day=!dt2s.Param:~0,2!
set dt2s.HH=!dt2s.Param:~11,2!
set dt2s.MM=!dt2s.Param:~14,2!
set dt2s.SS=!dt2s.Param:~17,2!
if %dt2s.Year% LSS 1980 (
set %2=0
goto :eof
)
if %dt2s.Year% GEQ 2048 (
set /a %2=0x7FFFFFF+0
goto :eof
)
set S01=0
set /a S02=S01 + 31 * 86400
set /a S03=S02 + 28 * 86400
set /a S04=S03 + 31 * 86400
set /a S05=S04 + 30 * 86400
set /a S06=S05 + 31 * 86400
set /a S07=S06 + 30 * 86400
set /a S08=S07 + 31 * 86400
set /a S09=S08 + 31 * 86400
set /a S10=S09 + 30 * 86400
set /a S11=S10 + 31 * 86400
set /a S12=S11 + 30 * 86400
call :LeapCount[] %dt2s.Day%.%dt2s.Month%.%dt2s.Year%
call :Trim1st0[] %dt2s.Day% dt2s.Day
call :Trim1st0[] %dt2s.HH% dt2s.HH
call :Trim1st0[] %dt2s.MM% dt2s.MM
call :Trim1st0[] %dt2s.SS% dt2s.SS
Set /a %2=((%dt2s.Year%-1980)*31536000) + S%dt2s.Month% + (%dt2s.Day%-1+%LeapCount%)*86400 + %dt2s.HH%*3600 + %dt2s.MM%*60 + %dt2s.SS%
goto :eof
::===========================================================================
:GetFileInfo[]
::===========================================================================
:: %1: filename %2: VarName
:: return: VarName.Origin VarName.Drive VarName.Path... etc
set %2.Origin=%1
for %%i in (%1) do (
set %2.Drive=%%~di
set %2.Path=%%~pi
set %2.DPath=%%~dpi
set %2.PNX=%%~fi
set %2.NX=%%~nxi
set %2.DT=%%~ti
set %2.Size=%%~zi
)
if not "!%2.DT!"=="" (
set %2.Year=!%2.DT:~6,4!
set %2.Month=!%2.DT:~3,2!
set %2.Day=!%2.DT:~0,2!
set %2.HH=!%2.DT:~11,2!
set %2.MM=!%2.DT:~14,2!
set %2.SS=00
call :DateTime2Seconds[] "%DATE% %TIME%" Now.DTSec
call :DateTime2Seconds[] "!%2.DT!.00" %2.DTSec
set /a %2.ModifyedSecAgo=Now.DTSec-%2.DTSec
)
goto :EOF
::===========================================================================
:Trim1st0[]
::===========================================================================
:: %1=string %2=var
if "%1"=="0" (
set %2=%1
goto :eof
)
set String=%1
set Char=!String:~0,1!
if "!Char!"=="0" (
set %2=!String:~1!
) else (
set %2=%1
)
goto :eof
::===========================================================================
:DisplayFileInfo[]
::===========================================================================
echo %1.Origin !%1.Origin!
echo %1.Drive !%1.Drive!
echo %1.Path !%1.Path!
echo %1.DPath !%1.DPath!
echo %1.PNX !%1.PNX!
echo %1.NX !%1.NX!
echo %1.DT !%1.DT!
echo %1.DTSec !%1.DTSec!
echo %1.Size !%1.Size!
echo %1.Year,Month,Day !%1.Year!,!%1.Month!,!%1.Day!
echo %1.HH,MM,SS !%1.HH!,!%1.MM!,!%1.SS!
echo %1.ModifyedSecAgo !%1.ModifyedSecAgo!
goto :eof
::===========================================================================
:LeapCount[]
::===========================================================================
:: %1=date, 1.1.1999 must be passed as 01.01.1999
:: return: !LeapCount!, Count of leap Days from 01.01.1980 to %1
set LeapCount.Debug==No
if "%1"=="-debug" (
shift
set LeapCount.Debug=Yes
)
set LeapCount.Date=%1
set LeapCount.Year=%LeapCount.Date:~-4%
set LeapCount.Month=%LeapCount.Date:~3,2%
set LeapCount.Day=%LeapCount.Date:~0,2%
set LeapCount=0
for /l %%i in (1980,1,!LeapCount.Year!) do (
set /a LeapCount.Mod4=%%i %% 4
set /a LeapCount.Mod100=%%i %% 100
set /a LeapCount.Mod400=%%i %% 400
set LeapCount.IsLeapYear=No
if !LeapCount.Div400!==0 (
set LeapCount.IsLeapYear=Yes
) else (
if !LeapCount.Div4!==0 (
if not !LeapCount.Div100!==0 (
set LeapCount.IsLeapYear=Yes
)
)
)
if !LeapCount.IsLeapYear!==Yes (
if !LeapCount.Year!==%%i (
if !LeapCount.Month! GEQ 03 (
set /a LeapCount+=1
)
) else (
set /a LeapCount+=1
)
if "LeapCount.Debug"=="Yes" (
echo LeapCount: %%i !LeapCount!
)
)
)
goto :eof
|