Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I calculate the opening days of online stores with different working days.?

I am having trouble automatically calculating the working days of different online stores that open at different days. The difficulty here is some of the stores open during the weekends. What i realized was JavaScript starts counting the days of the week from 0 which is a Sunday.

example
store A, WORKING_DAYS = Tue - Sun
store B, WORKING_DAYS = Mon - Fri
store C, WORKING_DAYS = Mon - Tue
store D, WORKING_DAYS = Fri - Mon
    //  0 (sunday) - 6 (saturday)  give day is thursay which is 4
    // workdays fri - tues, ie 5 - 2 but current day is saturday and we 
    looking at positive values
    if( dayStart < currentDay < dayEnd){
        return(
            <Text style={[styles.h4,styles.tag,  {backgroundColor:'#4eae5c'}]}>open</Text>
            )
        }
    if(currentDay) {
        return(
            <Text style={[styles.h4,styles.tag, 
        {backgroundColor:'red'}]}>closed</Text>
            )
        }

because Sunday returns 0 from JavaScript date, how do you find the interval between Friday and Monday

like image 712
Kweku Avatar asked Jul 24 '20 01:07

Kweku


2 Answers

You state that you want to determine whether an online store is open on a specific weekday, given that you know which weekday it opens and which weekday it closes. Days are numbered from 0 (Sunday) to 6 (Saturday). This gets challenging when a store opens on Friday (5) and closes on Monday (1).

A straightforward solution is the one given in the answer by otw:

if(dayStart is less than dayEnd) {
  check whether currentDay >= dayStart and currentDay <= dayEnd
} else {
  check whether currentDay <= dayStart or currentDay >= dayEnd
}

Another solution is to view the weekdays as a ring of integers modulo 7. We can then use modular arithmetic to check whether a number n is in the interval [a, b] with the following inequality, even when a is larger than b:

(n - a) mod 7 <= (b - a) mod 7

To solve your specific problem, we can define an isOpen() function like this:

function isOpen(currentDay, dayStart, dayEnd){
  return mod(currentDay - dayStart, 7) <= mod(dayEnd - dayStart, 7); 
}

function mod(a, n){
  return (a % n + n) % n; // guarantees positive modulo operation
}

Then, you can call this function in your code like this:

if(isOpen(currentDay, dayStart, dayEnd)) {
  return (
    <Text style={[styles.h4, styles.tag, {backgroundColor: '#4eae5c'}]}>open</Text>
  );
} else {
  return (
    <Text style={[styles.h4, styles.tag, {backgroundColor: 'red'}]}>closed</Text>
  );
}
like image 129
Tomas Langkaas Avatar answered Nov 20 '22 20:11

Tomas Langkaas


Here you go. day is the day you are checking, open is the first day open and close is the last day open of the week.

I am just using moment to convert the plain text names into numbers but you could easily map that to an array or something.

This code is basically a variation of this answer: Test if number is inside circular interval

Basically you just check if your open day is smaller than or equal to your close day.

If it is, then you have a normal range and are just checking if your day is greater than the open day AND smaller than the close day to see if it is open on that day.

If you open day is greater than your close day, that means your range is going to be starting its count over so you actually need to check if your day is greater than or equal to your open day OR less than or equal to your close day to see if it is open.

function isStoreOpen(day, open, close) {

  const dayNum = moment().day(day).day();
  const openNum = moment().day(open).day();
  const closeNum = moment().day(close).day();

  if(openNum <= closeNum) {
    return (dayNum >= openNum && dayNum <= closeNum);
  } else {
    return (dayNum >= openNum || dayNum <= closeNum);
  }

}

// store A, WORKING_DAYS = Tue - Sun
console.log("Store A (Tue - Sun) is open on Wednesday: " + isStoreOpen("Wednesday", "Tuesday", "Sunday"));

// store B, WORKING_DAYS = Mon - Fri
console.log("Store B (Mon - Fri) is open on Wednesday: " + isStoreOpen("Wednesday", "Monday", "Friday"));

// store C, WORKING_DAYS = Mon - Tue
console.log("Store C (Mon - Tue) is open on Wednesday: " + isStoreOpen("Wednesday", "Monday", "Tuesday"));

// store D, WORKING_DAYS = Fri - Mon
console.log("Store D (Fri - Mon) is open on Wednesday: " + isStoreOpen("Wednesday", "Friday", "Monday"));
console.log("Store D (Fri - Mon) is open on Saturday: " + isStoreOpen("Saturday", "Friday", "Monday"));
console.log("Store D (Fri - Mon) is open on Friday: " + isStoreOpen("Friday", "Friday", "Monday"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>

Here is an example with something closer to your code:

function isStoreOpen(currentDay, dayStart, dayEnd) {
  if (dayStart <= dayEnd) {
    if (currentDay >= dayStart && currentDay <= dayEnd) {
      return "open"
    } else {
      return "closed"
    }
  } else {
    if (currentDay >= dayStart || currentDay <= dayEnd) {
      return "open"
    } else {
      return "closed"
    }
  }
}

// store A, WORKING_DAYS = Tue - Sun
console.log("Store A (Tue - Sun) status on Wednesday: " + isStoreOpen(4, 2, 0));

// store B, WORKING_DAYS = Mon - Fri
console.log("Store B (Mon - Fri) status on Wednesday: " + isStoreOpen(4, 1, 5));

// store C, WORKING_DAYS = Mon - Tue
console.log("Store C (Mon - Tue) status open on Wednesday: " + isStoreOpen(4, 1, 2));

// store D, WORKING_DAYS = Fri - Mon
console.log("Store D (Fri - Mon) status on Wednesday: " + isStoreOpen(4, 5, 1));
console.log("Store D (Fri - Mon) status on Saturday: " + isStoreOpen(6, 5, 1));
console.log("Store D (Fri - Mon) status on Friday: " + isStoreOpen(5, 5, 1));

Your exact implementation might look something like this:

if (dayStart <= dayEnd) {
  if (currentDay >= dayStart && currentDay <= dayEnd) {
            return(<Text style={[styles.h4,styles.tag,  {backgroundColor:'#4eae5c'}]}>open</Text>);
  } else {
            return(<Text style={[styles.h4,styles.tag,{backgroundColor:'red'}]}>closed</Text>);
  }
} else {
  if (currentDay >= dayStart || currentDay <= dayEnd) {
            return(<Text style={[styles.h4,styles.tag,  {backgroundColor:'#4eae5c'}]}>open</Text>);
  } else {
            return(<Text style={[styles.h4,styles.tag,{backgroundColor:'red'}]}>closed</Text>);
  }
}
like image 1
otw Avatar answered Nov 20 '22 18:11

otw