• 追加された行はこの色です。
  • 削除された行はこの色です。
#title(Googleカレンダーを使って祝日の情報を取得する)

#navi(.NETプログラミング研究)

#contents

*Googleカレンダーを使って祝日の情報を取得する [#he43d2be]

「ある年の何月何日が祝日か」を知るのは、意外と難しいです。中でも春分の日と秋分の日は計算によって予測は付きますが、確定されるのは前年なので、2年後以降の正確な日付は分かりません。よって、祝日がいつかという情報が必要ならば、祝日が決定された後で手動で入力するというのが一番確実な方法でしょう。

しかし自動的に正確な情報を取得できるのであれば、それに越したことはありません。そこで、自動で祝日を取得する方法を考えてみます。

まず考えられるのが、計算で求める方法です。前述した通り、計算と実際の祝日が絶対に同じになるとは言い切れません。しかし、違うということもほぼないでしょう。また、法律が変わって祝日が変わる可能性もあります。

祝日を計算で求める方法は、Javaであれば、「[[Java祝日計算 プロジェクト>http://sourceforge.jp/projects/jholiday/]]」があります。また、.NETのライブラリとして、すらばさんが「[[Holiday_JP>http://www002.upp.so-net.ne.jp/zsu-23/soft2/holidayjp/index.html]]」を公開されています。また、VB.NET用のクラスとして、よっし〜さんが「[[祝日判定用クラス(平成19年度祝日法改正対応)>http://www.geocities.jp/tkhr0319/program.html]]」を公開されています。

別の方法は、Webサービスを利用するというものです。調べてみると、独立行政法人農業・食品産業技術総合研究機構のサイトに「[[曜日・祝日計算サービス>http://www.finds.jp/wsdocs/calendar/index.html.ja]]」というWebサービスを見つけました。

また、Googleが提供している「[[Google Calendar APIs>http://code.google.com/apis/calendar/]]」を利用する方法もあります。ここではこちらの方法を調べていきます。

**Google Calendar Data API Version2 [#y6458953]

実はこの記事はかなり前に書いたもので、その時はGoogle Calendar Data APIのバージョン2を使っていました。今年中に公開してしまおうと思い、ふとGoogle Calendar APIのページを見てみると、バージョン2に「Deprecated」と書かれているではありませんか。調べてみると、バージョン2は3年後(2014年11月17日)には使用できなくなるというのです。そのため、この期に及んで書き直さなければならなくなりました。

しかしせっかく書いたものですので、ここでバージョン2を使って祝日を取得するコードだけを紹介させていただきます。

#code(vbnet){{
'Imports System.IO
'Imports System.Net
'Imports System.Xml

''' <summary>
''' Googleカレンダーから指定した年の祝日を取得する
''' </summary>
''' <param name="year">祝日を取得する年(西暦)。</param>
''' <param name="userId">使用するカレンダーのID。</param>
''' <returns>指定された年の祝日を表す配列。</returns>
Public Shared Function GetNationalHolidaysV2(ByVal year As Integer, _
        ByVal userId As String) As NationalHoliday()
    'URLを作成する
    Const googleUrl As String = "http://www.google.com/calendar/feeds/"
    Const visibility As String = "public"
    Const projection As String = "full-noattendees"
    Const maxResults As Integer = 100
    'クエリーを作成する
    Dim query As String = String.Format( _
        "start-min={0}-01-01&start-max={1}-01-01&max-results={2}", _
        year, year + 1, maxResults)
    'つなげて完成
    Dim url As String = _
        googleUrl & userId & "/" & visibility & "/" & projection & "?" & query

    'サーバーからデータを受信する
    Dim req As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
    Dim res As HttpWebResponse = DirectCast(req.GetResponse(), HttpWebResponse)
    Dim st As Stream = res.GetResponseStream()
    Dim sr As New StreamReader(st)
    'すべてのデータを受信する
    Dim resXml As String = sr.ReadToEnd()
    '後始末
    sr.Close()
    st.Close()
    res.Close()

    '受信したデータを解析する
    'XmlDocumentに読み込む
    Dim xmlDoc As New XmlDocument()
    xmlDoc.LoadXml(resXml)
    Dim rootElm As XmlElement = xmlDoc.DocumentElement
    '<entry>要素を探す
    Dim nsmgr As New XmlNamespaceManager(xmlDoc.NameTable)
    nsmgr.AddNamespace("ns1", "http://www.w3.org/2005/Atom")
    Dim nodeList As XmlNodeList = rootElm.SelectNodes("/ns1:feed/ns1:entry", nsmgr)
    '見つかった祝日の名前と日付を取得する
    Dim holidays As NationalHoliday() = New NationalHoliday(nodeList.Count - 1) {}
    For i As Integer = 0 To nodeList.Count - 1
        Dim entryElm As XmlNode = nodeList(i)
        Dim title As String = entryElm("title").InnerXml
        Dim startTime As String = entryElm("gd:when").GetAttribute("startTime")
        holidays(i) = New NationalHoliday(title, startTime)
    Next

    Return holidays
End Function

''' <summary>
''' Googleカレンダーから指定した年の日本の祝日を取得する
''' </summary>
''' <param name="year">祝日を取得する年(西暦)。</param>
''' <returns>指定された年の祝日を表す配列。</returns>
Public Shared Function GetNationalHolidaysV2(ByVal year As Integer) _
        As NationalHoliday()
    'mozilla.org版
    Const japaneseHolidaysId As String = _
        "outid3el0qkcrsuf89fltf7a4qbacgt9@import.calendar.google.com"
    '公式版日本語
    'const string japaneseHolidaysId =
    '    "japanese__ja@holiday.calendar.google.com";
    '公式版英語
    'const string japaneseHolidaysId =
    '    "japanese@holiday.calendar.google.com";
    Return GetNationalHolidaysV2(year, japaneseHolidaysId)
End Function

''' <summary>
''' 祝日を表現したクラス
''' </summary>
Public Class NationalHoliday
    Private _name As String
    ''' <summary>
    ''' 祝日の名前
    ''' </summary>
    Public ReadOnly Property Name() As String
        Get
            Return Me._name
        End Get
    End Property

    Private _date As DateTime
    ''' <summary>
    ''' 祝日の日付
    ''' </summary>
    Public ReadOnly Property [Date]() As DateTime
        Get
            Return Me._date
        End Get
    End Property

    ''' <summary>
    ''' NationalHolidayのコンストラクタ
    ''' </summary>
    ''' <param name="holidayName">祝日の名前</param>
    ''' <param name="holidayDate">祝日の日付(RFC3339形式の文字列)</param>
    Public Sub New(ByVal holidayName As String, ByVal holidayDate As String)
        Me._name = holidayName
        Me._date = System.Xml.XmlConvert.ToDateTime(holidayDate, _
            System.Xml.XmlDateTimeSerializationMode.Local)
        '.NET Framework 1.1以前では、次のようにする
        'Me._date = XmlConvert.ToDateTime(holidayDate)
    End Sub
End Class
}}

#code(csharp){{
//using System;
//using System.IO;
//using System.Net;
//using System.Xml;

/// <summary>
/// Googleカレンダーから指定した年の祝日を取得する
/// </summary>
/// <param name="year">祝日を取得する年(西暦)。</param>
/// <param name="userId">使用するカレンダーのID。</param>
/// <returns>指定された年の祝日を表す配列。</returns>
public static NationalHoliday[] GetNationalHolidaysV2(int year, string userId)
{
    //URLを作成する
    const string googleUrl = "http://www.google.com/calendar/feeds/";
    const string visibility = "public";
    const string projection = "full-noattendees";
    const int maxResults = 100;
    //クエリーを作成する
    string query = string.Format(
        "start-min={0}-01-01&start-max={1}-01-01&max-results={2}",
        year, year + 1, maxResults);
    //つなげて完成
    string url = googleUrl + userId + "/" + visibility + "/" + projection + "?" + query;

    //サーバーからデータを受信する
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
    HttpWebResponse res = (HttpWebResponse)req.GetResponse();
    Stream st = res.GetResponseStream();
    StreamReader sr = new StreamReader(st);
    //すべてのデータを受信する
    string resXml = sr.ReadToEnd();
    //後始末
    sr.Close();
    st.Close();
    res.Close();

    //受信したデータを解析する
    //XmlDocumentに読み込む
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(resXml);
    XmlElement rootElm = xmlDoc.DocumentElement;
    //<entry>要素を探す
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
    nsmgr.AddNamespace("ns1", "http://www.w3.org/2005/Atom");
    XmlNodeList nodeList = rootElm.SelectNodes("/ns1:feed/ns1:entry", nsmgr);
    //見つかった祝日の名前と日付を取得する
    NationalHoliday[] holidays = new NationalHoliday[nodeList.Count];
    for (int i = 0; i < nodeList.Count; i++)
    {
        XmlNode entryElm = nodeList[i];
        string title = entryElm["title"].InnerXml;
        string startTime = entryElm["gd:when"].GetAttribute("startTime");
        holidays[i] = new NationalHoliday(title, startTime);
    }

    return holidays;
}

/// <summary>
/// Googleカレンダーから指定した年の日本の祝日を取得する
/// </summary>
/// <param name="year">祝日を取得する年(西暦)。</param>
/// <returns>指定された年の祝日を表す配列。</returns>
public static NationalHoliday[] GetNationalHolidaysV2(int year)
{
    //mozilla.org版
    const string japaneseHolidaysId =
        "outid3el0qkcrsuf89fltf7a4qbacgt9@import.calendar.google.com";
    //公式版日本語
    //const string japaneseHolidaysId =
    //    "japanese__ja@holiday.calendar.google.com";
    //公式版英語
    //const string japaneseHolidaysId =
    //    "japanese@holiday.calendar.google.com";
    return GetNationalHolidaysV2(year, japaneseHolidaysId);
}

/// <summary>
/// 祝日を表現したクラス
/// </summary>
public class NationalHoliday
{
    private string _name;
    /// <summary>
    /// 祝日の名前
    /// </summary>
    public string Name
    {
        get { return this._name; }
    }

    private DateTime _date;
    /// <summary>
    /// 祝日の日付
    /// </summary>
    public DateTime Date
    {
        get { return this._date; }
    }

    /// <summary>
    /// NationalHolidayのコンストラクタ
    /// </summary>
    /// <param name="holidayName">祝日の名前</param>
    /// <param name="holidayDate">祝日の日付(RFC3339形式の文字列)</param>
    public NationalHoliday(string holidayName, string holidayDate)
    {
        this._name = holidayName;
        this._date = XmlConvert.ToDateTime(holidayDate,
            XmlDateTimeSerializationMode.Local);
        //.NET Framework 1.1以前では、次のようにする
        //this._date = XmlConvert.ToDateTime(holidayDate);
    }
}
}}

**Google Calendar Data API Version3 [#w4f1dd58]

バージョン3は2よりハードルが上がっています。最低でもAPI key(または、OAuth 2.0 token)が必要です。もし持っていなければ、「[[Google APIs Console>https://code.google.com/apis/console/#project:839406137226:access]]」で取得してください(Googleのアカウントが必要です)。

また、結果がJSONで返されます。XMLでは取得できません。JSONを解析する方法は[[.NETプログラミング研究第97号>http://wiki.dobon.net/index.php?.NET%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%B8%A6%B5%E6%2F97]]で紹介していますが、XMLのように簡単にはいきません。

難しいことは後回しにして、とりあえず試してみましょう。ウェブブラウザで

https://www.googleapis.com/calendar/v3/calendars/ja.japanese%23holiday@group.v.calendar.google.com/events?key={YOUR_API_KEY}&timeMin=2012-01-01T00:00:00Z&timeMax=2013-01-01T00:00:00Z&maxResults=100&orderBy=startTime&singleEvents=true

というURLを開いてみてください(「{YOUR_API_KEY}」の部分は、有効なAPI keyに置き換えてください)。ダウンロードしたデータを見ていただけると分かると思いますが、このようにしてJSONで2012年の日本の祝日のリストが返されます。

それでは、「https://www.googleapis.com/calendar/v3/calendars/ja.japanese%23holiday@group.v.calendar.google.com/events?key={YOUR_API_KEY}&timeMin=2012-01-01T00:00:00Z&timeMax=2013-01-01T00:00:00Z&maxResults=100&orderBy=startTime&singleEvents=true」というURLの中身を詳しく見ていきましょう。

***calendarId [#f028bd3d]

「ja.japanese%23holiday@group.v.calendar.google.com」というのは「calendarId」で、Google公式の、日本の祝日を日本語で記述したカレンダーのIDです。

先頭の「ja.」は、日本語という意味です。「en.」とすると、英語になります。

日本以外に色々な国の祝日のカレンダーが用意されています。以下に幾つか紹介します(「%23」を「#」にデコードしています)。

|国名|calendarId|h
|日本|ja.japanese#holiday@group.v.calendar.google.com|
|アメリカ|ja.usa#holiday@group.v.calendar.google.com|
|カナダ|ja.canadian#holiday@group.v.calendar.google.com|
|イギリス|ja.uk#holiday@group.v.calendar.google.com|
|フランス|ja.french#holiday@group.v.calendar.google.com|
|ドイツ|ja.german#holiday@group.v.calendar.google.com|
|イタリア|ja.italian#holiday@group.v.calendar.google.com|
|スペイン|ja.spain#holiday@group.v.calendar.google.com|
|オランダ|ja.dutch#holiday@group.v.calendar.google.com|
|ロシア|ja.russian#holiday@group.v.calendar.google.com|
|オーストラリア|ja.australian#holiday@group.v.calendar.google.com|
|中国|ja.china#holiday@group.v.calendar.google.com|
|香港|ja.hong_kong#holiday@group.v.calendar.google.com|
|台湾|ja.taiwan#holiday@group.v.calendar.google.com|
|韓国|ja.south_korea#holiday@group.v.calendar.google.com|
|インド|ja.indian#holiday@group.v.calendar.google.com|
|タイ|ja.thai#holiday@group.v.calendar.google.com|
|インドネシア|ja.indonesian#holiday@group.v.calendar.google.com|
|フィリピン|ja.philippines#holiday@group.v.calendar.google.com|
|シンガポール|ja.singapore#holiday@group.v.calendar.google.com|
|ブラジル|ja.brazilian#holiday@group.v.calendar.google.com|

「ja.japanese#holiday@group.v.calendar.google.com」で取得できる祝日の情報は間違いが多く、春分の日や秋分の日が抜けていたり、間違った日にちになっているという報告があります。そのため、非公式のmozilla.org版「outid3el0qkcrsuf89fltf7a4qbacgt9@import.calendar.google.com」の方がよく使われているようです。

***events [#a94ec703]

「events」というのは、[[calendar.events.listメソッド>http://code.google.com/apis/calendar/v3/reference.html#method_calendar_events_list]]を呼び出すという意味です。このメソッドはカレンダーのイベントのコレクションを返します。祝日はイベントとして登録されています。

***timeMinとtimeMax [#g8e6b201]

「timeMin=2012-01-01T00:00:00Z&timeMax=2013-01-01T00:00:00Z」は、2012年1月1日0時0分0秒から2013年1月1日0時0分0秒までのイベントを返してくれという意味です。timeMinの日時は期間に含まれますが、timeMaxの日時は含まれませんので、2012年の正月は含まれても、2013年の正月は含まれません。

日時はRFC3339形式で指定します。また、日にちだけ指定することはできず、時刻も指定しなければならないようです。

***maxResults [#sc6ceed4]

「max-results」には、返して欲しいエントリーの数を指定します。私が試した所では、デフォルトは(max-resultsを指定しないと)50のようです。1年の祝日を取得するにはこれで十分ですが、もっと多くのエントリーを取得したいのであれば大きな値を指定します。ただし制限があるようで、制限を超えた数字をmaxResultsに設定しても制限値分しか返さないようです。

***orderBy [#wc0947e8]

「orderBy」を指定すると、エントリーを並び替えた状態で返してくれます。orderByに指定できる値は「startTime」と「updated」のどちらかで、「startTime」を指定すると「start date」(祝日の日にち)を昇順で並び替えてくれます。

***singleEvents [#sa25fae1]

「singleEvents」は繰り返しのイベントを展開するかを指定するものらしいですが、「orderBy」を指定した時は「singleEvents=true」としないとエラーになるようです。

***サンプルコード [#cd84b15c]

以上を踏まえて、Googleカレンダーから祝日の情報(名前と日付)を取得するサンプルコードを書いてみました。JSONの解析にはJavaScriptSerializerを使っていますので、.NET Framework 3.5以降で、System.Web.Extensionsを参照設定する必要があります。JSONの解析については、[[.NETプログラミング研究第97号>http://wiki.dobon.net/index.php?.NET%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%B8%A6%B5%E6%2F97]]で説明していますので、そちらをご覧ください。

また、「{YOUR_API_KEY}」は有効なAPI keyに書き換えてください。

#code(vbnet){{
Imports System.IO
Imports System.Net
Imports System.Xml
Imports System.Collections.Generic

Class Module1
    Shared Sub Main()
        '2012年の日本の祝日を取得する
        Dim holidays As NationalHoliday() = GetNationalHolidays(2012, _
            "{YOUR_API_KEY}")
        '結果を表示する
        For Each holiday As NationalHoliday In holidays
            Console.WriteLine("Name: {0}", holiday.Name)
            Console.WriteLine("Date: {0}", holiday.Date)
        Next

        Console.ReadLine()
    End Sub
    
    ''' <summary>
    ''' Googleカレンダーから指定した年の祝日を取得する
    ''' </summary>
    ''' <param name="year">祝日を取得する年(西暦)。</param>
    ''' <param name="apiKey">Google API key。</param>
    ''' <param name="calendarId">使用するカレンダーのID。</param>
    ''' <returns>指定された年の祝日を表す配列。</returns>
    Public Shared Function GetNationalHolidays(ByVal year As Integer, _
            ByVal apiKey As String, ByVal calendarId As String) As NationalHoliday()
        'URLを作成する
        Const googleUrl As String = "https://www.googleapis.com/calendar/v3/calendars/"
        Const methodString As String = "events"
        Const maxResults As Integer = 100
        'クエリーを作成する
        Dim query As String = String.Format("key={0}&" & _
            "timeMin={1}-01-01T00:00:00Z&" & _
            "timeMax={2}-01-01T00:00:00Z&" & _
            "maxResults={3}", _
            apiKey, year, year + 1, maxResults)
        'つなげて完成
        Dim url As String = googleUrl & calendarId & "/" & methodString & "?" & query

        'サーバーからデータを受信する
        Dim req As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
        Dim res As HttpWebResponse = DirectCast(req.GetResponse(), HttpWebResponse)
        Dim st As Stream = res.GetResponseStream()
        Dim sr As New StreamReader(st)
        'すべてのデータを受信する
        Dim jsonString As String = sr.ReadToEnd()
        '後始末
        sr.Close()
        st.Close()
        res.Close()

        '受信したデータを解析する
        Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer()
        Dim jsonDic As Dictionary(Of String, Object) = _
            serializer.Deserialize(Of Dictionary(Of String, Object))(jsonString)
        If Not jsonDic.ContainsKey("items") Then
            'itemsがなかったら失敗したと判断する
            Return New NationalHoliday(-1) {}
        End If
        Dim items As System.Collections.ArrayList = _
            DirectCast(jsonDic("items"), System.Collections.ArrayList)
        '見つかった祝日の名前と日付を取得する
        Dim holidays As NationalHoliday() = New NationalHoliday(items.Count - 1) {}
        For i As Integer = 0 To items.Count - 1
            Dim item As Dictionary(Of String, Object) = _
                DirectCast(items(i), Dictionary(Of String, Object))
            Dim title As String = DirectCast(item("summary"), String)
            Dim startTime As String = DirectCast(DirectCast(item("start"),  _
                    Dictionary(Of String, Object))("date"), String)
            holidays(i) = New NationalHoliday(title, startTime)
        Next

        Return holidays
    End Function

    ''' <summary>
    ''' Googleカレンダーから指定した年の日本の祝日を取得する
    ''' </summary>
    ''' <param name="year">祝日を取得する年(西暦)。</param>
    ''' <param name="apiKey">使用するカレンダーのID。</param>
    ''' <returns>指定された年の祝日を表す配列。</returns>
    Public Shared Function GetNationalHolidays(ByVal year As Integer, _
            ByVal apiKey As String) As NationalHoliday()
        'mozilla.org版
        Const japaneseHolidaysId As String = _
            "outid3el0qkcrsuf89fltf7a4qbacgt9@import.calendar.google.com"
        '公式版日本語
        'Const japaneseHolidaysId As String = _
        '    "ja.japanese%23holiday@group.v.calendar.google.com"
        Return GetNationalHolidays(year, apiKey, japaneseHolidaysId)
    End Function

    ''' <summary>
    ''' 祝日を表現したクラス
    ''' </summary>
    Public Class NationalHoliday
        Private _name As String
        ''' <summary>
        ''' 祝日の名前
        ''' </summary>
        Public ReadOnly Property Name() As String
            Get
                Return Me._name
            End Get
        End Property

        Private _date As DateTime
        ''' <summary>
        ''' 祝日の日付
        ''' </summary>
        Public ReadOnly Property [Date]() As DateTime
            Get
                Return Me._date
            End Get
        End Property

        ''' <summary>
        ''' NationalHolidayのコンストラクタ
        ''' </summary>
        ''' <param name="holidayName">祝日の名前</param>
        ''' <param name="holidayDate">祝日の日付(RFC3339形式の文字列)</param>
        Public Sub New(ByVal holidayName As String, ByVal holidayDate As String)
            Me._name = holidayName
            Me._date = XmlConvert.ToDateTime(holidayDate, _
                XmlDateTimeSerializationMode.Local)
            '.NET Framework 1.1以前では、次のようにする
            'Me._date = XmlConvert.ToDateTime(holidayDate)
        End Sub
    End Class
End Class
}}

#code(csharp){{
using System;
using System.IO;
using System.Net;
using System.Xml;
using System.Collections.Generic;

public class Program
{
    static void Main(string[] args)
    {
        //2012年の日本の祝日を取得する
        NationalHoliday[] holidays = GetNationalHolidays(
            2012, "{YOUR_API_KEY}");
        //結果を表示する
        foreach (NationalHoliday holiday in holidays)
        {
            Console.WriteLine("Name: {0}", holiday.Name);
            Console.WriteLine("Date: {0}", holiday.Date);
        }
    }

    /// <summary>
    /// Googleカレンダーから指定した年の祝日を取得する
    /// </summary>
    /// <param name="year">祝日を取得する年(西暦)。</param>
    /// <param name="apiKey">Google API key。</param>
    /// <param name="calendarId">使用するカレンダーのID。</param>
    /// <returns>指定された年の祝日を表す配列。</returns>
    public static NationalHoliday[] GetNationalHolidays(int year,
        string apiKey, string calendarId)
    {
        //URLを作成する
        const string googleUrl = "https://www.googleapis.com/calendar/v3/calendars/";
        const string methodString = "events";
        const int maxResults = 100;
        //クエリーを作成する
        string query = string.Format(
            "key={0}&" +
            "timeMin={1}-01-01T00:00:00Z&" + 
            "timeMax={2}-01-01T00:00:00Z&" +
            "maxResults={3}",
            apiKey, year, year + 1, maxResults);
        //つなげて完成
        string url = googleUrl + calendarId + "/" + methodString + "?" + query;

        //サーバーからデータを受信する
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
        HttpWebResponse res = (HttpWebResponse)req.GetResponse();
        Stream st = res.GetResponseStream();
        StreamReader sr = new StreamReader(st);
        //すべてのデータを受信する
        string jsonString = sr.ReadToEnd();
        //後始末
        sr.Close();
        st.Close();
        res.Close();

        //受信したデータを解析する
        System.Web.Script.Serialization.JavaScriptSerializer serializer =
            new System.Web.Script.Serialization.JavaScriptSerializer();
        Dictionary<string, object> jsonDic =
            serializer.Deserialize<Dictionary<string, object>>(jsonString);
        if (!jsonDic.ContainsKey("items"))
        {
            //itemsがなかったら失敗したと判断する
            return new NationalHoliday[0];
        }
        System.Collections.ArrayList items =
            (System.Collections.ArrayList)jsonDic["items"];
        //見つかった祝日の名前と日付を取得する
        NationalHoliday[] holidays = new NationalHoliday[items.Count];
        for (int i = 0; i < items.Count; i++)
        {
            Dictionary<string, object> item = (Dictionary<string, object>)items[i];
            string title = (string)item["summary"];
            string startTime =
                (string)((Dictionary<string, object>)item["start"])["date"];
            holidays[i] = new NationalHoliday(title, startTime);
        }

        return holidays;
    }

    /// <summary>
    /// Googleカレンダーから指定した年の日本の祝日を取得する
    /// </summary>
    /// <param name="year">祝日を取得する年(西暦)。/param>
    /// <param name="apiKey">使用するカレンダーのID。</param>
    /// <returns>指定された年の祝日を表す配列。</returns>
    public static NationalHoliday[] GetNationalHolidays(int year, string apiKey)
    {
        //mozilla.org版
        const string japaneseHolidaysId =
            "outid3el0qkcrsuf89fltf7a4qbacgt9@import.calendar.google.com";
        //公式版日本語
        //const string japaneseHolidaysId =
        //    "ja.japanese%23holiday@group.v.calendar.google.com";
        return GetNationalHolidays(year, apiKey, japaneseHolidaysId);
    }

    /// <summary>
    /// 祝日を表現したクラス
    /// </summary>
    public class NationalHoliday
    {
        private string _name;
        /// <summary>
        /// 祝日の名前
        /// </summary>
        public string Name
        {
            get { return this._name; }
        }

        private DateTime _date;
        /// <summary>
        /// 祝日の日付
        /// </summary>
        public DateTime Date
        {
            get { return this._date; }
        }

        /// <summary>
        /// NationalHolidayのコンストラクタ
        /// </summary>
        /// <param name="holidayName">祝日の名前</param>
        /// <param name="holidayDate">祝日の日付(RFC3339形式の文字列)</param>
        public NationalHoliday(string holidayName, string holidayDate)
        {
            this._name = holidayName;
            this._date = XmlConvert.ToDateTime(holidayDate,
                XmlDateTimeSerializationMode.Local);
            //.NET Framework 1.1以前では、次のようにする
            //this._date = XmlConvert.ToDateTime(holidayDate);
        }
    }
}
}}

出力結果は以下のようになります。

#pre{{
Name: 振替休日 / Furikae ky?jitsu / Substitute Holiday
Date: 2012/01/02 0:00:00
Name: 海の日 / Umi no hi / Marine Day
Date: 2007/07/16 0:00:00
Name: 成人の日 / Seijin no hi / Coming-of-age Day
Date: 2007/01/08 0:00:00
Name: 敬老の日 / Keir? no hi / Respect for the Aged Day
Date: 2007/09/17 0:00:00
Name: 振替休日 / Furikae ky?jitsu / Substitute Holiday
Date: 2012/12/24 0:00:00
Name: 体育の日 / Taiiku no hi / Health-Sports Day
Date: 2007/10/08 0:00:00
Name: 振替休日 / Furikae ky?jitsu / Substitute Holiday
Date: 2012/04/30 0:00:00
Name: 天皇誕生日 / Tenn? tanj?bi / Emperor Akihito's Birthday
Date: 2007/12/23 0:00:00
Name: 元日 / Ganjitsu / New Year's Day
Date: 2007/01/01 0:00:00
Name: 勤労感謝の日 / Kinr? kansha no hi / Labour Thanksgiving Day
Date: 2007/11/23 0:00:00
Name: 春分の日 / Shunbun no hi / Vernal Equinox Day
Date: 2008/03/20 0:00:00
Name: 憲法記念日 / Kenp? kinenbi / Constitution Memorial Day *
Date: 2007/05/03 0:00:00
Name: 秋分の日 / Sh?bun no hi / Autumnal Equinox Day
Date: 2012/09/22 0:00:00
Name: 昭和の日 / Sh?wa no hi / Sh?wa Day *
Date: 2007/04/29 0:00:00
Name: 文化の日 / Bunka no hi / Culture Day
Date: 2007/11/03 0:00:00
Name: 建国記念の日 / Kenkoku kinen no hi / National Foundation Day
Date: 2007/02/11 0:00:00
Name: 子供の日 / Kodomo no hi / Children's Day
Date: 2007/05/05 0:00:00
Name: みどりの日 / Midori no hi / Greenery Day *
Date: 2007/05/04 0:00:00
}}

**最後に [#h011aa1d]

年末の忙しい時に取り急ぎ書きなおしたため、もしかしたら不備があるかもしれません(多分あるでしょう)。もしありましたら、申し訳ないです。

最後になりましたが、皆様良いお年をお迎えください。

**コメント [#ad61196d]
#comment

//これより下は編集しないでください
#pageinfo([[:Category/.NET]] [[:Category/ASP.NET]],2011-12-30 (金) 02:04:44,DOBON!,2011-12-30 (金) 02:04:44,DOBON!)

[ トップ ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]