views:

120

answers:

2

I've been trying to count the age of something in weekdays. I've tried the method detailed in this question, http://stackoverflow.com/questions/883615/given-a-date-range-how-to-calculate-the-number-of-weekends-partially-or-wholly-wi but it doesn't seem to fit my usecase.

An item has a created DATETIME in the database, and I need to mark it as old if the created date is over 2 days old. However, the client has requested that age only count week days (Mon to Fri) and exclude Sat+Sun.

So far, my pseudo code looks like the following,

now - created_datetime = number_of_days
for(i number_of_days)
  if(created_datetime - i)
    is a weekday, then age++

There must be a cleaner way of achieving this? As if an item were to get very old, looping through each day of it's age, looking for a weekend day would impact speed quite a bit.

Any ideas would be great! Thanks

A: 

I'm sure you can do this with some math and a bit of careful thought. You need to check what day of the week the item was created and what day of the week it currently is. First, you calculate the number of days old it is, as I'm sure you were doing at first.

// if today is saturday, subtract 1 from the day. if its sunday, subtract 2
if (now() is sunday) $now = now() - 2 days;
if (now() is saturday) $now = now() - 1 day;

// same thing for $date posted.  but adding 1 or 2 days
if ( $date is saturday) $date = $date + 2;
if ( $date is sunday) $date = $date + 1;

// get days difference
$days = $today - $date;
// have to subtract 2 days for every 7
$days = $days - floor($days/7)*2

You'd have to check if that works. Maybe you can do the calculation without moving your date to before/after the weekend. It may not be perfect, but its the right idea. No need to iterate.

pocketfullofcheese
This doesn't count the correct age for all days of the week. For example, if the date created is a Friday, and today is Monday, you say it's 3 days old, but it's only 1 day old.
Ben S
like i said, i didn't work out the details. But you just have to worry about coding a few of those edge cases and you'll be fine. The overall idea is the same. do days - floor($days/7)*2 and handle edge cases
pocketfullofcheese
+1  A: 

You only have to check the last 7 days to know the exact age in weekdays.

Here's the intuition:

Subtract from the total age of the object, the number of weekends in its lifetime. Note that every 7 days there are exactly 2 weekends. Add to this the number of weekend days in the remainder days (the ones that aren't in a full week) and you have to total number of weekend days in its lifetime. Subtract from the real age to get the weekday age.

int weekendCount = 0;
// Check the remainder days that are not in a full week.
for (int i = totalAge % 7; i < 7; i++) {
    if (created_datetime - i is weekend) {
        weekendCount++;
    }
}

weekdayAge = totalNumberOfDays  - (((totalNumberOfDays / 7) * 2) + weekendCount);

Note that the division is an integer division.

Ben S