7
$\begingroup$

Consider the following scenario.

Suppose I consider time range from TimeObject[{18,30,0}] to TimeObject[{22,30,0}] on Weekdays and TimeObject[{18,0,0}] to TimeObject[{22,0,0}] on Weekends as peak time for something.

Now given a date range DateObject[{2019,7,18,20,12,30}] to DateObject[{2019,7,31,18,45,30}]. I want to find the intervals of peak times encountered in this range. Also I want to find the proportion of time spend in peak? What is the easiest way to calculate this using the Mathematica's Date and Time functionality.

Does Wolfram language provide a symbolic wrapper to represent a date/time interval and also a disjoint but periodic intervals of time?


Thank you @kglr it works! Although "Duration" property does not exactly calculate what I want but the following workaround works.

With[{
    interval=DateTime`DateInterval[{3755358615, 3755368800}, {3755440800, 3755455200}, {3755527200, 3755540710}, True]
},
    {
        Query[Apply[Plus]@*All,Apply[Subtract]@*Reverse]@interval["Dates"],
        interval["Duration"],
        DateObject[{2019,1,1,19,10,15},"Instant","Gregorian",1.`]-DateObject[{2019,1,3,21,45,10},"Instant","Gregorian",1.`]
    }
]
$\endgroup$
10
$\begingroup$

Yes ... there is (undocumented) DateTime`DateInterval:

di = DateTime`DateInterval[{DateObject[{2019, 7, 18, 1, 30, 0}] , 
       DateObject[{2019, 7, 18, 12, 30, 0}]}]

enter image description here

Options[DateTime`DateInterval]

{CalendarType -> Automatic, TimeZone :> $TimeZone}

di["Properties"]

{"CalendarType", "DateRange", "Dates", "DayCount", "Duration", "Max", "Min", "RawDates", "TimeZone"}

di /@ {"Min", "Max"}

enter image description here

di["Duration"]

Quantity[0.458333, "Days"]

UnitConvert[di["Duration"], "Seconds"]

Quantity[39600., "Seconds"]

Multiple intervals:

dilist = DateTime`DateInterval /@ 
   {{DateObject[{2019, 7, 18, 1, 30}] , DateObject[{2019, 7, 21, 12, 30}]}, 
    {DateObject[{2019, 7, 20, 2, 45}] , DateObject[{2019, 7, 22, 10, 30}]}};

Column @ dilist

enter image description here

Interval operations work the same way as for Interval objects:

IntervalIntersection @@ dilist 

enter image description here

IntervalUnion @@ dilist 

enter image description here

Show[TimelinePlot[Association /@ 
   (Column[Insert[DateObject /@ #[[1]], "thru", 2], Center] -> # & /@ dilist), 
     AxesOrigin -> Bottom],
 TimelinePlot[Association[
    Column[Insert[DateObject /@ #[[1]], "thru", 2], Center] -> # &[
     IntervalIntersection @@ dilist]], 
     AxesOrigin -> Top, PlotStyle -> Red], 
  PlotRange -> All, Frame -> False, Axes -> {True, False}]

enter image description here

Note: Used this answer by Vitaliy Kaurov to avoid label clutter in TimelinePlot.

$\endgroup$
  • 1
    $\begingroup$ Thanks for this answer. I did not know about this undocumented functionality. $\endgroup$ – Anton Antonov Jul 30 at 20:28
  • 2
    $\begingroup$ @Anton, I did not know about it myself till I tried Names["*`*Date*Interval*"]:) $\endgroup$ – kglr Jul 30 at 20:33
  • 2
    $\begingroup$ @klgr I am near speechless that that actually worked. It tells you something about the consistency of Mathematica's naming scheme, and perhaps the number of functions existing behind the scenes. $\endgroup$ – lirtosiast Jul 31 at 7:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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