Google様から祝日リストをもらう

仕事をしていると、勤○管理表とかを後付けで書かないと行けなくなることもあるでしょう。そんなときに、たとえば、2009年8月の土日祝日を除く日付の一覧が欲しくなることが良くあります(少なくとも僕の場合)。

そんなズボラさんたちのためにC#でコードを書いてみました。
コードは手抜きなので例外が発生するとその場で死にますが、まぁ、簡易ツールなので文句は言わないと言うことで。

using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Collections.Generic;

namespace CalTest
{
  class CalTest
  {
    static void Main(string[] args)
    {
      if (args.Length < 2)
      {
        Console.WriteLine("caltest YYYY MM");
        return;
      }
      
      int y = int.Parse(args[0]);
      int m = int.Parse(args[1]);
      int days = DateTime.DaysInMonth(y, m);
      string from = string.Format("{0:D4}-{1:D2}-01", y, m);
      string to = string.Format("{0:D4}-{1:D2}-{2:D2}", y, m, days);
      
      string url = string.Format("http://www.google.com/calendar/feeds/japanese__ja%40holiday.calendar.google.com/public/full-noattendees?start-min={0}&start-max={1}", from, to);
      
      var doc = new XmlDocument();
      var nsMan = new XmlNamespaceManager(doc.NameTable);
      nsMan.AddNamespace("a", "http://www.w3.org/2005/Atom");
      nsMan.AddNamespace("gd", "http://schemas.google.com/g/2005");

      using (WebClient wc = new WebClient())
      using (Stream stream = wc.OpenRead(url))
      {
        doc.Load(stream);
      }

      var entries = doc.DocumentElement.SelectNodes("/a:feed/a:entry", nsMan);
      var holidays = new Dictionary<string, string>();
      foreach (XmlNode entry in entries)
      {
        var title = entry.SelectSingleNode("a:title", nsMan);
        var when = entry.SelectSingleNode("gd:when", nsMan);
        var date = when.Attributes["startTime"].Value;
        holidays.Add(date, title.InnerText);
      }
      
      for (int d = 1; d <= days; d++)
      {
        var day = new DateTime(y, m, d);
        if (day.DayOfWeek == DayOfWeek.Saturday
          || day.DayOfWeek == DayOfWeek.Sunday)
        {
          continue;
        }
        
        string date = string.Format("{0:D4}-{1:D2}-{2:D2}", y, m, d);
        if (holidays.ContainsKey(date))
          continue;
        
        Console.WriteLine("{0:D2}/{1:D2}", m, d);
      }
    }
  }
}