1

I am trying to create time slots between the given time.

I am passing key named enableDays which tells us which days of week slots need to be created.

If enableDays = [0,1,2,3,4,5,6] //all week

or

If enableDays = [1,2,3,4,5] //skip Saturday and sunday

or in some cases

If enableDays = [1,2,3,4,6] //skip friday and sunday

Also, I am trying to round up the given time to the nearest Hour.

Here is my code what I have tried till now

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>

Is there any way I can achieve this?

Thanks.

xMayank
  • 1,875
  • 2
  • 5
  • 19
  • I don't have an answer for you but one small issue. timezone should actually be called offset and it should be part of the start and end time as an ISO8601 timestamp (which also includes a date). You can get into all sorts of nasty edge case bugs if you don't do this. – Matt Aug 18 '20 at 04:40
  • What is interval supposed to be doing? It sets time but it never uses time after that. – Matt Aug 18 '20 at 04:47
  • Some times there is, sometimes we don't get interval. – xMayank Aug 18 '20 at 04:47
  • But this code looks dead: `if (interval){ time.setMinutes(time.getMinutes() + interval); }` time variable is not used after. – Matt Aug 18 '20 at 04:48
  • Yes I got confused in it that is why I am here for help. – xMayank Aug 18 '20 at 04:49
  • Actually I missed ```let time = new Date(datetimeLocal);``` – xMayank Aug 18 '20 at 04:58
  • 1
    @xMayank can you add to your question what you are trying to achieve. So what input data should produce what output data? For example: `if we take { "fromTime": "05:31:00", "toTime": "12:50:00", "duration": 60, "interval": 0, "slotCount": 11, "timezone": "+05:30", "enableDays": [0,1,2,3,4,5,6] }` then re sult must be like `[ [ { "from": "08:00", "to": "09:00" }, { "from": "09:00", "to": "10:00" },` and so on. It will be good to have more that 1 example (different). Thank you – Anton Aug 25 '20 at 08:54

1 Answers1

0

I would like to help you set parameters for timezone and weekday. I hope this is close to what you are looking for. I did account for these conditions.

all week skip Saturday and sunday skip friday and sunday

as well as others which you can set by calling filterDays or writing a new array by hand.

To help see what's going on, I made some small functions. Each is named by the action inside.

At the bottom we make a few factories: One for each of the days you list. If you want different settings, you can create a whole new factory.

For your end time logic, you will need to update that part. All of the times are moment objects. I highly recommend you keep your data pure like this (as moment objects) until you have to render it.

// global moment

const ROUNDING = 60 * 60 * 1000;
const TIMEZONE = "+05:30";
const ENABLEDDAYS = [0,1,2,3,4,5,6] 

const allDays = filterDays();
const skipSatSun = filterDays([5,6]);
const skipFriSun = filterDays([4,6]);
const date = moment().utc();

const settings = 
  { "fromTime": "05:31:00"
  , "toTime": "12:50:00"
  , "duration": 60
  , "interval": 0
  , "size": 11
  }


function printDate(date, format = 'YYYY-MM-DD') {
  console.log(date.format(format))
}


/** Get days of the week with selected dates removed */
function filterDays(...removals) {
  const allDays = [0,1,2,3,4,5,6];  
  return allDays.filter( (selection,i) => !removals.includes(selection))
}


/** courtesy: https://stackoverflow.com/questions/17691202/round-up-round-down-a-momentjs-moment-to-nearest-minute */
function roundUp(m) {
  return m.minute() || m.second() || m.millisecond() ? m.add(1, 'hour').startOf('hour') : m.startOf('hour');
}


/** Create a moment object for the start and endpoints  */
function getEndpoints(time, duration, toTime, final = false) {
  const start = moment(time);
  let end = moment(time)
  end.minutes(end.minutes() + duration)

  //We need to adjust last slot timings to match toTime, duration value is overwritten. 
  if (final) {
    // sorry can't help you here, good luck :)
    end = moment(time);
  }

  
  return {
    start,
    end
  }
}


/** Use a settings object to create a factory for your timezones and selected dates. */
function create(settings) {
  let { fromTime, toTime, duration, interval, size } = settings;

  function factory(timezone, selections) {
    const now = moment(date + 'T' + fromTime + '.000Z').utcOffset(timezone);
    const time = roundUp(now);

    const slots = selections.map((el, index) => {  
      const list = []
      for (var i = 0; i < size; i++) {
        let isFinal = (i +1) === size;
        let newDate = getEndpoints( time, duration, toTime, isFinal )
        
        list.push( newDate )
        if (interval) {
          time.minutes(time.minutes() + interval);
        }
      }

      date.date(date.date() + 1);
      return list;
    })

    return slots;
  }

  return factory;
}


const DateFactory = create(settings)
const targetAllDays = DateFactory(TIMEZONE, ENABLEDDAYS)

console.log(targetAllDays)
console.log(DateFactory(TIMEZONE, skipFriSun))
console.log(DateFactory(TIMEZONE, skipSatSun))
Naltroc
  • 989
  • 1
  • 14
  • 34