5
$\begingroup$

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.

$\endgroup$
1

3 Answers 3

8
$\begingroup$

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 *)

$\endgroup$
7
  • $\begingroup$ Does IntervalMemberQ handle datetime objects in 10.0? $\endgroup$ Commented Apr 27, 2015 at 16:57
  • $\begingroup$ @2012rcampion no it doesn't. but you can convert to AbsoluteTime. $\endgroup$
    – Eric Brown
    Commented Apr 27, 2015 at 17:38
  • $\begingroup$ David, I'd add that to your answer, considering the question: "I need to know if I'm in such an interval or not" $\endgroup$ Commented Apr 27, 2015 at 17:40
  • $\begingroup$ @2012rcampion See my amended answer for the answer to your interval question. $\endgroup$ Commented Apr 27, 2015 at 17:59
  • $\begingroup$ How would you represent "From Monday to Friday, from 8 am to 12pm and from 1pm to 4pm"? It would require an infinite number of DateObjects it seems. $\endgroup$
    – C. E.
    Commented Apr 27, 2015 at 19:15
2
$\begingroup$

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 *)
$\endgroup$
2
$\begingroup$

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
        ]
    ];
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.