Home > src > seconds2human.m

# seconds2human

## PURPOSE

- human readable time output

## SYNOPSIS

function out = seconds2human(secs, varargin)

## DESCRIPTION

     - human readable time output

     The original version of this code is covered on the BSD license and is
     copyright by Rody Olennhuis.  Minor updates to this code are covered
     either this same BSD license, or, if applicable, but the umbrella GPL
     license used by the SOS software, as follows:

## CROSS-REFERENCE INFORMATION

This function calls:

This function is called by:

- sos - SOS optimization object

## SOURCE CODE

    0001 % - human readable time output
    0002 %
    0003 % The original version of this code is covered on the BSD license and is
    0004 % copyright by Rody Olennhuis.  Minor updates to this code are covered
    0005 % either this same BSD license, or, if applicable, but the umbrella GPL
    0006 % license used by the SOS software, as follows:
    0007
    0008 % copyright 2009-2012 Blair Armstrong, Christine Watson, David Plaut
    0009 %
    0010 %    This file is part of SOS
    0011 %
    0012 %    SOS is free software: you can redistribute it and/or modify
    0013 %    it for academic and non-commercial purposes
    0014 %    under the terms of the GNU General Public License as published by
    0015 %    the Free Software Foundation, either version 3 of the License, or
    0016 %    (at your option) any later version.  For commercial or for-profit
    0017 %    uses, please contact the authors (sos@cnbc.cmu.edu).
    0018 %
    0019 %    SOS is distributed in the hope that it will be useful,
    0020 %    but WITHOUT ANY WARRANTY; without even the implied warranty of
    0021 %    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    0022 %    GNU General Public License for more details.
    0023
    0024 %    You should have received a copy of the GNU General Public License
    0025 %    along with SOS (see COPYING.txt).
    0026 %    If not, see <http://www.gnu.org/licenses/>.
    0027
    0028
    0029 function out = seconds2human(secs, varargin)
    0030 %% outputs time in human readable format.  Slightly modified version of Rody P.S. Oldenhuis's version
    0031 %
    0032 %   str = SECONDS2HUMAN(seconds) returns a human-readable string from a
    0033 %   given (usually large) amount of seconds. For example,
    0034 %
    0035 %       str = seconds2human(1463456.3)
    0036 %
    0037 %       str =
    0038 %       'About 2 weeks and 2 days.'
    0039 %
    0040 %   You may also call the function with a second input argument; either
    0041 %   'short' (the default) or 'full'. This determines the level of detail
    0042 %   returned in the string:
    0043 %
    0044 %       str = seconds2human(1463456.3, 'full')
    0045 %
    0046 %       str =
    0047 %       '2 weeks, 2 days, 22 hours, 30 minutes, 56 seconds.'
    0048 %
    0049 %   The 'short' format returns only the two largest units of time.
    0050 %
    0051 %   [secs] may be an NxM-matrix, in which case the output is an NxM cell
    0052 %   array of the corresponding strings.
    0053 %
    0054 %   NOTE: SECONDS2HUMAN() defines one month as an "average" month, which
    0055 %   means that the string 'month' indicates 30.471 days.
    0056 %
    0057 %   See also datestr, datenum, etime.
    0058
    0059
    0060 %   Author: Rody P.S. Oldenhuis
    0061 %   Delft University of Technology
    0062 %   E-mail: oldnhuis@dds.nl
    0063 %   Last edited 11/Feb/2010.
    0064
    0065 %  Modified by Blair Armstrong, July 11, 2010
    0066 %   Carnegie Mellon University
    0067
    0068
    0069     % default error
    0070     error(nargchk(1,2,nargin));%#ok
    0071
    0072     % define some intuitive variables
    0073     Seconds   = round(1                 );
    0074     Minutes   = round(60     * Seconds  );
    0075     Hours     = round(60     * Minutes  );
    0076     Days      = round(24     * Hours    );
    0077     Weeks     = round(7      * Days     );
    0078     Months    = round(30.471 * Days     );
    0079     Years     = round(365.26 * Days     );
    0080     Centuries = round(100    * Years    );
    0081     Millennia = round(10     * Centuries);
    0082
    0083     % put these into an array, and define associated strings
    0084     units   = [Millennia, Centuries, Years, Months, Weeks, ...
    0085                Days, Hours, Minutes, Seconds];
    0086     singles = {'millennium'; 'century'; 'year'; 'month'; ...
    0087                'w'; 'd'; 'h'; 'm'; 's'};
    0088     plurals = {'millennia' ; 'centuries'; 'years'; 'months'; ...
    0089                'w'; 'd'; 'h'; 'm'; 's'};
    0090
    0091     % cut off all decimals from the given number of seconds
    0092     assert(isnumeric(secs), 'seconds2human:seconds_mustbe_numeric', ...
    0093         'The argument ''secs'' must be a scalar or matrix.');
    0094     secs = round(secs);
    0095
    0096     % parse second argument
    0097     short = true;
    0098     if (nargin > 1)
    0099         % extract argument
    0100         short = varargin{1};
    0101         % check its type
    0102         assert(ischar(short), 'seconds2human:argument_type_incorrect', ...
    0103             'The second argument must be either ''short'' or ''full''.');
    0104         % check its contents
    0105         switch lower(short)
    0106             case 'full' , short = false;
    0107             case 'short', short = true;
    0108             otherwise
    0109                 error('seconds2human:short_format_incorrect',...
    0110                     'The second argument must be either ''short'' or ''full''.');
    0111         end
    0112     end
    0113
    0114     % pre-allocate appropriate output-type
    0115     numstrings = numel(secs);
    0116     if (numstrings > 1), out = cell(size(secs)); end
    0117
    0118     % build (all) output string(s)
    0119     for j = 1:numstrings
    0120
    0121         % initialize nested loop
    0122         secsj   = secs(j);
    0123         counter = 0;
    0124         if short, string = '';
    0125         else      string = '';
    0126         end
    0127
    0128         % possibly quick exit
    0129         if (secsj < 1), string = '1s'; end
    0130
    0131         % build string for j-th amount of seconds
    0132         for i = 1:length(units)
    0133
    0134             % amount of this unit
    0135             amount = fix(secsj/units(i));
    0136
    0137             % include this unit in the output string
    0138             if amount > 0
    0139
    0140                 % increase counter
    0141                 counter = counter + 1;
    0142
    0143                 % append (single or plural) unit of time to string
    0144                 if (amount > 1)
    0145                     string = [string, num2str(amount), '', plurals{i}];%#ok
    0146                 else
    0147                     string = [string, num2str(amount), '', singles{i}];%#ok
    0148                 end
    0149
    0150                 % Finish the string after two units if short format is requested
    0151                 if (counter > 1 && short), string = [string, '.']; break, end%#ok
    0152
    0153                 % determine whether the ending should be a period (.) or a comma (,)
    0154                 if (rem(secsj, units(i)) > 0)
    0155                     if short, ending = ' and ';
    0156                     else ending = ' ';
    0157                     end
    0158                 else ending = '';
    0159                 end
    0160                 string = [string, ending];%#ok
    0161
    0162             end
    0163
    0164             % subtract this step from given amount of seconds
    0165             secsj = secsj - amount*units(i);
    0166         end
    0167
    0168         % insert in output cell, or set output string
    0169         if (numstrings > 1)
    0170             out{j} = string;
    0171         else
    0172             out = string;
    0173         end
    0174     end % for
    0175
    0176 end % seconds2human