Code covered by the BSD License

### Highlights from Round off dates and times

4.75
4.8 | 4 ratings Rate this file 26 Downloads (last 30 days) File Size: 5.99 KB File ID: #26374 Version: 1.1

# Round off dates and times

### Kevin J. Delaney (view profile)

13 Jan 2010 (Updated )

Rounds off a datenum to the nearest second, minute, hour, day, month or year.

File Information
Description

Rounds off a datenum to the nearest second, minute, hour, day, month or year. Zip file includes "units.m" (file 4093) by Henning Ressing.

Example: datenum_round_off(now, 'minute')

Acknowledgements

Units.M inspired this file.

This file inspired Round Serial Date Numbers Or Date Vectors.

MATLAB release MATLAB 7.9 (R2009b)
20 Jun 2016 Hossein Sangrody

### Hossein Sangrody (view profile)

29 Sep 2015 Kai Parker

### Kai Parker (view profile)

I had a bit of a problem with this function as it introduced a slight rounding error in floating point notation in comparison to the datenum command. This causes a failure when using intersect. Solved by adding:

% Deal with rounding issues by converting to a datevector then back to a
% datenumber;
temp = datevec(datenum_rounded);
datenum_rounded = datenum(temp);

Comment only

This solved my problem perfectly, right out of the box. Thanks for sharing.

20 Oct 2014 Matlab2010

### Matlab2010 (view profile)

with the below mod:

function datenum_rounded = datenum_round_off(datenum_in, time_unit_string, direction)
% Rounds off a datenum to the nearest second, minute, hour, whatever.
%
% datenum_rounded = datenum_round_off(datenum_in, time_unit_string)
%
% Inputs:
% datenum_in Date/time in Matlab datenum format
% time_unit_string String like 'minute', 'second', etc.
%
% Output:
% datenum_rounded Input value rounded off

% Kevin J. Delaney
% January 13, 2010
if(nargin<3)
direction = 'default';
end

datenum_rounded = [];

if ~exist('datenum_in', 'var')
help(mfilename);
return
end

if isempty(datenum_in) || ~isnumeric(datenum_in)
errordlg('Input "datenum_in" is empty or non-numeric.', mfilename);
return
end

if ~exist('time_unit_string', 'var') || ...
isempty(time_unit_string) || ...
~ischar(time_unit_string)
errordlg('Input "time_unit_string" is missing, empty or non-char.', ...
mfilename);
return
end

switch lower(time_unit_string)
case {'second', 'seconds', 'sec', 's'}
time_unit = units(1, 'second', 'day');

case {'minute', 'minutes', 'min', 'm'}
time_unit = units(1, 'minute', 'day');

case {'hour', 'hours', 'hr', 'h'}
time_unit = units(1, 'hour', 'day');

case {'day', 'days', 'd'}
time_unit = 1;

case {'month', 'months', 'mon'}
% Break up the input into year, month, day components.
[yr, mon, day, hr, min, sec] = datevec(datenum_in);

% Are we halfway through the month?
datenum_start_of_this_month = datenum(yr, mon, ones(size(day)), zeros(size(hr)), zeros(size(min)), zeros(size(sec)));
datenum_start_of_next_month = datenum(yr, mon + 1, ones(size(day)), zeros(size(hr)), zeros(size(min)), zeros(size(sec)));
round_up_to_next_month_syndrome = (datenum_start_of_next_month - datenum_in) < (datenum_in - datenum_start_of_this_month);
boost_vector = zeros(size(datenum_in));
boost_vector(round_up_to_next_month_syndrome) = 1;
datenum_rounded = datenum(yr, mon + boost_vector, ones(size(day)), zeros(size(hr)), zeros(size(min)), zeros(size(sec)));
return

case {'year', 'years', 'yr'}
% Break up the input into year, month, day components.
[yr, mon, day, hr, min, sec] = datevec(datenum_in);

% Are we halfway through the year?
datenum_start_of_this_year = datenum(yr, ones(size(mon)), ones(size(day)), zeros(size(hr)), zeros(size(min)), zeros(size(sec)));
datenum_start_of_next_year = datenum(yr + 1, ones(size(mon)), ones(size(day)), zeros(size(hr)), zeros(size(min)), zeros(size(sec)));
round_up_to_next_year_syndrome = (datenum_start_of_next_year - datenum_in) < (datenum_in - datenum_start_of_this_year);
boost_vector = zeros(size(datenum_in));
boost_vector(round_up_to_next_year_syndrome) = 1;
datenum_rounded = datenum(yr + boost_vector, ones(size(mon)), ones(size(day)), zeros(size(hr)), zeros(size(min)), zeros(size(sec)));
return

otherwise
errordlg(['Unknown time unit: "', time_unit_string, '".'], mfilename);
return
end

if(strcmpi(direction, 'default'))
datenum_rounded = time_unit * round(datenum_in / time_unit);
elseif(strcmpi(direction, 'down'))
datenum_rounded = time_unit * floor(datenum_in / time_unit);
elseif(strcmpi(direction, 'up'))
datenum_rounded = time_unit * ceil(datenum_in / time_unit);
end

end

Comment only
20 Sep 2013 janez

### janez (view profile)

26 Jun 2012 Andrea

### Andrea (view profile)

Nice one, thanks. You can add the possibility of rounding down, up or scientifically by changing the final "round" with floor, ceil or leave it to round (and possibly make the user decide with an argument to the function)