LESSON 18: Working with dates

*FOCUS QUESTION: How can I extract information from data sets based on the date.

This lesson demonstrates how to work with dates in MATLAB.

In this lesson you will:
  • Work with the serial date number, string and vector representations of dates.
  • Use datenum to convert a string date to date number.
  • Use datevec to extract the year, month and day from a date number.
  • Use datestr to convert a serial date number to a string for output.
  • Extract the day-of-the-week from the date number.
Sample railway schedule that uses both 00:00 and 24:00

Contents


DATA FOR THIS LESSON

File Description
diaries.mat contains the extracted, cleaned, and consolidated sleep diary data in MATLAB variables. The arrays have a column for each person. The vectors have an element for each person. The values in column n correspond to the same person as the value in position n of each vector. The file contains the following variables:
  • bedTimes - array of bed times in decimal-date format.
  • dayCaffeine - array of daytime caffeine indicators.
  • gender - vector of male/female gender designators.
  • nightCaffeine - array of evening caffeine indicators.
  • section - vector of section indicators. The possible section numbers are 0, 1, 3 and 4. Section 0 contains only a single instructor. The remaining section numbers correspond to the actual course section numbers.
  • toSleepMinutes - an array of number of minutes to fall asleep.
  • useAlarm - array of alarm use indicators.
  • wakeTimes - array of wakeup times in decimal-date format.

SETUP FOR LESSON 18


EXAMPLE 1: Load the sleep diary data and find number of rows and columns

Create a new cell in which you type and execute:

    load diaries.mat;  % Load the sleep diaries
    [numDays, numDiaries] = size(bedTimes);  % How many rows and columns?
    fprintf('\n\n%g Sleep diaries kept for %g days\n', numDiaries, numDays);

You should see bedTimes, dayCaffeine, gender, nightCaffeine, section, toSleepMinutes, useAlarm, wakeTimes, numDays, and numDiaries variables in your Workspace. You should also see the following output in the Command Window:


144 Sleep diaries kept for 21 days


EXAMPLE 2: Output the day 1 wake-up time of the instructor in different formats

Create a new cell in which you type and execute:

    wakeDate = wakeTimes(1, 1);   % Pick out instructor's wake-up on first day
    fprintf('\nFormat\tDate\n');
    for format = 1:31
        fprintf('%g\t %s\n', format, datestr(wakeDate, format));
    end;

You should see wakeDate and format variables in your Workspace Browser and the following output in the Command Window.

Format	Date
1	 23-Sep-2009
2	 09/23/09
3	 Sep
4	 S
5	 09
6	 09/23
7	 23
8	 Wed
9	 W
10	 2009
11	 09
12	 Sep09
13	 05:49:00
14	  5:49:00 AM
15	 05:49
16	  5:49 AM
17	 Q3-09
18	 Q3
19	 23/09
20	 23/09/09
21	 Sep.23,2009 05:49:00
22	 Sep.23,2009
23	 09/23/2009
24	 23/09/2009
25	 09/09/23
26	 2009/09/23
27	 Q3-2009
28	 Sep2009
29	 2009-09-23
30	 20090923T054900
31	 2009-09-23 05:49:00


EXAMPLE 3: Convert a day to a date number and output in a different format

Create a new cell in which you type and execute:

   myDate = '10/01/2009';           %This is the date we want to look at
   myDateNum = datenum(myDate, 23); % Convert wake-up date to a number
   fprintf('\nOriginal date = %s, decimal date number is %g, new format is %s\n', ...
           myDate, myDateNum, datestr(myDateNum, 26)); % Output in readable format

You should see myDate and myDateNum variables in your Workspace and the following output in the Command Window:

Original date = 10/01/2009, decimal date number is 734047, new format is 2009/10/01


EXAMPLE 4: Calculate the average wake-up time for a particular date

