日時文字列をDateTimeに変換する(C#)

日時の表記方法には様々なものがあります。
そのうち、以下のような表記をDateTimeに変換する処理です。

■使い方
DateTime dt;

StringToDateTime("   2016-04-08T12:34:56+09:00  ", out dt);		//日時オフセットが9時間。前後に空白
StringToDateTime("2016-04-08T01:34:56-02:00  ", out dt);		//日時オフセットがマイナス2時間。後ろに空白
StringToDateTime("2016-04-08T03:34:56Z", out dt);				//UTC表記の日時
StringToDateTime("2016:04:08 12:34", out dt);					//秒なし。日時区切りが「:」
StringToDateTime("2016/4/8 12:34", out dt);						//日時が1桁
StringToDateTime("2016/4/08(金)12:34:56", out dt);			//日本語表記。カッコで曜日がある
StringToDateTime("2016年04月08日", out dt);						//日付のみ
StringToDateTime("2016年04月08日(金)", out dt);
StringToDateTime("2016年04月08日(金)12時34分56秒", out dt);	//日付と時刻。全部日本語
StringToDateTime("2016年04月08日12:34:56", out dt);				//日付と時刻の間に空白なし
StringToDateTime("2016年04月08日 12:34:56", out dt);			//日付と時刻の間に空白あり
StringToDateTime("2016年04月08日 12:34", out dt);
■ソースコード
		/// <summary>
		/// 「yyyy/mm/dd」「yyyymmdd」「yyyy/mm/dd hh:mm」「yyyy/mm/dd hh:mm:ss」をDateTimeにする
		/// 
		///「2016-04-07T19:01:01+09:00」の形式対応(時差がプラス9時間でなければそれに合わせて変換後返す)
		///「2016-04-07T10:00:44Z」(UTC日時)の形式対応(プラス9時間して返す)
		/// 
		/// yyyymmddの区切りは「年月日」「/」「:」「-」に対応
		/// hhmmssの区切りは「時分秒」「:」に対応
		/// カッコで囲まれた曜日表記に対応 ex. 「(日)」「(水)」「(Wed)」「(sat.)」
		/// </summary>
		public static bool StringToDateTime(string strDate, out DateTime dtDate)
		{
			//「yyyy年mm月dd日」				→「yyyy/mm/dd」
			//「yyyy年mm月dd日hh時mm分」		→「yyyy/mm/dd hh:mm」
			//「yyyy年mm月dd日hh時mm分」		→「yyyy/mm/dd hh:mm」
			//「yyyy年mm月dd日 hh時mm分」		→「yyyy/mm/dd hh:mm」
			//「yyyy年mm月dd日hh時mm分ss秒」	→「yyyy/mm/dd hh:mm:ss」
			//「yyyy年mm月dd日 hh時mm分ss秒」	→「yyyy/mm/dd hh:mm:ss」
			//「yyyy年mm月dd日hh:mm」			→「yyyy/mm/dd hh:mm」
			//「yyyy年mm月dd日 hh:mm」			→「yyyy/mm/dd hh:mm」
			//「yyyy年mm月dd日hh:mm:ss」		→「yyyy/mm/dd hh:mm:ss」
			//「yyyy年mm月dd日 hh:mm:ss」		→「yyyy/mm/dd hh:mm:ss」
			{
				//カッコで囲まれた曜日の除去
				{
					//カッコを全角に統一
					strDate = strDate.Replace("(", "(");
					strDate = strDate.Replace(")", ")");

					//カッコを1つのスペースに変換
					Regex regex = new Regex(@"((.*))");
					MatchCollection matchCol = regex.Matches(strDate);
					if (matchCol.Count > 0)
						strDate = strDate.Replace(matchCol[0].Groups[1].Value, " ");
				}

				strDate = strDate.Replace(" ", " ");	//全角スペースの半角化
				strDate = strDate.Replace("年", "/");
				strDate = strDate.Replace("月", "/");
				strDate = strDate.Replace("日 ", " ");	//後ろにスペースのある「日」はそのまま除去
				strDate = strDate.Replace("時", ":");
				strDate = strDate.Replace("分", ":");
				strDate = strDate.Replace("秒", "");

				//2つ以上のスペースを1つに変換
				while (strDate.IndexOf("  ") >= 0)
				{
					strDate = strDate.Replace("  ", " ");
				}
				//前後のスペースを除去
				{
					strDate = strDate.TrimStart();
					strDate = strDate.TrimEnd();
				}

				//以下の4パターンを考慮して「日」を除去する
				//「yyyy/mm/dd日」→「yyyy/mm/dd」
				//「yyyy/mm/dd日hh:mm」→「yyyy/mm/dd hh:mm」
				//「yyyy/mm/dd日hh:mm:ss」→「yyyy/mm/dd hh:mm:ss」
				//「yyyy/mm/dd日 hh:mm:ss」→「yyyy/mm/dd hh:mm:ss」
				if (strDate.IndexOf("日") > 0)
				{
					strDate = strDate.Replace("日 ", "");			//スペース除去
					Regex regex = new Regex(@"(\d+)日(\d+)");
					MatchCollection matchCol = regex.Matches(strDate);
					if (matchCol.Count > 0)
						strDate = strDate.Replace("日", " ");
					else
						strDate = strDate.Replace("日", "");
				}
			}



			//「yyyy/mm/dd」「yyyy/mm/d」「yyyy/m/dd」「yyyy/m/d」
			if (strDate.Length == 10 || strDate.Length == 9 || strDate.Length == 8)
			{
				Regex regex = new Regex(@"(\d{4})[-/:](\d+)[-/:](\d+)");
				MatchCollection matchCol = regex.Matches(strDate);
				for (int i = 0; i < matchCol.Count; i++)
				{
					if (matchCol[i].Groups.Count == 4)
					{
						try
						{
							dtDate = new DateTime(Int32.Parse(matchCol[i].Groups[1].Value), Int32.Parse(matchCol[i].Groups[2].Value), Int32.Parse(matchCol[i].Groups[3].Value));
							return true;
						}
						catch (Exception)
						{
						}
					}
				}
			}

			//「yyyymmdd」
			if (strDate.Length == 8)
			{
				Regex regex = new Regex(@"(\d{4})(\d{2})(\d{2})");
				MatchCollection matchCol = regex.Matches(strDate);
				for (int i = 0; i < matchCol.Count; i++)
				{
					if (matchCol[i].Groups.Count == 4)
					{
						try
						{
							dtDate = new DateTime(Int32.Parse(matchCol[i].Groups[1].Value), Int32.Parse(matchCol[i].Groups[2].Value), Int32.Parse(matchCol[i].Groups[3].Value));
							return true;
						}
						catch (Exception)
						{
						}
					}
				}
			}

			//「yyyy/mm/dd hh:mm」「yyyy/mm/d hh:mm」「yyyy/m/dd hh:mm」「yyyy/m/d hh:mm」「yyyy/m/d h:mm」
			if (strDate.Length == 16 || strDate.Length == 15 || strDate.Length == 14 || strDate.Length == 13)
			{
				Regex regex = new Regex(@"(\d{4})[-/:](\d+)[-/:](\d+) (\d+):(\d{2})");
				MatchCollection matchCol = regex.Matches(strDate);
				for (int i = 0; i < matchCol.Count; i++)
				{
					if (matchCol[i].Groups.Count == 6)
					{
						try
						{
							dtDate = new DateTime(Int32.Parse(matchCol[i].Groups[1].Value), Int32.Parse(matchCol[i].Groups[2].Value), Int32.Parse(matchCol[i].Groups[3].Value)
									, Int32.Parse(matchCol[i].Groups[4].Value), Int32.Parse(matchCol[i].Groups[5].Value), 0);
							return true;
						}
						catch (Exception)
						{
						}
					}
				}
			}

			//「yyyy/mm/dd hh:mm:ss」「yyyy/m/dd hh:mm:ss」「yyyy/mm/d hh:mm:ss」「yyyy/m/d hh:mm:ss」「yyyy/m/d h:mm:ss」
			if (strDate.Length == 19 || strDate.Length == 18 || strDate.Length == 17 || strDate.Length == 16)
			{
				Regex regex = new Regex(@"(\d{4})[-/:](\d+)[-/:](\d+) (\d+):(\d{2}):(\d{2})");
				MatchCollection matchCol = regex.Matches(strDate);
				for (int i = 0; i < matchCol.Count; i++)
				{
					if (matchCol[i].Groups.Count == 7)
					{
						try
						{
							dtDate = new DateTime(Int32.Parse(matchCol[i].Groups[1].Value), Int32.Parse(matchCol[i].Groups[2].Value), Int32.Parse(matchCol[i].Groups[3].Value)
									, Int32.Parse(matchCol[i].Groups[4].Value), Int32.Parse(matchCol[i].Groups[5].Value), Int32.Parse(matchCol[i].Groups[6].Value));
							return true;
						}
						catch (Exception)
						{
						}
					}
				}
			}


			//「2016-04-07T19:01:01+09:00」の形式
			//
			//「2016-04-07T19:01:01」がオフセット+09:00(日本時間)という意味。戻り値は「2016-04-07 19:01:01」
			//「2016-04-07T19:01:01+00:00」の場合、オフセット+00:00(UTC)という意味。戻り値はJST変換して「2016-04-08 04:01:01」
			if (strDate.Length == 25)
			{
				//Parseですませちゃう
				try
				{
					dtDate = DateTime.Parse(strDate);
					return true;
				}
				catch (Exception)
				{
				}

				//Regex regex = new Regex(@"(\d{4})[-/:](\d+)[-/:](\d+)T(\d+):(\d{2}):(\d{2})([+-])(\d{2}):(\d{2})");
				//MatchCollection matchCol = regex.Matches(strDate);
				//for (int i = 0; i < matchCol.Count; i++)
				//{
				//	if (matchCol[i].Groups.Count == 10)
				//	{
				//		try
				//		{
				//			dtDate = new DateTime(Int32.Parse(matchCol[i].Groups[1].Value), Int32.Parse(matchCol[i].Groups[2].Value), Int32.Parse(matchCol[i].Groups[3].Value)
				//					, Int32.Parse(matchCol[i].Groups[4].Value), Int32.Parse(matchCol[i].Groups[5].Value), Int32.Parse(matchCol[i].Groups[6].Value));


				//			//渡された文字列の時差取得
				//			bool bTimeZonePlus = (matchCol[i].Groups[7].Value == "+") ? true : false;
				//			TimeSpan spanTimeZone = new TimeSpan(Int32.Parse(matchCol[i].Groups[8].Value), Int32.Parse(matchCol[i].Groups[9].Value), 0);

				//			//UTCとシステムの時差取得
				//			TimeSpan spanUTC = TimeZoneInfo.Local.BaseUtcOffset;		//UTCオフセット取得(日本なら常に+09:00)

				//			TimeSpan span;

				//			//両者の差を求めて
				//			if (bTimeZonePlus)
				//				span = spanUTC - spanTimeZone;
				//			else
				//				span = spanUTC + spanTimeZone;

				//			//渡された文字列の時差に合わせて変換
				//			dtDate = dtDate + span;

				//			return true;
				//		}
				//		catch (Exception)
				//		{
				//		}
				//	}
				//}
			}

			//「2016-04-07T10:00:44Z」の形式
			//
			//↑はタイムオフセットゼロ=UTCという意味。日本時間にするため時差9時間プラスして返す
			if (strDate.Length == 20)
			{
				//Parseですませちゃう
				try
				{
					dtDate = DateTime.Parse(strDate);
					return true;
				}
				catch (Exception)
				{
				}

				//Regex regex = new Regex(@"(\d{4})[-/:](\d+)[-/:](\d+)T(\d+):(\d{2}):(\d{2})Z");
				//MatchCollection matchCol = regex.Matches(strDate);
				//for (int i = 0; i < matchCol.Count; i++)
				//{
				//	if (matchCol[i].Groups.Count == 7)
				//	{
				//		try
				//		{
				//			dtDate = new DateTime(Int32.Parse(matchCol[i].Groups[1].Value), Int32.Parse(matchCol[i].Groups[2].Value), Int32.Parse(matchCol[i].Groups[3].Value)
				//					, Int32.Parse(matchCol[i].Groups[4].Value), Int32.Parse(matchCol[i].Groups[5].Value), Int32.Parse(matchCol[i].Groups[6].Value));


				//			//UTCとシステムの時差取得
				//			TimeSpan spanUTC = TimeZoneInfo.Local.BaseUtcOffset;		//UTCオフセット取得(日本なら常に+09:00)

				//			//渡された文字列の時差に合わせて変換
				//			dtDate = dtDate + spanUTC;

				//			return true;
				//		}
				//		catch (Exception)
				//		{
				//		}
				//	}
				//}
			}

			//Parseしてみる
			try
			{
				dtDate = DateTime.Parse(strDate);
				return true;
			}
			catch (Exception)
			{
			}


			dtDate = DateTime.MinValue;
			return false;
		}

カテゴリー「その他」 のエントリー