Jacob Carpenter’s Weblog

April 16, 2008

PC#1: A solution

Filed under: challenge, csharp, extension methods, LINQ — Jacob @ 12:21 pm

So, when I initially posed the programming challenge #1 I stated:

… since I intended to output HTML, ASP.NET seemed a logical choice. But I was amazed at the amount of code required for such a seemingly simple task (not to mention how ugly code containing <% and %> is!).

Well, it turns out, using plain old C# with a little LINQ to XML functional construction made my solution a lot nicer.

Prerequisites

I created a few DateTimeExtensions to enhance readability, though I could have easily inlined the implementation of each of those methods without any LOC impact.

public static class DateTimeExtensions
{
    public static DateTime ToFirstDayOfMonth(this DateTime dt)
    {
        return new DateTime(dt.Year, dt.Month, 1);
    }
    public static DateTime ToLastDayOfMonth(this DateTime dt)
    {
        return new DateTime(dt.Year, dt.Month, DateTime.DaysInMonth(dt.Year, dt.Month));
    }
    public static DateTime ToFirstDayOfWeek(this DateTime dt)
    {
        return dt.AddDays(-((int) dt.DayOfWeek));
    }
    public static DateTime ToLastDayOfWeek(this DateTime dt)
    {
        return dt.AddDays(6 - ((int) dt.DayOfWeek));
    }
}

I also relied on the Slice extension method I’ve previously blogged about.

Solution

static void Main(string[] args)
{
    DateTime today = DateTime.Today;
    DateTime firstDayOfMonth = today.ToFirstDayOfMonth();
    DateTime startCalendar = firstDayOfMonth.ToFirstDayOfWeek();
    DateTime lastDayOfMonth = today.ToLastDayOfMonth();
    DateTime endCalendar = lastDayOfMonth.ToLastDayOfWeek();

    var calendarPrefix =
        from day in Enumerable.Range(startCalendar.Day, (firstDayOfMonth - startCalendar).Days)
        select new XElement("td", new XAttribute("class", "prevMonth"), day);
    var calendarMonth =
        from day in Enumerable.Range(1, lastDayOfMonth.Day)
        select new XElement("td", day == today.Day ? new XAttribute("class", "today") : null, day);
    var calendarSuffix =
        from day in Enumerable.Range(1, (endCalendar - lastDayOfMonth).Days)
        select new XElement("td", new XAttribute("class", "nextMonth"), day);

    var calendar = calendarPrefix.Concat(calendarMonth).Concat(calendarSuffix);

    var table = new XElement("table",
        new XElement("thead",
            new XElement("tr",
                from offset in Enumerable.Range(0, 7)
                select new XElement("th", startCalendar.AddDays(offset).ToString("ddd")))),
        new XElement("tbody",
            from week in calendar.Slice(7)
            select new XElement("tr", week)));

    Console.WriteLine(table);
}

I’d love to see more ways to solve this. If you’ve got a simpler or more beautiful implementation in your favorite programming langauge/web application framework, let me know in the comments of the original post.

About these ads

2 Comments »

  1. Very elegant.

    Comment by Will Asrari — April 16, 2008 @ 12:39 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: