2017-11-19 1 views
2

Wenn Google Kalender-API, dauert es:Suche nächste freie Stunde gegeben Reihe von geschäftigen Zeiten

start (Epochenzeit) end (Epochenzeit) timeZone (dh America/Los_Angeles)

Die Antwort eine ist Array genannt busy, welche Objekte wie { start <Date>, end<Date>}

Mein Ziel enthält: finden Sie die nächste freie Stunde zwischen start und end.

mit den folgenden Einschränkungen:

  • in Werktagen (Montag-Freitag) sein muss
  • muss in der Arbeitszeit sein (9.00 Uhr bis 17.00 Uhr)

Dies ist, was ich versucht habe, :

  1. manuell mehr busy Objekte für jeden Tag von 9.00 bis 17.00 Uhr
  2. erstellen
  3. manuell mehr busy Objekte für Samstag und Sonntag
  4. merge erstellen alle busy zusammen Blöcke so wird es

nun die entgegengesetzten Zeiten, die die free Zeiten sind nimm keine Kreuzung sein.

Das erste freie Zeitobjekt ({start <Date>,end <Date>}), für die start - end> = 1 hour

die nächste freie Stunde. Falls keine der free Objekte größer als 1 Stunde ist, gibt es keine freie Stunde zwischen start und end


Dieser Sound auch für dieses Problem viel, Ich mag würde hören Vorschläge


so weit

Dieser ist mein Code (in Betrieb):

const moment=require('moment-timezone'); 
const chrono = require('chrono-node'); 
const ms = require('ms'); 
     /** 
     * given start and end dates and list of busy dates, return the next free hour 
     * @param {Number} start - epoch date 
     * @param {Number} end - epoch date 
     * @param {String} timeZone - to get the actual date data (like day of week for the start,end dates) 
     * @param {Array} epochBusyRanges - [{start,end},{start,end}...] all epoch dates 
     * @return {Number|null} if number, this is the start of the next available free hour 
     */ 
     function nextAvailableHour(start, end, timeZone, epochBusyRanges) { 


     //SOME SETTINGS 
     const minMeetingTimeMS  = ms('1 hour'); 
     const startWorkDayAM  = 9; 
     const endWorkDayPM   = 5; 
     const weekendStartDateTime = 'friday 23:59'; 
     const weekendEndDateTime = 'sunday 23:59'; 
     //manually put "busy" hours (work days (Monday to Friday) + work hours (9 to 17) are free,else busy) 
     const momentStart   = moment.tz(start, timeZone); 
     const momentEnd   = moment.tz(end, timeZone); 
     let next5pm    = moment.tz(chrono.parseDate(`${endWorkDayPM}pm`, momentStart), timeZone); 
     let next9am; 
     while (Number(next5pm) < Number(momentEnd)) { 
      next9am = moment.tz(chrono.parseDate(`tomorrow ${startWorkDayAM}am`, next5pm), timeZone); 
      epochBusyRanges.push({start: Number(next5pm), end: Number(next9am)}); 
      next5pm = moment.tz(chrono.parseDate(`${endWorkDayPM}pm`, next9am), timeZone); 
     } 
     //we need to put also yesterday's 5pm-9am is the start is before 9am, otherwise it will make a "false" free time.. 
     if (momentStart.hour() < startWorkDayAM) { 
      const yesterday5pm = moment.tz(chrono.parseDate(`yesterday ${endWorkDayPM}pm`, momentStart), timeZone); 
      const today9am  = moment.tz(chrono.parseDate(`tomorrow ${startWorkDayAM}am`, yesterday5pm), timeZone); 
      epochBusyRanges.push({start: Number(yesterday5pm), end: Number(today9am)}); 
     } 
     //insert weekends manually 
     let nextWeekendStart = moment.tz(chrono.parseDate(`this ${weekendStartDateTime}`, momentStart), timeZone); 
     let nextWeekendEnd; 
     while (Number(nextWeekendStart) < Number(momentEnd)) { 
      nextWeekendEnd = moment.tz(chrono.parseDate(`next ${weekendEndDateTime}`, nextWeekendStart), timeZone); 
      epochBusyRanges.push({start: Number(nextWeekendStart), end: Number(nextWeekendEnd)}); 
      nextWeekendStart = moment.tz(chrono.parseDate(`this ${weekendStartDateTime}`, nextWeekendEnd), timeZone); 
     } 
     //we need also last weekend if we happen to be inside it. 
     if (momentStart.day() === 0 || momentStart.day() === 6) { 
      const lastWeekendStart = moment.tz(chrono.parseDate(weekendStartDateTime, momentStart), timeZone); 
      const lastWeekendEnd = moment.tz(chrono.parseDate(`next ${weekendEndDateTime}`, lastWeekendStart), timeZone); 
      epochBusyRanges.push({start: Number(lastWeekendStart), end: Number(lastWeekendEnd)}); 

     } 
     //sort the times 
     epochBusyRanges.sort((o1, o2) => o1.start > o2.start); 
     //merge busy blocks 
     epochBusyRanges = merge(epochBusyRanges.map(o => [o.start, o.end])); 
     //map again to our format 
     epochBusyRanges = epochBusyRanges.map(o => {return {start: o[0], end: o[1]}}); 
     //find next hour 
     for (let i = 0; i < epochBusyRanges.length; i++) { 
      const _start = i === 0 ? start : epochBusyRanges[i - 1].end; 
      const _end = epochBusyRanges[i].start; 
      if ((_end - _start) >= minMeetingTimeMS) { 
      return _start; 
      } 
     } 
     //maybe there is a free time after the last busy block 
     if (epochBusyRanges.length > 0) { 
      const _start = epochBusyRanges[epochBusyRanges.length - 1].end; 
      if ((end - _start) >= minMeetingTimeMS) { 
      return _start 
      } 
     } 
     //not busy time at all. so just check for the duration between start and end 
     if (epochBusyRanges.length === 0) { 
      if ((end - start) >= minMeetingTimeMS) { 
      return start; 
      } 
     } 
     return null; 
     } 


//helper function: given [[10,20],[12,30],[40,50]] --- > [[10,30],[40,50]] 
function merge(arr) { 
      // copy and sort the array 
      const result = arr.slice().sort((a, b) => a[0] > b[0]); 
      let i  = 0; 
      while (i < result.length - 1) { 
      const current = result[i], 
        next = result[i + 1]; 
      // check if there is an overlapping 
      if (current[1] >= next[0]) { 
       current[1] = Math.max(current[1], next[1]); 
       // remove next 
       result.splice(i + 1, 1); 
      } else { 
       // move to next 
       i++; 
      } 
      } 
      return result; 
     } 

Antwort

1

Es ist in der Regel nicht einfach, mit Zeitstempel oder Bereiche zu arbeiten, und Sie versuchen, bot zu tun h.

Das gesagt, Sie können möglicherweise Ihre Logik mit moment-range vereinfachen. Es unterstützt grundlegende Arithmetik (Addieren, Subtrahieren, Überlappungen, Überschneidungen, ...) und Iteration.

+0

Dank der verfügbaren Arithmetik, können Sie grobe Schritte des Algorithmus zur Verfügung stellen? – YardenST

Verwandte Themen