Create a new cell in which you type and execute:

   myDayNum = floor(myDateNum);   % Throw away minutes and seconds if needed
   dayRowV = floor(wakeTimes(:, 1)) == myDayNum; % Find rows for this date
   wakeupTimes = wakeTimes - floor(wakeTimes); % Calculate wake-up time
   dayTimes = wakeupTimes(dayRowV, :);  % Pick out row(s) for this day
   averageWakeup = mean(dayTimes);  % Calculate average wake-up for that day
   fprintf('\nAverage wake-up time on %s was: %s\n', ...
           datestr(myDayNum, 23), datestr(averageWakeup, 16)); % Output

You should see myDayNum, dayRowV, wakeupTimes, dayTimes, and averageWakeup variables in your Workspace. You should also see the following output in the Command Window. Note: This example assumes that every subject has exactly one wake-up time on the specified date.

Average wake-up time on 10/01/2009 was:  8:19 AM


EXAMPLE 5: Calculate the average wake-up time for particular date (alternative)

Create a new cell in which you type and execute:

   dayRowVAlt = floor(wakeTimes) == myDayNum; % Find rows for this date
   dayRowVAlt = dayRowVAlt(:);     % Everyone's wake-up days may not be same
   wakeupTimesAlt = wakeupTimes(:);
   dayTimesAlt = wakeupTimesAlt(dayRowVAlt); % Pick out all relevant entries
   averageWakeupAlt = mean(dayTimesAlt);  % Calculate average wake-up for those entries
   fprintf('\nAverage wake-up time on %s was: %s\n', ...
           datestr(myDayNum, 23), datestr(averageWakeupAlt, 16)); % Output

You should see dayRowVAlt, wakeupTimesAlt, dayTimesAlt, and averageWakeupAlt variables in your Workspace. You should also see the following output in the Command Window. Note: This example does not assume that every subject has exactly one wake-up time on the specified date.

Average wake-up time on 10/01/2009 was:  8:19 AM


EXAMPLE 6: Which subjects had unusual wake-up patterns on Oct 1?

Create a new cell in which you type and execute:

    dayCount = sum(floor(wakeTimes) == myDayNum); % How many wake-ups on the day
    noWakeups = find(dayCount < 1);   % Which subjects didn't wake-up on Oct1
    tooManyWakeups = find(dayCount > 1); % Which subjects woke up more than once on Oct 1

You should see dayCount, noWakeups and tooManyWakeups variables in your Workspace.


EXAMPLE 7: Which subjects had unusual wake-up patterns on Oct 1?

Create a new cell in which you type and execute:

    fprintf('\nSubjects with no wake-ups on %s: ', datestr(myDayNum, 23));
    fprintf('%g ', noWakeups);
    fprintf('\nSubjects with too many wake-ups on %s: ', datestr(myDayNum, 23));
    fprintf('%g ', tooManyWakeups);
    fprintf('\n');                 % End output with a new line

You should the following output in the Command Window:

Subjects with no wake-ups on 10/01/2009:  
Subjects with too many wake-ups on 10/01/2009:  


EXAMPLE 8: How many wake-up entries are in October?

Create a new cell in which you type and execute:

    [Y, M, D, H, MN, S] = datevec(wakeTimes); % Split dates into components
    octoberV = M == 10;     % Positions where wake-up dates are October
    totalOct = sum(octoberV(:));
    fprintf('\nTotal wake-up entries for October: %g\n', totalOct);

You should Y, M, D, H, MN, S, octoberV, and totalOct variables in your Workspace. You should also see the following output in the Command Window:

Total wake-up entries for October: 1872


EXAMPLE 9: Separate wake-ups into weekend and non-weekend groups

Create a new cell in which you type and execute:

    wakeupHours = (wakeTimes - floor(wakeTimes))*24; % Calculate wake-up hours
    dayNumbers = weekday(wakeTimes); % Find day numbers
    weekendV = (dayNumbers == 1) | (dayNumbers == 7);
    weekendWakeups = wakeupHours(weekendV(:));  % Pick out weekend values
    weekdayWakeups = wakeupHours(~weekendV(:)); % Pick out weekday values

