Three weeks ago I wrote about MATLAB's new spreadsheet import tool. Since then I've had a few conversations regarding using dates in MATLAB; dates are common as column headers or table data. The import tool will turn Excel dates into MATLAB datenums. A datenum in MATLAB is just a double that represents any date & time after midnight Jan 1, 0000 AD. MATLAB comes with several useful functions for handling these special case numbers, and in particular for displaying them.
The now, clock, and date functions will provide the current date & time as a datenum, datevec, or detestr, respectively. While a datenum is a single number representing the date and time, a datevec splits the year, month, day, hour, minute, and second components out in 1x6 vector. A datestr is the string representation of a date time. There are a ton formatting options available for how the date and time are displayed (see below).
currentTimeAndDate = now currentTimeAndDateAsVector = clock currentDateAsString = date
currentTimeAndDate = 7.3484e+05 currentTimeAndDateAsVector = 2011 11 28 8 50 20.486 currentDateAsString = 28-Nov-2011
As far as the data is concerned, these three date types are interchangeable using the conversion functions. You can use the datenum, datevec, and datestr functions to convert between the three types. Individual functions that perform calculations on dates usually prefer a particular format, for example addtodate looks for datenum types.
currentDateAsNumber = datenum(currentDateAsString) currentDateAndDtimeAsNumber = datenum(currentTimeAndDate) %note the difference from above currentDate = datestr(currentTimeAndDate) currentDateAsVector = datevec(currentDateAsString)
currentDateAsNumber = 734835 currentDateAndDtimeAsNumber = 7.3484e+05 currentDate = 28-Nov-2011 08:50:20 currentDateAsVector = 2011 11 28 0 0 0
The usage of dates I'm particularly interested in is with plots. Let's say we have some time-varying data and we want the x-axis to reflect those dates. If I just plot the data against the datenum, by default the x-labels will all be large, ugly numbers.
firstInMonths = repmat([2011 1 1 0 0 0],12,1); firstInMonths(:,2) = 1:12; bar(datenum(firstInMonths),rand(1,12)*10)
Thankfully, MATLAB comes with a simple function, datetick, for turning those numbers into strings:
Unfortunately, those tick labels aren't very pretty. Let's use a date format with the datetick function to specify how we want labels to look. For this function, we can use any date format recognized by the detestr function (see below).
Finally, for your reference, here is the help information for datestr, which lists how to formate a date string:
DATESTR String representation of date. S = DATESTR(V) converts one or more date vectors V to date strings S. Input V must be an M-by-6 matrix containing M full (six-element) date vectors. Each element of V must be a positive double-precision number. DATESTR returns a column vector of M date strings, where M is the total number of date vectors in V. S = DATESTR(N) converts one or more serial date numbers N to date strings S. Input argument N can be a scalar, vector, or multidimensional array of positive double-precision numbers. DATESTR returns a column vector of M date strings, where M is the total number of date numbers in N. S = DATESTR(D, F) converts one or more date vectors, serial date numbers, or date strings D into the same number of date strings S. Input argument F is a format number or string that determines the format of the date string output. Valid values for F are given in Table 1, below. Input F may also contain a free-form date format string consisting of format tokens as shown in Table 2, below. Date strings with 2-character years are interpreted to be within the 100 years centered around the current year. S = DATESTR(S1, F, P) converts date string S1 to date string S, applying format F to the output string, and using pivot year P as the starting year of the 100-year range in which a two-character year resides. The default pivot year is the current year minus 50 years. F = -1 uses the default format. S = DATESTR(...,'local') returns the string in a localized format. The default (which can be called with 'en_US') is US English. This argument must come last in the argument sequence. Note: The vectorized calling syntax can offer significant performance improvement for large arrays. Table 1: Standard MATLAB Date format definitions Number String Example =========================================================================== 0 'dd-mmm-yyyy HH:MM:SS' 01-Mar-2000 15:45:17 1 'dd-mmm-yyyy' 01-Mar-2000 2 'mm/dd/yy' 03/01/00 3 'mmm' Mar 4 'm' M 5 'mm' 03 6 'mm/dd' 03/01 7 'dd' 01 8 'ddd' Wed 9 'd' W 10 'yyyy' 2000 11 'yy' 00 12 'mmmyy' Mar00 13 'HH:MM:SS' 15:45:17 14 'HH:MM:SS PM' 3:45:17 PM 15 'HH:MM' 15:45 16 'HH:MM PM' 3:45 PM 17 'QQ-YY' Q1-96 18 'QQ' Q1 19 'dd/mm' 01/03 20 'dd/mm/yy' 01/03/00 21 'mmm.dd,yyyy HH:MM:SS' Mar.01,2000 15:45:17 22 'mmm.dd,yyyy' Mar.01,2000 23 'mm/dd/yyyy' 03/01/2000 24 'dd/mm/yyyy' 01/03/2000 25 'yy/mm/dd' 00/03/01 26 'yyyy/mm/dd' 2000/03/01 27 'QQ-YYYY' Q1-1996 28 'mmmyyyy' Mar2000 29 (ISO 8601) 'yyyy-mm-dd' 2000-03-01 30 (ISO 8601) 'yyyymmddTHHMMSS' 20000301T154517 31 'yyyy-mm-dd HH:MM:SS' 2000-03-01 15:45:17 Table 2: Free-form date format symbols Symbol Interpretation of format symbol =========================================================================== yyyy full year, e.g. 1990, 2000, 2002 yy partial year, e.g. 90, 00, 02 mmmm full name of the month, according to the calendar locale, e.g. "March", "April" in the UK and USA English locales. mmm first three letters of the month, according to the calendar locale, e.g. "Mar", "Apr" in the UK and USA English locales. mm numeric month of year, padded with leading zeros, e.g. ../03/.. or ../12/.. m capitalized first letter of the month, according to the calendar locale; for backwards compatibility. dddd full name of the weekday, according to the calendar locale, e.g. "Monday", "Tuesday", for the UK and USA calendar locales. ddd first three letters of the weekday, according to the calendar locale, e.g. "Mon", "Tue", for the UK and USA calendar locales. dd numeric day of the month, padded with leading zeros, e.g. 05/../.. or 20/../.. d capitalized first letter of the weekday; for backwards compatibility HH hour of the day, according to the time format. In case the time format AM | PM is set, HH does not pad with leading zeros. In case AM | PM is not set, display the hour of the day, padded with leading zeros. e.g 10:20 PM, which is equivalent to 22:20; 9:00 AM, which is equivalent to 09:00. MM minutes of the hour, padded with leading zeros, e.g. 10:15, 10:05, 10:05 AM. SS second of the minute, padded with leading zeros, e.g. 10:15:30, 10:05:30, 10:05:30 AM. FFF milliseconds field, padded with leading zeros, e.g. 10:15:30.015. PM set the time format as time of morning or time of afternoon. AM or PM is appended to the date string, as appropriate. Examples: DATESTR(now) returns '24-Jan-2003 11:58:15' for that particular date, on an US English locale DATESTR(now,2) returns 01/24/03, the same as for DATESTR(now,'mm/dd/yy') DATESTR(now,'dd.mm.yyyy') returns 24.01.2003 To convert a non-standard date form into a standard MATLAB dateform, first convert the non-standard date form to a date number, using DATENUM, for example, DATESTR(DATENUM('24.01.2003','dd.mm.yyyy'),2) returns 01/24/03. See also DATE, DATENUM, DATEVEC, DATETICK. Reference page in Help browser doc datestr
If you're interested in using dates with MATLAB, here is a link to the date functions that are available.
4 CommentsOldest to Newest
Muy interesante, justo estaba con ese problema para poder colocar los meses en la variabilidad estacional.
Good post, helped me solve a problem with date strings cleanly.
Matlab’s date functions are very powerful. The intelligent input parsing allows for a smart error checking of user inputs:
Str = datestr(’31-Feb-2011 12:62:70′);
% replies ’03-Mar-2011 13:03:10′
A drawback of this power is the computing time: If the input has a well defined format and the values are known to be valid (e.g. the file date taken from DIR), the conversion can be done much faster. Examples:
DATESTR(0) -> DATEVEC format: 50 times faster (See http://www.mathworks.com/matlabcentral/fileexchange/25594-dateconvert )
DATESTR(0) -> DATENUM format: 200 times faster (See http://www.mathworks.com/matlabcentral/fileexchange/28093-datestr2num )
Kind regards, Jan
Whilst I appreciate the datetick method, it really needs to be more dynamic.
Currently if you call datetick on an axis it converts the labels at the current tick locations to a formatted date string. However, if you zoom in, the tick locations are not recalculated and you typically end up with a label-less x-axis. Also, if you call datetick when zoomed in it appears to re-determine new tick locations but re-uses the old label values.
What it needs to be is a mode on the x-axis (much like ‘semilog’ where it will treat the x-values at datetimes and use the figure’s OnZoom callbacks to recalculate appropriate tick locations and reformat the labels with a user supplied formatting string.
Prior to OnZoom figure callbacks being available I used to create a timerFcn to apply to the axes that would relabel the axes every 100ms based on its current bounds.