Date
Arithmetic
wrote
this for a particular case where I needed to find out the number
of seconds batch jobs had run for. The jobs produced logs which had the
start and stop times in the format...
CCYYMMDDhhmmss
...so at least the
conversions were straightforward, as can be seen from the code.
/* --------------------------------------------------
Name: datesub
Purpose: See ShowHelp() function for full description
-------------------------------------------------- */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#define DATELENGTH 14
/* ----------------------
Function Prototypes...
------------------- */
long ConvertToCalendarTime(char *SourceDate);
int GetTwoDigits(char* SourceString, int StartFrom);
void ShowHelp();
void FormatAsDayHourMinuteSecond(long NumberOfSeconds);
/* ==================================================
The main function controls the entire programme...
=============================================== */
int main (int argc, char **argv)
{
char Mode;
char FirstDate[DATELENGTH + 1];
char SecondDate[DATELENGTH + 1];
long FirstDateInSeconds;
long SecondDateInSeconds;
long ResultInSeconds;
char FormattedResult[14];
/* -----------------------------
Is the user looking for help?
-------------------------- */
if ( (argc == 1 ) || (*argv[1] == '?'))
{
ShowHelp();
return -1;
}
/* ---------------------------------------------------
If there are the wrong number of arguments, fail...
------------------------------------------------ */
if ( argc != 4 )
{
printf("\nWRONG NUMBER OF PARAMETERS!\n");
ShowHelp();
return -1;
}
/* ----------------------------------------------
Extract the arguments from the command line...
------------------------------------------- */
Mode = *argv[1];
sprintf(FirstDate, "%s", argv[2]);
sprintf(SecondDate, "%s", argv[3]);
/* -------------------------------
If the mode is invalid, fail...
---------------------------- */
if ((Mode != 's') && (Mode != 'f'))
{
printf("\nINVALID MODE SETTING!\n");
ShowHelp();
return -1;
}
/* -------------------------------------------------------------------
Convert the first and second dates to seconds since Jan 1st 1970...
---------------------------------------------------------------- */
FirstDateInSeconds = ConvertToCalendarTime(FirstDate);
SecondDateInSeconds = ConvertToCalendarTime(SecondDate);
/* ------------------------------
Do the required calculation...
--------------------------- */
ResultInSeconds = FirstDateInSeconds - SecondDateInSeconds;
/* ----------------
Are we finished?
------------- */
if (Mode == 's')
{
printf("%d\n", ResultInSeconds);
exit(0);
}
/* -----------------------------------
Still here, so format the output...
-------------------------------- */
FormatAsDayHourMinuteSecond(ResultInSeconds);
exit(0);
}
/* ================================================================================
Function converts the date passed to the number of seconds since Jan 1st 1970...
============================================================================= */
long ConvertToCalendarTime(char *SourceDate)
{
int Century, Year, Month, Day, Hour, Minute, Second;
int TotalYears;
int ThisYear;
long CalenderTime = 0;
Century = GetTwoDigits(SourceDate, 0);
Year = GetTwoDigits(SourceDate, 2);
Month = GetTwoDigits(SourceDate, 4);
Day = GetTwoDigits(SourceDate, 6);
Hour = GetTwoDigits(SourceDate, 8);
Minute = GetTwoDigits(SourceDate, 10);
Second = GetTwoDigits(SourceDate, 12);
/* ----------------------------------------------------------
Calculate the number of seconds in the years since 1970...
------------------------------------------------------- */
TotalYears = ((Century * 100) + Year);
for( ThisYear = 1970; ThisYear < TotalYears; ThisYear++ )
if( (ThisYear % 4) == 0)
CalenderTime = CalenderTime + 31622400;
else
CalenderTime = CalenderTime + 31536000;
/* -------------------------------------------------------
Add in the number of seconds in the months this year.
Uses a case statement for simplicity and readability...
---------------------------------------------------- */
switch (Month)
{
case 1: break;
case 2: CalenderTime = CalenderTime + 2678400;
break;
case 3: if((TotalYears %4) == 0)
CalenderTime = CalenderTime + 5184000;
else
CalenderTime = CalenderTime + 5097600;
break;
case 4: if((TotalYears %4) == 0)
CalenderTime = CalenderTime + 7862400;
else
CalenderTime = CalenderTime + 7776000;
break;
case 5: if((TotalYears %4) == 0)
CalenderTime = CalenderTime + 10454400;
else
CalenderTime = CalenderTime + 10368000;
break;
case 6: if((TotalYears %4) == 0)
CalenderTime = CalenderTime + 13132800;
else
CalenderTime = CalenderTime + 13046400;
break;
case 7: if((TotalYears %4) == 0)
CalenderTime = CalenderTime + 15724800;
else
CalenderTime = CalenderTime + 15638400;
break;
case 8: if((TotalYears %4) == 0)
CalenderTime = CalenderTime + 18403200;
else
CalenderTime = CalenderTime + 18316800;
break;
case 9: if(
(TotalYears %4) == 0)
CalenderTime = CalenderTime + 21081600;
else
CalenderTime = CalenderTime + 20995200;
break;
case 10: if((TotalYears %4) == 0)
CalenderTime = CalenderTime + 23673600;
else
CalenderTime = CalenderTime + 23587200;
break;
case 11: if((TotalYears %4) == 0)
CalenderTime = CalenderTime + 26352000;
else
CalenderTime = CalenderTime + 26265600;
break;
case 12: if((TotalYears %4) == 0)
CalenderTime = CalenderTime + 28944000;
else
CalenderTime = CalenderTime + 28857600;
break;
default: printf("\nINVALID MONTH VALUE!\n");
ShowHelp();
exit (-1);
}
/* ------------------------------------------------------
Add in the number of seconds in the days this month...
--------------------------------------------------- */
CalenderTime = CalenderTime + (Day - 1) * 86400;
/* -----------------------------------------
Add in the seconds for the hours today...
-------------------------------------- */
CalenderTime = CalenderTime + (Hour - 1) * 3600;
/* --------------------------------------------------
Add in the seconds for the minutes in this hour...
----------------------------------------------- */
CalenderTime = CalenderTime + (Minute - 1) * 60;
/* --------------------------
And finally the seconds...
----------------------- */
CalenderTime = CalenderTime + Second;
return (CalenderTime);
}
/* ============================================================
Function extracts two digits from the supplied source string
and returns them as an integer...
========================================================= */
int GetTwoDigits(char* SourceString, int StartFrom)
{
char TargetString[3];
TargetString[0] = SourceString[StartFrom];
TargetString[1] = SourceString[StartFrom + 1];
TargetString[2] = '\0';
return(atoi(TargetString));
}
/* ===================================================================
Function provides an explanation of what this filter does (help)...
================================================================ */
void ShowHelp()
{
printf("\nThis filter subtracts one date from another and returns the result\n")
printf("either as seconds or as a formatted string.\n");
printf("\n");
printf("The first parameter is the operation which may be...");
printf("\n");
printf(" <s> result is to be in seconds\n");
printf(" <f> format result as days, hours, minutes and seconds (DD:HH:MM:SS)\n");
printf("\n");
printf("The second and third parameters are the dates to be processed\n");
printf("in the format CCYYMMDDHHMMSS\n");
printf("\n");
printf("example usage: datesub s 20010817105823 20010816113402 \n");
}
/* =======================================================================
Function accepts a number of seconds and formats them as dd:hh:mm:ss...
==================================================================== */
void FormatAsDayHourMinuteSecond(long NumberOfSeconds)
{
int Days, Hours, Minutes, Seconds;
long Remainder;
char ResultString[14];
Days = NumberOfSeconds / 86400;
Remainder = NumberOfSeconds % 86400;
Hours = Remainder / 3600;
Remainder = Remainder % 3600;
Minutes = Remainder / 60;
Seconds = Remainder % 60;
printf("%02d:%02d:%02d:%02d\n", Days, Hours, Minutes, Seconds);
}
/* =======================================================================
END END END END END END END END END END END END END END END END END END
==================================================================== */