0

I would like to calculate a duration between two dates which have DD/MM/YYYY HH:MM:SS as format:

echo Jours;Mois;Année;hh;mm;JoursF;MoisF;AnnéeF;hhF;mmF;Duration>Duration.csv

REM ====Découper la date en jours, mois et années ==
SET AA1=2018
SET MM1=01
SET JJ1=01

REM REM ====Découper l'heures en heures, Minutes, Secondes ==

SET hh1=01
SET mmm1=20

REM =====saisie deux 

REM ====Découper la date en jours, mois et années ==
SET AA2=2019
SET MM2=02
SET JJ2=03

REM ====Découper l'heures en heures, Minutes, Secondes ==

SET hh2=02
SET mmm2=5

REM==== statement condition
IF %AA2% EQU %AA1% IF %MM2% EQU %MM1% IF %JJ2% EQU %JJ1% IF %hh2% EQU %hh1% 
IF %mmm2% GTR %mmm1% set /a duration = %mmm2%-%mmm1%

REM===== display duration 

Echo %JJ1%;%MM1%;%AA1%;%hh1%;%mmm1%;%JJ2%;%MM2%;%AA2%;%hh2%;%mmm2%;%duration% >>Duration.csv
Daniel B
  • 3,109
  • 2
  • 33
  • 42
mourad
  • 21
  • 1
  • 1
  • 3
    I suggest to use PowerShell which has built-in date functions while Windows command processor does not have. But you can find ready to use code on Stack Overflow to determine the time difference between two dates. You just have to search for it. Look for example on the results found with [\[batch-file\] date time difference](https://stackoverflow.com/search?q=%5Bbatch-file%5D+date+time+difference). – Mofi Jun 28 '18 at 13:02
  • Take a look at http://ritchielawrence.github.io/batchfunctionlibrary/#date-and-time-functions otherwise I second to use PowerShell for this. –  Jun 28 '18 at 14:36
  • A general solution for this so sooo hard with cmd. You would have to do all the fooling with leap days and local daylight savings time, etc. – mojo Jun 28 '18 at 19:31

2 Answers2

3

There are a lot of examples on how to achieve these conversions in a Batch file. However, most of those methods are rudimentary and crude.

I developed a very efficient method to get the elapsed seconds between two times, but I never had completed the equivalent efficient method to get the elapsed days between two dates. So here it is:

@echo off
setlocal EnableDelayedExpansion

rem Get elapsed days/time between two timestamps in "DD/MM/YYYY HH:MM:SS" format
rem Antonio Perez Ayala aka Aacini

rem Define the "Date in DDMMYYYY format" To "Julian Day Number" conversion "function"
set "DateToJDN(Date)=( a=1Date, y=a%%10000, a/=10000, m=a%%100, d=a/100-100, a=(m-14)/12, (1461*(y+4800+a))/4+(367*(m-2-12*a))/12-(3*((y+4900+a)/100))/4+d-32075 )"

echo Enter two timestamps in "DD/MM/YYYY HH:MM:SS" format
set /P "stamp1=Enter start timestamp:   "
set /P "stamp2=Enter  end  timestamp:   "

for /F "tokens=1-4" %%a in ("%stamp1% %stamp2%") do set "date1=%%a" & set "time1=%%b" & set "date2=%%c" & set "time2=%%d"

set /A "days=!DateToJDN(Date):Date=%date2:/=%! - !DateToJDN(Date):Date=%date1:/=%!"
set /A "ss=(((1%time2::=-100)*60+1%-100) - (((1%time1::=-100)*60+1%-100)"
if %ss% lss 0 set /A "ss+=60*60*24, days-=1"
set /A "hh=ss/3600+100, ss%%=3600, mm=ss/60+100, ss=ss%%60+100"

echo/
echo Duration: %days% days and %hh:~1%:%mm:~1%:%ss:~1%

You may review further information about this program at these links: the efficient conversion method for the time part is described at this answer, the JulianDayNumber to Date conversions method is described at this reply, and the way to define "functions" in Batch is described at this thread.

Aacini
  • 65,180
  • 12
  • 72
  • 108
2

Here's a generic PowerShell solution (invoked from a batch file—should work on any Windows OS). You didn't say what format the elapsed time should be in, so this is a proof of concept.

SETLOCAL

SET "DATE1=25/06/2018 13:18:25"
SET "DATE2=26/06/2018 09:57:59"

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "((Get-Date -Year %DATE1:~6,4% -Month %DATE1:~3,2% -Day %DATE1:~0,2% -Hour %DATE1:~11,2% -Minute %DATE1:~14,2% -Second %DATE1:~17,2%) - (Get-Date -Year %DATE2:~6,4% -Month %DATE2:~3,2% -Day %DATE2:~0,2% -Hour %DATE2:~11,2% -Minute %DATE2:~14,2% -Second %DATE2:~17,2%)).ToString()" <NUL

This produces

20:39:33.9995000

The date format must have zero-padded values (probably what you described) for this method to work.

If the date is in a format that matches your system locale (I presume you're in Europe or Canada), the PowerShell command can be greatly simplified, allowing Windows to do all the parsing for you. Zero-padding is no longer a requirement in this case.

SETLOCAL

SET "DATE1=25/06/2018 13:18:25"
SET "DATE2=26/06/2018 09:57:59"

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "((Get-Date '%DATE2%') - (Get-Date '%DATE1%')).ToString()" <NUL

If you wanted the elapsed time as a decimal number of seconds, minutes, hours, or days, you could just use, .TotalSeconds (or .TotalMinutes, .TotalHours, or TotalDays) instead of .ToString().

In my opinion, date libraries are the right tool for the job. CMD can only do integer arithmetic and most other logic is painful. If the job can be reduced to simple arithmetic (@aacini's solution is cool in this regard), then it might not be too bad. Otherwise, don't reinvent the wheel.

mojo
  • 4,050
  • 17
  • 24