Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Computing the Date of the Last Day of a Reporting Week

5.00/5 (1 vote)
17 Nov 2017BSD3 min read 6.3K   49  
Calculating the day on which a reporting period that ends on a specific day of the week is not as easy as it looks.

Introduction

The static C# method around which this article revolves came into being as part of a bare bones professional services billing application that I just put into production in my one-person consulting practice. I wanted the invoice to report the date on which the weekly reporting period that it covers ended.

Background

I had little trouble finding a simple, straightforward algorithm to compute the date of the last or next Sunday, such as "Find Week Ending Date of Last Completed Week," at this link.

Adapting this algorithm to support reporting periods that end on an arbitrary weekday (e. g., Friday or Saturday, both common in the US), not to mention periods that cut off earlier in the week, such as Wednesday (common in commercial construction and other industries) was not as simple as it first seemed. Nevertheless, I devised a fairly straightforward algorithm, and did my best to document it in plain English.

Using the Code

The sample program that I included with this article is a dedicated unit test for WeekEndAsOfDate, the static method, implemented in C#, that implements the algorithm.

Since it uses a loop that iterates over a set of integers, the unit test implements the call as follows:

C#
DateTime dtmResult = WeekEndAsOfDate (
    dtmDateWorked ,
    ( DayOfWeek ) intWeekdayNumber );

A more normal implementation would substitute an actual member of the DayOfWeek enumeration as the second argument, as I did here in the production program for which I created and tested it.

C#
DateTime dtmWeekEndedAsOfDate = WeekEndAsOfDate (
    Convert.ToDateTime (
    drFwdOnlyReadOnly [ "dtmEndDate" ] ) ,  // DateTime  pdtmLastDayWorked 
    DayOfWeek.Sunday );                     // DayOfWeek penmDayOfWeekAsOf

In the above example, note the use of Convert.ToDateTime to cast the generic object returned by the drFwdOnlyReadOnly object, which is a SqlDataReader.

Points of Interest

The statement that immediately follows the WeekEndAsOfDate call that computes the reporting period ending date is interesting for a couple of reasons.

C#
Console.WriteLine (
    "Work date {0,-9}, {1}, reporting week ends = {2,-9}, {3}" ,
    dtmDateWorked.DayOfWeek ,               // Format Item 0: For work date {0,-9}, {1}
    dtmDateWorked.ToString ( SHORT_DATE ) , // Format Item 1: For work date {0,-9}, {1}
    ( DayOfWeek ) intWeekdayNumber ,        // Format Item 2: reporting week ends = {2,-9}, {3}
    dtmResult.ToString ( SHORT_DATE ) );    // Format Item 3: reporting week ends = {2,-9}, {3}
  1. The first and third format items (index 0 and index 2) are composite format items that display the weekday name left aligned and padded on the right to a total width of 9, the number of characters required to spell the longest weekday, Wednesday.
  2. Each item goes on its own line, with a line comment that shows where it appears in the format control string. The more items there are in the array of output items, the more useful these comments become. Though they are a little harder to maintain when the format is read from a string resource, they become invaluable writing and debugging aids then.

The last section of the main program is also interesting for two reasons:

C#
Console.WriteLine (
    "WeekEndAsOfDate tests done!{0}{0}Press the ENTER (Return) key to exit the program." ,
    Environment.NewLine );
Console.Beep ( 440 , 250 );
Console.ReadLine ( );
Environment.Exit ( ERROR_SUCCESS );
  1. This simple mechanism requires the operator to press the Return key to dismiss the program. This technique is an implementation of the mechanism that I've used for almost three decades to suspend execution of batch files with something a little more robust than the internal pause command, which accepts any key, making accidental premature dismissals, accompanied by total loss of the information displayed, all too common.
  2. Its presence in this character mode program that takes no command line arguments enables the program to be started from the file explorer, while allowing you to use the tools in the system menu to copy the output into the Windows clipboard. This is how I captured the output shown in the single worksheet in EndWeekAnyWeekdayUnit_Test_Report_Worksheets.xlsx, which is included in the archive.

The unit test in the main routine and the function are amply documented.

Though the code in the package targets version 4.5 of the Microsoft .NET Framework, since the program uses only core parts of the framework, it can be adapted to target any version of the framework. The production billing program targets the 64 bit framework (4.5) running on Windows 7 Professional.

History

  • Saturday, 18th November 2017: Initial version

License

This article, along with any associated source code and files, is licensed under The BSD License