• C

calculating work shift time rather than actual time.

I am working with a proprietery language of CA & it's very much similar to C and hence I find this a good place to put my question.
I want to make some workshift calculations in a function that takes start date & end date as arguments and calculates the difference in time taking into account the shift timings. for e.g. time difference between 11/4/2004 09:00:00 & 11/5/2004 09:00:00 should be  28800 seconds (8 hours) and not 24 hours (assuming my shift timings for that day are defined as 09:00-17:00).
I have "date" data type and some in-build functions that can be used. e.g. now() returns current date in "mm/dd/yyyy hh:mm:dd" format and typecasting a date datatype to integer gives number of seconds elapsed since some reference time. e.g.
(int)now() will return 231321....(some integer value).
This is all i have for date time manipulation. I have other standard c operators like if, else, ==, etc. which i can use.
The shift times are defined in another table and right now i am only concerned with regular shif times. i.e. Mon-Fri 09:00-17:00, Sat-Sun 00:00-00:00
I will be glad if someone can help me out.
Thanks in advance.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kent OlsenData Warehouse Architect / DBACommented:

Hi Picaso,

It sounds like this can be broken down into the difference of two easy steps.

Compute the difference between the start and end datetimes.
Compute the shift difference.
Subtract them.

Or is this more complicated than that?
picasothakkarAuthor Commented:
It's more complicated esp. since we have to keep track of the week day & the workshift hours defined for that day.
Kent OlsenData Warehouse Architect / DBACommented:

Ok.  From your first post I don't know where you're going.  What calculations are you trying to solve?

Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

is there any way you can find what day a particular date is?

-- Adil
picasothakkarAuthor Commented:
That is the major calculation. We don't have provision to find out what day a particular date is. I started with something like taking a reference date which we know is Sunday & then carry out iterations till the point it reaches the date we are interested in.
I think i need to do following:
lets say we are calculating time difference between 1st Nov 10 am & 2nd  Nov 10 am.
1. Take a reference date which falls on sunday and cast it to int.
2. Start increamenting it by adding total seconds in week and arrive to sunday of "start date & time" (1st Nov 10 am) we are interested in. Lets say we got the "weekly offset" which gives us integer value of sunday 00:00:00.
I am still into middle of it....Let me know if something clicks you
Calculating the day of the week is not that difficult.  There's quite a few implematations out there of Zeller's Congruence.  Here's one you can use.

