5.27.1 Problem
You want to compute the date for some weekday of some other week.
5.27.2 Solution
Figure out the date for that weekday in the current week, then shift the result into the desired week.
5.27.3 Discussion
Calculating the date for a day of the week in some other week is a problem that breaks down into a day-within-week shift (using the formula given in the previous section) plus a week shift. These operations can be done in either order because the amount of shift within the week is the same whether or not you shift the reference date into a different week first. For example, to calculate Wednesday of a week by the preceding formula, n is 4. To compute the date for Wednesday two weeks ago, you can perform the day-within-week shift first, like this:
mysql> SET @target = -> DATE_SUB(DATE_ADD(CURDATE( ),INTERVAL 4-DAYOFWEEK(CURDATE( )) DAY), -> INTERVAL 14 DAY); mysql> SELECT CURDATE( ), @target, DAYNAME(@target); +------------+------------+------------------+ | CURDATE( ) | @target | DAYNAME(@target) | +------------+------------+------------------+ | 2002-07-15 | 2002-07-03 | Wednesday | +------------+------------+------------------+
Or you can perform the week shift first:
mysql> SET @target = -> DATE_ADD(DATE_SUB(CURDATE( ),INTERVAL 14 DAY), -> INTERVAL 4-DAYOFWEEK(CURDATE( )) DAY); mysql> SELECT CURDATE( ), @target, DAYNAME(@target); +------------+------------+------------------+ | CURDATE( ) | @target | DAYNAME(@target) | +------------+------------+------------------+ | 2002-07-15 | 2002-07-03 | Wednesday | +------------+------------+------------------+
Some applications need to determine dates such as the n-th instance of particular weekdays. For example, if you administer a payroll where paydays are the 2nd and 4th Thursdays of each month, you'd need to know what those dates are. One way to do this for any given month is to begin with the first-of-month date and shift it forward. It's easy enough to shift the date to the Thursday in that week; the trick is to figure out how many weeks forward to shift the result to reach the 2nd and 4th Thursdays. If the first of the month occurs on any day from Sunday through Thursday, you shift forward one week to reach the 2nd Thursday. If the first of the month occurs on Friday or later, you shift forward by two weeks. The 4th Thursday is of course two weeks after that.
The following Perl code implements this logic to find all paydays in the year 2002. It runs a loop that constructs the first-of-month date for the months of the year. For each month, it issues a query that determines the dates of the 2nd and 4th Thursdays:
my $year = 2002; print "MM/CCYY 2nd Thursday 4th Thursday "; foreach my $month (1..12) { my $first = sprintf ("%04d-%02d-01", $year, $month); my ($thu2, $thu4) = $dbh->selectrow_array (qq{ SELECT DATE_ADD( DATE_ADD(?,INTERVAL 5-DAYOFWEEK(?) DAY), INTERVAL IF(DAYOFWEEK(?) <= 5, 7, 14) DAY), DATE_ADD( DATE_ADD(?,INTERVAL 5-DAYOFWEEK(?) DAY), INTERVAL IF(DAYOFWEEK(?) <= 5, 21, 28) DAY) }, undef, $first, $first, $first, $first, $first, $first); printf "%02d/%04d %s %s ", $month, $year, $thu2, $thu4; }
The output from the program looks like this:
MM/CCYY 2nd Thursday 4th Thursday 01/2002 2002-01-10 2002-01-24 02/2002 2002-02-14 2002-02-28 03/2002 2002-03-14 2002-03-28 04/2002 2002-04-11 2002-04-25 05/2002 2002-05-09 2002-05-23 06/2002 2002-06-13 2002-06-27 07/2002 2002-07-11 2002-07-25 08/2002 2002-08-08 2002-08-22 09/2002 2002-09-12 2002-09-26 10/2002 2002-10-10 2002-10-24 11/2002 2002-11-14 2002-11-28 12/2002 2002-12-12 2002-12-26
Using the mysql Client Program
Writing MySQL-Based Programs
Record Selection Techniques
Working with Strings
Working with Dates and Times
Sorting Query Results
Generating Summaries
Modifying Tables with ALTER TABLE
Obtaining and Using Metadata
Importing and Exporting Data
Generating and Using Sequences
Using Multiple Tables
Statistical Techniques
Handling Duplicates
Performing Transactions
Introduction to MySQL on the Web
Incorporating Query Resultsinto Web Pages
Processing Web Input with MySQL
Using MySQL-Based Web Session Management
Appendix A. Obtaining MySQL Software
Appendix B. JSP and Tomcat Primer
Appendix C. References