You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
6.4 KiB
C#
177 lines
6.4 KiB
C#
#region License, Terms and Conditions
|
|
//
|
|
// Jayrock - JSON and JSON-RPC for Microsoft .NET Framework and Mono
|
|
// Written by Atif Aziz (atif.aziz@skybow.com)
|
|
// Copyright (c) 2005 Atif Aziz. All rights reserved.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License as published by the Free
|
|
// Software Foundation; either version 2.1 of the License, or (at your option)
|
|
// any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful, but WITHOUT
|
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
// details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with this library; if not, write to the Free Software Foundation, Inc.,
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
#endregion
|
|
|
|
namespace Jayrock
|
|
{
|
|
#region Imports
|
|
|
|
using System;
|
|
using System.Globalization;
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Provides date and time parsing according to the formats described in
|
|
/// RFC 822/1123 specification.
|
|
/// </summary>
|
|
|
|
public sealed class InternetDate
|
|
{
|
|
private static readonly string[] _formats =
|
|
{
|
|
"dd MMM yyyy HH':'mm",
|
|
"dd MMM yyyy HH':'mm':'ss",
|
|
"ddd, dd MMM yyyy HH':'mm",
|
|
"ddd, dd MMM yyyy HH':'mm':'ss",
|
|
};
|
|
|
|
public static DateTime Parse(string input)
|
|
{
|
|
if (input == null)
|
|
throw new ArgumentNullException("input");
|
|
|
|
if (input.Length < _formats[0].Length)
|
|
throw new ArgumentException("input");
|
|
|
|
//
|
|
// Parse according to the following syntax:
|
|
//
|
|
// date-time = [ day "," ] date time ; dd mm yy
|
|
// ; hh:mm:ss zzz
|
|
//
|
|
// day = "Mon" / "Tue" / "Wed" / "Thu"
|
|
// / "Fri" / "Sat" / "Sun"
|
|
//
|
|
// date = 1*2DIGIT month 2DIGIT ; day month year
|
|
// ; e.g. 20 Jun 82
|
|
//
|
|
// month = "Jan" / "Feb" / "Mar" / "Apr"
|
|
// / "May" / "Jun" / "Jul" / "Aug"
|
|
// / "Sep" / "Oct" / "Nov" / "Dec"
|
|
//
|
|
// time = hour zone ; ANSI and Military
|
|
//
|
|
// hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT]
|
|
// ; 00:00:00 - 23:59:59
|
|
//
|
|
// zone = "UT" / "GMT" ; Universal Time
|
|
// ; North American : UT
|
|
// / "EST" / "EDT" ; Eastern: - 5/ - 4
|
|
// / "CST" / "CDT" ; Central: - 6/ - 5
|
|
// / "MST" / "MDT" ; Mountain: - 7/ - 6
|
|
// / "PST" / "PDT" ; Pacific: - 8/ - 7
|
|
// / 1ALPHA ; Military: Z = UT;
|
|
// ; A:-1; (J not used)
|
|
// ; M:-12; N:+1; Y:+12
|
|
// / ( ("+" / "-") 4DIGIT ) ; Local differential
|
|
// ; hours+min. (HHMM)
|
|
//
|
|
// For more information, see:
|
|
// http://www.w3.org/Protocols/rfc822/#z28
|
|
//
|
|
|
|
//
|
|
// Start by processing the time zone component, which is the
|
|
// part that cannot be delegated to DateTime.ParseExact.
|
|
//
|
|
|
|
int zzz; // time zone offset stored as HH * 100 + MM
|
|
|
|
int zoneSpaceIndex = input.LastIndexOf(' ');
|
|
|
|
if (zoneSpaceIndex <= 0)
|
|
throw new FormatException();
|
|
|
|
string zone = input.Substring(zoneSpaceIndex + 1);
|
|
|
|
if (zone.Length == 0)
|
|
throw new FormatException("Missing time zone.");
|
|
|
|
switch (zone)
|
|
{
|
|
//
|
|
// Greenwich Mean Time (GMT) or Universal Time (UT)
|
|
//
|
|
|
|
case "UT" :
|
|
case "GMT" : zzz = +0000; break;
|
|
|
|
//
|
|
// Common North American time zones
|
|
//
|
|
|
|
case "EDT" : zzz = -0400; break;
|
|
case "EST" :
|
|
case "CDT" : zzz = -0500; break;
|
|
case "CST" :
|
|
case "MDT" : zzz = -0600; break;
|
|
case "MST" :
|
|
case "PDT" : zzz = -0700; break;
|
|
case "PST" : zzz = -0800; break;
|
|
|
|
//
|
|
// Local differential = ( "+" / "-" ) HHMM
|
|
//
|
|
|
|
default :
|
|
{
|
|
if (zone.Length < 4)
|
|
throw new FormatException("Length of local differential component must be at least 4 characters (HHMM).");
|
|
|
|
try
|
|
{
|
|
zzz = int.Parse(zone, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture);
|
|
}
|
|
catch (FormatException e)
|
|
{
|
|
throw new FormatException("Invalid local differential.", e);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Strip the time zone component along with any trailing space
|
|
// and parse out just the time piece by simply delegating to
|
|
// DateTime.ParseExact.
|
|
//
|
|
|
|
input = input.Substring(0, zoneSpaceIndex).TrimEnd();
|
|
DateTime time = DateTime.ParseExact(input, _formats, CultureInfo.InvariantCulture, DateTimeStyles.AllowInnerWhite);
|
|
|
|
//
|
|
// Subtract the offset to produce zulu time and then return the
|
|
// result as local time.
|
|
//
|
|
|
|
TimeSpan offset = new TimeSpan(zzz / 100, zzz % 100, 0);
|
|
return time.Subtract(offset).ToLocalTime();
|
|
}
|
|
|
|
private InternetDate()
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
}
|
|
}
|