For some reason, Microsoft didn’t add a Week property to the DateTime class. I never could figure out why. Instead they gave us the System.Globalization namespace, filled with date related functionality like the different calendar classes. In this example, I’m going to use the GregorianCalendar class to find the week number of a certain date.

using System.Globalization;

public static int WeekNumber(DateTime date)
{
   GregorianCalendar cal = new GregorianCalendar(GregorianCalendarTypes.Localized);
   return cal.GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

As you can see, it’s not that difficult as long as you know where to look.

You can also check for the total number of weeks in a certain year. You would have to know the last day of the year, that never can be part of the first week of the following year. That day is december 28th. Here is a method that gives you the number of weeks in a specified year.

using System.Globalization;

public static int WeeksInYear(int year)
{
   GregorianCalendar cal = new GregorianCalendar(GregorianCalendarTypes.Localized);
   return cal.GetWeekOfYear(new DateTime(year, 12, 28), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

Now for the tricky part. Let’s say you want to know the number of weeks between two dates. Just pass the two dates into the above method and subtract them from each other like “WeekNumber(dateFrom) – WeekNumber(dateTo)  + 1”. Wrong! If the first date is from another year than the second one, it will not work.

In order to write a method that takes two dates and return the number of weeks in between them, you need some smart logic to make it work. Here’s is a method that I use for this purpose. It’s simple to use, but a little too complex for such a simple task, which I think should have been a part of the DateTime class to begin with.

public static int NumberOfWeeks(DateTime dateFrom, DateTime dateTo)
{
   TimeSpan Span = dateTo.Subtract(dateFrom);

   if (Span.Days <= 7)
   {
      if (dateFrom.DayOfWeek > dateTo.DayOfWeek)
      {
         return 2;
      }

      return 1;
   }

   int Days = Span.Days - 7 + (int)dateFrom.DayOfWeek;
   int WeekCount = 1;
   int DayCount = 0;

   for (WeekCount = 1; DayCount < Days; WeekCount++)
   {
      DayCount += 7;
   }

   return WeekCount;
}

As you can see from these code examples, working with weeks in C# is not that obvious.

Today, I had to implement custom performance counters in one of our applications. I haven’t worked much with performance counters before, so I wanted to check the Internet for some good articles and maybe some helper classes or wrappers around the functionality.

I found this article, which does an excellent job explaining how to go about it. But it didn’t offer any helper class or plug ‘n play wrapper, so I decided to build my own. Then I can use it the next time I have to implement performance counters in .NET.

The code is not very complicated, and I think it is pretty self explanatory. It consist of a helper class and a method that calls this helper class.

#region Using

using System;
using System.Diagnostics;

#endregion

namespace PerformanceCounters
{

/// <summary>
/// A helper class to create the specified performance counters.
/// </summary>
public class PerfmormanceMonitor
{

/// <summary>
/// Creates an instance of the class.
/// </summary>
/// <param name="categoryName">The name of the performance counter category.</param>
public PerfmormanceMonitor(string categoryName)
{
   this._Category = categoryName;
}

private CounterCreationDataCollection _Counters = new CounterCreationDataCollection();
private string _Category = string.Empty;

/// <summary>
/// Creates the performance counters
/// </summary>
public void CreateCounters()
{
   if (!PerformanceCounterCategory.Exists(_Category))
   { 
      PerformanceCounterCategory.Create(this._Category, this._Category, PerformanceCounterCategoryType.Unknown, this._Counters);
   }
}

/// <summary>
/// Add a performance counter to the category of performance counters.
/// </summary>
public void AddCounter(string name, string helpText, PerformanceCounterType type)
{
   CounterCreationData ccd = new CounterCreationData();
   ccd.CounterName = name;
   ccd.CounterHelp = helpText;
   ccd.CounterType = type;
   this._Counters.Add(ccd);
}

}
}

And here is the method that uses the helper class:

using System.Diagnostics;

static void CreatePerformanceCounter()
{
   PerfmormanceMonitor mon = new PerfmormanceMonitor("Headlight Parser");
   mon.AddCounter("# operations executed", "Total number of executed commands", PerformanceCounterType.NumberOfItems64);
   mon.AddCounter("# logfiles parsed", "Total number of logfiles parsed", PerformanceCounterType.NumberOfItems64);
   mon.AddCounter("# operations / sec", "Number of operations executed per second", PerformanceCounterType.RateOfCountsPerSecond32);
   mon.AddCounter("average time per operation", "Average duration per operation execution", PerformanceCounterType.AverageTimer32);
   mon.AddCounter("average time per operation base", "Average duration per operation execution base", PerformanceCounterType.AverageBase);
   mon.CreateCounters();
}

The functionality could be greatly expanded in the helper class, but I haven't got the time for it at the moment.