Click here to Skip to main content
15,886,788 members
Articles / Programming Languages / C#
Tip/Trick

Computing the Date of the Last Day of a Reporting Week

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
17 Nov 2017BSD3 min read 6.2K   48  
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


Written By
Software Developer (Senior)
United States United States
I deliver robust, clean, adaptable, future-ready applications that are properly documented for users and maintainers. I have deep knowledge in multiple technologies and broad familiarity with computer and software technologies of yesterday, today, and tomorrow.

While it isn't perceived as sexy, my focus has always been the back end of the application stack, where data arrives from a multitude of sources, and is converted into reports that express my interpretation of The Fundamental Principle of Tabular Reporting, and are the most visible aspect of the system to senior executives who approve the projects and sign the checks.

While I can design a front end, I prefer to work at the back end, getting data into the system from outside sources, such as other computers, electronic sensors, and so forth, and getting it out of the system, as reports to IDENTIFY and SOLVE problems.

When presented with a problem, I focus on identifying and solving the root problem for the long term.

Specialties: Design: Relational data base design, focusing on reporting; organization and presentation of large document collections such as MSDS libraries

Development: Powerful, imaginative utility programs and scripts for automated systems management and maintenance

Industries: Property management, Employee Health and Safety, Services

Languages: C#, C++, C, Python, VBA, Visual Basic, Perl, WinBatch, SQL, XML, HTML, Javascript

Outside Interests: Great music (mostly, but by no means limited to, classical), viewing and photographing sunsets and clouds, traveling by car on small country roads, attending museum exhibits (fine art, history, science, technology), long walks, especially where there is little or no motor traffic, reading, especially nonfiction and thoughtfully written, thought provoking science fiction

Comments and Discussions

 
-- There are no messages in this forum --