Checking if a given date hour is within a predefin

2019-07-27 05:49发布

问题:

I have a table with dates (and other things), which I have extracted from a CSV file. In order to do some processing of my data (including plotting) I decided to convert all my date-strings to date-numbers (below for simplicity reasons I will exclude all the rest of the data and concentrate on the dates only so don't mind the step from dates to timetable and the fact that it can be omitted):

dates = [7.330249777777778e+05;7.330249291666667e+05;7.330246729166667;7.330245256944444;7.330246763888889;7.330245284722222;7.330245326388889;7.330246625000000];

timetable = table(dates);

timetable
_________
7.330249777777778e+05
7.330249291666667e+05
7.330246729166667
7.330245256944444
7.330246763888889
7.330245284722222
7.330245326388889
7.330246625000000

I'm facing the following issue - based on the time during the day I want to tell the user if a date is in the morning (24-hours scale: 5-12h), noon (12-13h), afternoon (13-18h), evening (18-21h), night (21-5h) based on the date I have stored in my table. In case I had a date-vector (with elements: year,month,day,hour,minute,second) it would be pretty straight forward:

for date = 1:size(timetable)
    switch timetable(date).hour
      case {5,12}
        'morning'
      case {12,13}
        'noon'
      case {13,18}
        'afternoon'
      case {18,21}
        'evening'
      otherwise
        'night'
    end
end

With 7.330246729166667 and the rest this is not that obvious at least to me. Any idea how to avoid converting to some other date-format just for this step and at the same time avoid some complex formula for extracting the required data (not necessarily hour only but I'm interested in the rest too)?

回答1:

One unit in Matlab serial dates is equivalent to 1 day, i.e. 24 hours. Knowing this, you can bin the fractional part of the the dates within the intraday buckets you defined (note that your switch will only work for values exactly equal to the case lists):

bins  = {'morning', 'noon', 'afternoon', 'evening', 'night'};
edges = [5,12,13,18,21,25]./24; % As fraction of a day

% Take fractional part
time = mod(dates,1);

% Bin with lb <= x < ub, where e.g. lb = 5/25 and is ub = 12/24
[counts,~,pos] = histcounts(time, edges);
% Make sure unbinned x in [0,5) are assigned 'night' 
pos(pos==0) = 5;

bins(pos)'
ans = 
    'night'
    'night'
    'morning'
    'morning'
    'morning'
    'morning'
    'morning'
    'morning'