int DayOfWeek(int y, int m, int d) { // y += 7e8 // Sun = 0
      if (m<3) { m += 12 ; y--;}
      return (2 + d + (int)((13*m-2)/5) + y + (int)(y/4) - (int)(y/100) + (int)(y/400)) % 7;

Kent OlsenData Warehouse Architect / DBACommented:
Hi Picasco,

Going back to your original post, you said that now() returns the number of seconds to a base date.

Problem solved.

Determine what date is the base date and what day of the week that this day falls on.

Now you can compute the day of week with:

DayOfWeek = ((now () / 86400) % 7);

picasothakkarAuthor Commented:
Thanks so much.. Now i have day of week. From day of week, I can find out what were the shift timings for that day. Now how do i actually calculate then difference? e.g. lets take the case wherein i need to calculate the difference in time for 11/3/2004 12:00:00 & 11/4/2004 09:00:00 & my shift timings for both these days are 09:00 - 17:00.
so my answer should be  18000 seconds. How do i arrive to this figure?
picasothakkarAuthor Commented:
Hi Kent,
Can you tell me workaround for using "%" operator? I don't have it!!!!
Kent OlsenData Warehouse Architect / DBACommented:
Hi Picaso,

You may have to "roll up" the total times until you get there.  If your language allows you to do so.  Here's the steps to computing shift time spanning different days.

Calculate the first time, in seconds.  Noon is 12 hours * 3600 seconds, or 43200 seconds.

Subtract this value from the shift end time.  Shift end is 17 hours * 3600, or 61200.  The difference is 18000.

Add 8 * 3600, or 28800 for every WHOLE day between the start and end dates.  In this case, the days are consecutive so there is nothing to add.

Calculate the end time, in seconds.  9AM is 9 hours * 3600 seconds, or 32400.

Subtract the shift start time from the end-time.  The shift start time is 9AM, 9 hours * 3600, or 32400.

In this case, the end time and the shift start time are the same, so the result is zero.

Add the last calculation to the number that has been rolled up.  (First days calculation + 2800 * whole days.)

The result is the shift time, in this case, 18000.



Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
picasothakkarAuthor Commented:
Hi kent plz check this out. can you check the results with c compiler? it will really help.
plz ignore TZC for now. you can assume it constant.

   int iSdate;
   int iEdate;

   int DayOffset;
   int NumberOfWeeks;
   int FrTimes[21];
   int ToTimes[21];
   int count;
   int todate;
   int accum;
   int numdayper;

   int WeekOffset; // Should be a Sunday at 00:00 before the StartDate
   int efound;
   int iInterval;
   int DOW;
   int totime;
   int fromtime;
   int numweek;
   date TempDate1;
   date TempDate2;
   int TempDate3;

   TempDate3 = (int)((date)"01/01/1999 00:00:00");
   count = 0;
//check "day"From values, which are part of object.
   if (!is_empty(SundayFrom)) {
      TempDate1 = (date)format("01/01/1999 %s:00", SundayFrom);
      TempDate2 = (date)format("01/01/1999 %s:00", SundayTo);
      FrTimes[count] = (int)TempDate1 - TempDate3 + 0 + TZC;
      ToTimes[count] = (int)TempDate2 - TempDate3 + 0 + TZC;
      count = count + 1;
   if (!is_empty(MondayFrom)) {
      TempDate1 = (date)format("01/01/1999 %s:00", MondayFrom);
      TempDate2 = (date)format("01/01/1999 %s:00", MondayTo);
      FrTimes[count] = (int)TempDate1 - TempDate3 + 86400 + TZC;
      ToTimes[count] = (int)TempDate2 - TempDate3 + 86400 + TZC;
      count = count + 1;
   if (!is_empty(TuesdayFrom)) {
      TempDate1 = (date)format("01/01/1999 %s:00", TuesdayFrom);
      TempDate2 = (date)format("01/01/1999 %s:00", TuesdayTo);
      FrTimes[count] = (int)TempDate1 - TempDate3 + 172800 + TZC;
      ToTimes[count] = (int)TempDate2 - TempDate3 + 172800 + TZC;
      count = count + 1;
   if (!is_empty(WednesdayFrom)) {
      TempDate1 = (date)format("01/01/1999 %s:00", WednesdayFrom);
      TempDate2 = (date)format("01/01/1999 %s:00", WednesdayTo);
      FrTimes[count] = (int)TempDate1 - TempDate3 + 259200 + TZC;
      ToTimes[count] = (int)TempDate2 - TempDate3 + 259200 + TZC;
      count = count + 1;
   if (!is_empty(ThursdayFrom)) {
      TempDate1 = (date)format("01/01/1999 %s:00", ThursdayFrom);
      TempDate2 = (date)format("01/01/1999 %s:00", ThursdayTo);
      FrTimes[count] = (int)TempDate1 - TempDate3 + 345600 + TZC;
      ToTimes[count] = (int)TempDate2 - TempDate3 + 345600 + TZC;
      count = count + 1;
   if (!is_empty(FridayFrom)) {
      TempDate1 = (date)format("01/01/1999 %s:00", FridayFrom);
      TempDate2 = (date)format("01/01/1999 %s:00", FridayTo);
      FrTimes[count] = (int)TempDate1 - TempDate3 + 432000 + TZC;
      ToTimes[count] = (int)TempDate2 - TempDate3 + 432000 + TZC;
      count = count + 1;
   if (!is_empty(SaturdayFrom)) {
      TempDate1 = (date)format("01/01/1999 %s:00", SaturdayFrom);
      TempDate2 = (date)format("01/01/1999 %s:00", SaturdayTo);
      FrTimes[count] = (int)TempDate1 - TempDate3 + 518400 + TZC;
      ToTimes[count] = (int)TempDate2 - TempDate3 + 518400 + TZC;
      count = count + 1;
   numdayper = count;

   // Lets find out what the start day is
   WeekOffset=943747200; // This was a Sunday at 00:00
      iInterval = 0;
      FrTimes[numdayper] = 604800 + TZC;
      while (iSdate < iEdate) {
            numweek = iSdate - (WeekOffset + TZC);
            numweek = numweek / 604800;
            WeekOffset = WeekOffset + (604800 * numweek);
            // find a FromTime >= iSdate
            DOW = numdayper;
            for (count=0;count<numdayper;count++) {
               if (((FrTimes[count] + WeekOffset) <= iSdate) && ((FrTimes[count+1] + WeekOffset) > iSdate)) {
                  DOW = count;
            if (DOW == numdayper) {
            // StartDate is not between any Fr/To pair, advance to next week
               iSdate = WeekOffset + 604800;
            } else {
               if (iSdate < (FrTimes[DOW] + WeekOffset)) {
                  // less than start of this period
                  todate = FrTimes[DOW] + WeekOffset ;
                  accum = 0;
               } else if (iSdate < (ToTimes[DOW] + WeekOffset)) {
                  // more than the start but less than the end
                  todate = ToTimes[DOW] + WeekOffset + 1 ;
                  accum = 1;
               } else if (iSdate < (FrTimes[DOW+1] + WeekOffset)) {
                  // after the end of this one but before the beginning of the next
                  todate = FrTimes[DOW+1] + WeekOffset + 1;
                  accum = 1;
               if (iEdate < todate) {
                  // Dont go too far...
                  todate = iEdate;
               if (accum == 1) {
                  iInterval = iInterval + todate - iSdate;
               iSdate = todate;
Kent OlsenData Warehouse Architect / DBACommented:
Not much that a C compiler will do to help, here.

The 'date' data type, format() function, etc. will keep the program from compiling and running.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.