Algoritmo per calcolare gli orari degli appuntamenti?

4

Ho una strana situazione in cui un cliente vorrebbe uno script che imposta automaticamente migliaia di appuntamenti per diversi giorni. La parte più delicata è che gli appuntamenti riguardano una varietà di fusi orari negli Stati Uniti e devo tenere conto del fuso orario locale del consumatore quando si generano date e orari degli appuntamenti per ciascun record.

Regole per gli appuntamenti:

  • Gli appuntamenti devono essere impostati dalle 8:00 alle 20:00, ora internazionale orientale, con pause da 12P-2P e 4P-6P. Questo lascia un totale di 8 ore al giorno disponibili per l'impostazione degli appuntamenti.

  • Gli appuntamenti dovrebbero essere programmati a 5 minuti di distanza l'uno dall'altro. 8 ore di intervalli di 5 minuti significa 96 appuntamenti al giorno.

  • Ci saranno 5 utenti alla volta che gestiscono gli appuntamenti. 96 appuntamenti al giorno moltiplicati per 5 utenti equivalgono a 480, quindi il numero massimo di appuntamenti che è possibile impostare al giorno è 480.

  • Ora il difficile requisito: gli appuntamenti sono limitati alle 8:00 alle 20:00 nel fuso orario locale del consumatore . Ciò significa che il primo orario consentito per ciascun appuntamento è diverso a seconda del fuso orario del consumatore:

    • Orientale: 8A
    • Centrale: 9A
    • Montagna: 10A
    • Pacific: 11A
    • Alaska: 12P
    • Hawaii o non definito: 2P
    • Arizona: 10A o 11A in base all'ora legale corrente

Supponendo che un set di dati possa essere diverse migliaia di record e ogni record conterrà un valore di fuso orario, esiste un algoritmo che potrei usare per determinare una data e un'ora per ogni record che corrisponde alle regole sopra?

    
posta Rachel 10.07.2012 - 18:10
fonte

3 risposte

2

Ho pensato ad un algoritmo che credo funzionerà per questo

Inizierò creando una struttura per tenere traccia degli appuntamenti man mano che vengono impostati. Può essere qualcosa di così semplice:

class Day
{
    public DateTime Date { get; set; }
    public List<DateTime> AssignedTimes { get; }

    // Assigns the next available time to a record, 
    // or returns false if no time is available
    public bool AssignNextAvailableTime(MyRecord record, int minHour)
    {
        // Get the next available time after minimum hour, 
        // based off of the list of already AssignedTimes, 
        // and whatever other logic is needed
        var nextAvailableTime = GetNextAvailableTime();

        if (nextAvailableTime == DateTime.MinValue) 
            return false;

        record.AppointmentDateTime = nextAvailableTime;
        AssignedTimes.Add(nextAvailableTime);

        return true;
    }
}

Passa in rassegna i record più restrittivi (Hawaii o Non definito) e assegnali a una data e un'ora, aggiungendo un giorno se necessario. Ecco un esempio da dimostrare:

List<Day> days = new List<Day>();

foreach(var record in records.Where(r => r.TimeZone == null || r.TimeZone == "Hawaii"))
{
    foreach(var day in days)
        if (day.AssignNextAvailableTime(record, 14))
            break;

    if (record.AppointmentDateTime == null)
    {
        var day = new Day();
        day.AssignNextAvailableTime(record, 14);
        days.Add(day);
    }
}

Fai la stessa cosa con il resto dei fusi orari, passando dal più restrittivo al meno restrittivo.

Il risultato finale sarà che a ogni record viene assegnata una data e un'ora tra 8a e 8p nell'ora locale del consumatore e le date / ore saranno le più compatte possibile, il che significa che verrà utilizzato il numero minimo di giorni per pianificare tutti gli appuntamenti

    
risposta data 10.07.2012 - 18:48
fonte
1

Immagino di poter inserire i miei commenti insieme in una risposta completa:

Modello dati

Utente - L'astrazione del tuo utente:

  • UserId

  • TimeZone

Appuntamento : un appuntamento programmato:

  • AppointmentId

  • UserId

  • DateRange (5 minuti a partire da un timestamp UTC)

Giorno - Prendendo in prestito pesantemente dalla tua risposta Rachel, questo oggetto sarà un elenco derivato di tutti gli appuntamenti per un singolo giorno ...

MA ... L'idea di un singolo giorno è un concetto fluttuante. A seconda del fuso orario dell'utente, un giorno di una persona potrebbe sovrapporsi a un altro giorno di persone , pertanto il giorno è relativo a un fuso orario degli utenti, pertanto i DateRanges negli appuntamenti per quel giorno potrebbero essere completamente diverso a seconda del fuso orario di cui stiamo parlando.

Per recuperare gli appuntamenti di un giorno: Dato un fuso orario, determina l'elenco di DateRang statici, 8 am- 8pm con interruzioni. Successivamente, recupera tutti gli appuntamenti per DateRange che rientrano in questo.

Concorrenza

La pianificazione attiva è sensibile al fattore tempo e rappresenta una risorsa di quantità limitata per la quale gli utenti sono in competizione (devi guardarla in questi termini). Il blocco della tabella degli appuntamenti durante la convalida e la pianificazione per un singolo utente è necessario per evitare la doppia prenotazione.

Algoritmo

Dopo aver recuperato un giorno per un determinato utente e il rispettivo fuso orario:

  • Passa in rassegna le Date Date automatiche del giorno e assicurati che l'orario dell'appuntamento richiesto rientri in uno di questi intervalli.

  • Passa il ciclo degli appuntamenti già pianificati e assicurati che l'orario dell'appuntamento richiesto non si sovrapponga a nessun appuntamento pianificato esistente.

  • Se passano queste convalide, crea un nuovo appuntamento con il suo DateRange appropriato e persist.

  • Risciacquare e ripetere ...

risposta data 10.07.2012 - 20:07
fonte
0

Creerei un'interfaccia per i fusi orari usando il tempo militare (24 ore).

Come in, per il fuso orario x, EST = tempo; CST = tempo + 1; MST = tempo + 2;

e così via.

Quindi, è possibile passare il fuso orario alla funzione dell'appuntamento, quindi il tempo verrà calcolato automaticamente quando si crea o si modifica un appuntamento. Nella funzione appuntamento, è possibile inserire facilmente la logica if / then per le interruzioni, ad esempio:

    if((time>12:00 && time<14:00) || (time>16:00 && time<18:00)){
    //code for break time, no appointments made here, timezone lets you use the current timezone you're in
    }
    
risposta data 10.07.2012 - 18:51
fonte

Leggi altre domande sui tag