5

What would be the best way to represent a complex schedule in Mathematica ?

For example a representation of the plain words schedule: "From Monday to Friday, from 8 am to 12pm and from 1pm to 4pm", or another schedule like "Monday from 2am to 6am,Tuesday from 10 am to 11am, ..."

This needs stems from the fact that I need to start and stop scheduled tasks if I am in an interval specified by a schedule, and given a time I need to know if I'm in such an interval or not, in order to know if the state is "Started" or "Stopped".

Possibly somebody has had a similar need in Mathematica before, thank you.

Maybe one possibility would be to create a scheduled task that starts or stops the next bound of a time interval.

faysou
  • 10,999
  • 3
  • 50
  • 125
  • This may be what you need to look into.

    http://mathematica.stackexchange.com/questions/40739/schedule-programing-problem-with-integer-linear-programming

    – Bob Brooks Apr 27 '15 at 14:43

3 Answers3

8

Try (in version 10.1):

    TimelinePlot[{{Interval[{DateObject[{2015, 4, 27, 6, 30, 15}], 
     DateObject[{2015, 4, 28, 9, 15, 45}]}], 
   DateObject[{2015, 4, 28, 12, 0, 0}], 
   Interval[{DateObject[{2015, 4, 28, 15, 30, 0}], 
     DateObject[{2015, 4, 29, 10, 0, 
       0}]}]}, {Interval[{DateObject[{2015, 4, 28, 11, 0, 0}], 
     DateObject[{2015, 4, 29, 0, 0, 0}]}], 
   DateObject[{2015, 4, 29, 0, 30, 0}], 
   Interval[{DateObject[{2015, 4, 29, 12, 0, 0}], 
     DateObject[{2015, 4, 30, 18, 0, 0}]}]}},
 Ticks -> {
   ({DateObject[{2015, 4, #}],
       DateString[{2015, 4, #}, {"DayName", "  ", "Month", "/", 
         "Day"}]}) & /@ Range[26, 30]
   , Automatic} 
 ]

enter image description here

To check whether you're in an interval it appears you must convert to absolute time:

IntervalMemberQ[
 Interval[{AbsoluteTime[DateObject[{2015, 4, 27, 4, 30, 0}]], 
   AbsoluteTime[DateObject[{2015, 4, 29, 4, 30, 0}]]}], 
 AbsoluteTime[DateObject[{2015, 4, 28, 4, 30, 0}]]]

(* True *)

David G. Stork
  • 41,180
  • 3
  • 34
  • 96
2

In short: use DayMatchQ to check the day and use TimeObject for time intervals.

timeIntervals = {};

AppendTo[timeIntervals, {
    TimeObject[{8, 0, 0}],
   TimeObject[{12, 0, 0}]
   }];

AppendTo[timeIntervals, {
    TimeObject[{13, 0, 0}],
   TimeObject[{16, 0, 0}]
   }];

dayCriterias = {
   "Weekday"
   };

checkDay[day_, time_, timeIntervals_, dayCriterias_] := 
 Module[{dayMatch, timeMatch},
  dayMatch = Or @@ Map[DayMatchQ[day, #] &, dayCriterias];
  timeMatch = Or @@ (# < time < #2 & @@@ timeIntervals);
  And[dayMatch, timeMatch]
  ]

Examples, evaluated on a Monday:

checkDay[Today, TimeObject[{10, 0, 0}], timeIntervals, dayCriterias]
(* True *)

checkDay[Today, TimeObject[{12, 30, 0}], timeIntervals, dayCriterias]
(* False *)
C. E.
  • 70,533
  • 6
  • 140
  • 264
2

Here's how I did it. I use the fact that Sort sorts lists in lexicographic order.
Note that a schedule for a day of the form "Monday(23:40)" matches a time until the end of the day.

schedule="Monday(10:30-10:40/23:40-23:41:32),Tuesday(10:50-11:23:26)";
IsInTimeSchedule[schedule,{2004,3,8,23,41,31}]

The code:

parseTime[time_]:=StringSplit[time,"-"]//Map[(StringSplit[#,":"]//ToExpression)&];
parseDaySchedule[daySchedule_]:=StringCases[daySchedule,x__~~"("~~Shortest[y__]~~")":>{ToExpression@x,StringSplit[y,"/"]//Map[parseTime]}]//First;
g:parseSchedule[schedule_]:=g=StringSplit[schedule,","]//Map[parseDaySchedule];

isInTimeInInterval[timeInterval_,t_]:=t==Sort[Append[timeInterval,t]][[2]];(*Sort sorts lists in lexicographic order*)

IsInTimeSchedule[schedule_String,time_]:=IsInTimeSchedule[parseSchedule[schedule],time];
IsInTimeSchedule[schedule_,time_]:=
    Block[{dayName,daySchedule},

        dayName=DayName@time;
        daySchedule=SelectFirst[schedule,First@#===dayName&];

        If[daySchedule=!=Missing["NotFound"],
            AnyTrue[daySchedule[[2]],isInTimeInInterval[#,time[[4;;]]]&]
            ,
            False
        ]
    ];
faysou
  • 10,999
  • 3
  • 50
  • 125