Click here to Skip to main content
Click here to Skip to main content
Go to top

Format Specifier to Get Quarter Value of a Date

, 9 Apr 2013
Rate this:
Please Sign up or sign in to vote.
Extension method that defines a format specifier q or Q and finds the Quarter for a DateTime value

Introduction

This tip describes adding an extension method to DateTime data-type that accepts a format specifier q or Q to return the Quarter for a DateTime value. Additionally, there is a provision to specify the month of the first quarter. The usage is demonstrated with NUnit unit-tests.

Background

The C# DateTime data type doesn't have a pre-defined method or format specifier to get the quarter value for a particular date. One way to build support would be to create an extension method to get the quarter value but it would be nice to have a new format specifier for use with string.Format() and ToString() that can return the quarter value similar to other specifiers like day, month, year, etc. Unfortunately, defining a customer formatter will limit the usage with only string.Format() as ToString() doesn't seem to support a custom formatter (although it does have an overload just for that). So here an extension method is created that builds support for new specifier q or Q and returns the Quarter value for a DateTime value. Additionally, there is support for specifying the month of first quarter, for example for an Apr to Mar cycle, the first quarter will be month 4.

Extension Method

An extension method ToStringEx() is defined on DateTime. Quarter value is returned for the specifiers q; any other specifiers are passed on to the default ToString() method. Some additional code takes care of the provision to specify the starting quarter month.

public static string ToStringEx(this DateTime input, string format)
{
	string dateString = string.Empty;

	string firstFormatChar = format.Substring(0, 1);

	switch (firstFormatChar)
	{
		case "q":
		case "Q":
			string remainingFormatChar = format.Substring(1);

			int firstQuarterMonth = 1;

			if (remainingFormatChar.Length > 0)
			{
				firstQuarterMonth = int.Parse(remainingFormatChar);
				if (firstQuarterMonth < 1 || firstQuarterMonth > 12)
					throw new FormatException
					("Expecting number between 1 & 12!");
			}

			//shift the reference to the starting of first quarter
			int monthNo = input.Month - firstQuarterMonth + 1; 
			if (monthNo <= 0)
				monthNo += 12; //adding 12 when we are crossing the year

			//forcing 'double' input and type casting the return value
			int quarter = (int)Math.Ceiling(monthNo / 3.0); 
			dateString = quarter.ToString();

			break;

		default:
			dateString = input.ToString
				(format, System.Globalization.CultureInfo.InvariantCulture);
			break;
	}
	return dateString;
}  

Using the Code

The extension method ToStringEx() becomes available on all DateTime values and when invoked with a format specifier q or Q shall return the appropriate quarter value. Demonstrating the usage here with a unit test:

[Test]
public void DatetimeExtensionTest()
{
	//default case when Jan is the month of first quarter
	//Jan is the first quarter by default
	Assert.AreEqual("1", (new DateTime(2013, 1, 1)).ToStringEx("q")); 
	//Jul is expected in 3rd quarter
	Assert.AreEqual("3", (new DateTime(2013, 7, 1)).ToStringEx("q")); 

	//Considering Oct as the start of first quarter
	//Jan is the 2nd quarter
	Assert.AreEqual("2", (new DateTime(2013, 1, 1)).ToStringEx("q10")); 
	//Jul is the 4th quarter
	Assert.AreEqual("4", (new DateTime(2013, 7, 1)).ToStringEx("q10")); 
}

Points of Interest

By default, the q specifier assumes Jan as the starting of the first quarter, the extension method allows passing a number from 1 to 12 to specify the starting month of first quarter - some calculation shifts the reference to the starting of the first quarter. The attached source code has more unit-tests which test for all dates in the four quarters in a year.

History

  • 8th April, 2013: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

No Biography provided

Comments and Discussions

 
SuggestionAn alternative suggestion. PinmemberGeorge Swan9-Apr-13 9:34 
AnswerRe: An alternative suggestion. [modified] Pinmemberdotted_decimal9-Apr-13 19:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 9 Apr 2013
Article Copyright 2013 by dotted_decimal
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid