スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: スポンサー広告

m番目のn曜日

仕事でサマータイムについて考える事があった。
夏時間
ある日ある時間を境に、1時間進んでみたり戻ってみたりするという奴だ。
ヨーロッパの実施時間をWikiから引用すると

3月最終日曜日午前1時〜10月最終日曜日午前1時(UTC基準)

となっている。この「最終日曜日」というの具体性(明確な日付)のない規定がプログラミングでは曲者だった。
C#のDateTimeは通常、各現地のローカル時間を扱う。サマータイムを実施していない日本ではなーんの考慮も要らないんだけど、実施している地域が絡むとめんどくさい話になる。サマータイムを使った計算云々は、仕事上やむを得ず実装した特殊なケースなので載せることもないんだけど、「m番目のn曜日」を日付に変えるという処理は、共通的に使えそうなので実装したコードをメモっておく。
using System;

namespace TawamureDays {

public static class Utils {

/// <summary>
/// 指定日付が属する月の、[weekNumber]番目の曜日(weekDay)
/// に当たる日付を取得します。<br/>
/// 指定日付から、数えて…というわけではありません。<br/>
/// </summary>
/// <param name="date">指定日付</param>
/// <param name="weekNumber">指定週(大体1~5)</param>
/// <param name="weekDay">曜日</param>
/// <returns>[weekNumber]番目の曜日(weekDay)に当たる日付]
///(時分秒は、dateのものを引き継ぎます)</returns>
public static DateTime GetDateByWeekNumber(this DateTime date,
int weekNumber, DayOfWeek weekDay) {

//月の月初日と月末日
var firstDay = date.FirstDayOfMonth();
var lastDay = date.LastDayOfMonth();
//0番目ってのはないよ?
var week = Math.Max(1, weekNumber);
var day = 0;

do {
//日付の計算(日曜=0, 土曜=6の時の計算式)
//月初日の曜日と、引数の曜日の大小関係で計算方法が変わります。
//日付が末日を超える限り計算を続けます。
if (weekDay >= firstDay.DayOfWeek) {
day = 7 * (week - 1) +
((int)weekDay - (int)firstDay.DayOfWeek) + 1;

} else {
day = 7 * week + ((int)weekDay - (int)firstDay.DayOfWeek) + 1;
}

week --;

} while (day > lastDay.Day);

return new DateTime(firstDay.Year, firstDay.Month, day,
date.Hour, date.Minute, date.Second);
}
}
}

FirstDayOfMonthメソッドとLastDayOfMonthメソッドも載せておく。
/// <summary>
/// 指定された日付の月初日を取得します<br/>
/// </summary>
/// <param name="date">日付</param>
/// <returns>月初日</returns>
public static DateTime FirstDayOfMonth(this DateTime date) {
return new DateTime(date.Year, date.Month, 1);
}

/// <summary>
/// 指定された日付の月末日を取得します<br/>
/// </summary>
/// <param name="date">日付</param>
/// <returns>月末日</returns>
public static DateTime LastDayOfMonth(this DateTime date) {
return date.FirstDayOfMonth().AddMonths(1).AddDays(-1);
}
見ればわかるので説明は省略。
使い方はこんな感じ。

//最後の日曜日を取得しよう。
var lastSunday = DateTime.Today.GetDateByWeekNumber(5, DayOfWeek.Sunday);
これを書いた2013年3月なら、lastSundayは「2013/03/31」となる。

//最初の日曜日を取得しよう。
var firstSunday = DateTime.Today.GetDateByWeekNumber(1, DayOfWeek.Sunday);
これを書いた2013年3月なら、lastSundayは「2013/03/3」となる。
「第3日曜からxxxxする」とか、「第1,3月曜はxxxxしない。」という条件があるときには使えるかな。
(追記)
Windows7以降であれば、サマータイムの有無はOSからも確認できる。
日本
20130326_1
ドイツ周辺
20130326_2
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: C# | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。