You should wakeupHours, dayNumbers, dayStrings, weekendV, weekendWakeups and weekdayWakeups in your Workspace. You should also see the following output in the Command Window:


EXAMPLE 10: Are the wakeup times later on the weekends than weekdays

Create a new cell in which you type and execute:

    h = ttest2(weekendWakeups, weekdayWakeups, 0.05, 'right');
    if h == 1
       fprintf('Wake-ups are later on weekends than weekdays at the 0.05 significance level\n');
    else
       fprintf('Weekend and weekday wake-up times are not distinguishable at the 0.05 significance level\n');
    end;

You should see an h variable in your Workspace Browser and the following output in the Command Window:

Wake-ups are later on weekends than weekdays at the 0.05 significance level

EXAMPLE 11: A more formal way of reporting the results of EXAMPLE 10

Create a new cell in which you type and execute:

   fprintf(['\nNull hypothesis: Weekend and weekday wake-up times ' ...
            'can not be distinguished']);
   fprintf('\nAlt hypothesis: Wake-ups are later on weekends than weekdays\n');
   [h, p, ci] = ttest2(weekendWakeups, weekdayWakeups, 0.05, 'right');
   if h == 1
       fprintf('\t Reject null hypothesis in favor of alternative ');
   else
       fprintf('\t Cannot reject the null hypothesis ');
   end;
   fprintf('at the 0.05 significance level\n');
   fprintf('\t Hypothesis = %g\n', h);  % Truth of alternative hypothesis
   fprintf('\t Pvalue = %g\n', p); % Lower value indicates more support for alt hyp
   fprintf('\t 95%% confidence interval for difference of population means: ');
   fprintf('[%g, %g]\n', ci);

You should see an h variable in your Workspace Browser and the following output in the Command Window:

Null hypothesis: Weekend and weekday wake-up times can not be distinguished
Alt hypothesis: Wake-ups are later on weekends than weekdays
	 Reject null hypothesis in favor of alternative at the 0.05 significance level
	 Hypothesis = 1
	 Pvalue = 1.36884e-47
	 95% confidence interval for difference of population means: [1.16621, Inf]


EXAMPLE 12: Calculate the average weekend and weekday wakeup times

Create a new cell in which you type and execute:

    weekendAverages = zeros(1, numDiaries);
    weekdayAverages = zeros(1, numDiaries);
    for k = 1:numDiaries
        weekends = weekendV(:, k);
        endAverage = mean(wakeupHours(weekends, k));
        dayAverage = mean(wakeupHours(~weekends, k));
        weekendAverages(k) = endAverage;
        weekdayAverages(k) = dayAverage;
    end;

You should see weekendAverages, weekdayAverages, k, weekends, endAverage, and dayAverage variables in your Workspace Browser.



SUMMARY OF SYNTAX

MATLAB syntax Description
n = datenum(s, format) Returns a double value n containing the date number for the date represented by the string s. The value of s must be a string representing a date in the format specified by the format number format. We will not consider the more complicated forms of the datenum function.
S = datestr(N, format) Returns a vector S of strings that has the same number of entries as the array N. The entries of S are the date strings for the date numbers in the corresponding elements of the linear representation of N. The entries of S have the format specified by format number format.
[Y, M, D, H, MN, S] = datevec(N) Returns 6 different arrays of double corresponding to the different components of the corresponding date numbers in the array N. The components are year, month, day, hours, minutes, and seconds. Month 1 is January, the first of the month is day 1, hours range from 0 to 23, minutes range from 0 to 59, and seconds range from 0 to 59.
D = weekday(N) Returns an array D of day-of-the-week numbers that is the same size as the array of date numbers N. Sunday corresponds to day of the week number 1.


This lesson was written by Kay A. Robbins of the University of Texas at San Antonio and last modified on 31-Dec-2010. Please contact krobbins@cs.utsa.edu with comments or suggestions. The image is a a railway schedule that uses both 24:00 for arrival times and 0:00 of the following day for departure times. The image is available on Wikipedia as <http://en.wikipedia.org/wiki/File:Railtime.jpg>.