![]() |
Languages »
C# »
Date / Time
Beginner
License: The Code Project Open License (CPOL)
W3CDateTime Structure in C#By heebaek-choiSimple W3CDateTime Structure when you using atom feed like a gmail |
C#, .NET (.NET 2.0), Dev
|
||||||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
I'm please to post this article, my very first one. Please understand my bad english. my english is not as good as my programming skill.. :-P
this article about simple W3CDateTime Structure in C#.
I made it purpose of parse w3c datetime of gmail atom feed.
but i think you can use it common way if you have w3c date time string.
<modified>2009-1103T16:52:16:Z</modified>
"2009-1103T16:52:16:Z" - this is w3c date time string.
"Z" means this time is expressed in universal time
there are many libraries to parse gmail atom feed, because no official gmail api
like a atom.net. but i can't find simple class just for handling W3CDateTime.
http://www.w3.org/TR/NOTE-datetime
TZD used for time zone offset for issuer. (+09:00, -05:00, or Z means 0)
hh = 00 through 23. but i think gmail atom feed use 01 through 24.
"2009-11-02T24:39:06Z" - this time was logged in my application.
in my application, exception occured when DateTime.Parse(innerText);
because of default DateTime class does not support w3c date string and gmail atom feed do use 1-24hour :(
after made this structure i can solve this problem by replace just small amount of source.
like this - W3CDateTime.ParseToLocalTime(innerText);
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Bobaman.NewTools
{
public struct W3CDateTime
{
public static TimeSpan CurrentTimeZoneOffset
{
get
{
return TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
}
}
private DateTime time;
private TimeSpan tzd;
public W3CDateTime(DateTime time, TimeSpan tzd)
{
this.time = time;
this.tzd = tzd;
}
public override string ToString()
{
string timePart = time.ToString("yyyy-MM-ddTHH:mm:ss");
string tzdPart = "Z";
if (tzd != TimeSpan.Zero)
tzdPart = String.Format("{0}{1:00}:{2:00}", tzd > TimeSpan.Zero ? "+" : "-", tzd.Hours, tzd.Minutes);
return timePart + tzdPart;
}
public DateTime ToLocalTime()
{
return ToUniversalTime().ToLocalTime();
}
public DateTime ToUniversalTime()
{
return DateTime.SpecifyKind(time - tzd, DateTimeKind.Utc);
}
public static W3CDateTime Parse(string W3CDateTimeString)
{
}
public static DateTime ParseToLocalTime(string W3CDateTimeString)
{
return Parse(W3CDateTimeString).ToLocalTime();
}
public static DateTime ParseToUniversalTime(string W3CDateTimeString)
{
return Parse(W3CDateTimeString).ToUniversalTime();
}
public static W3CDateTime FromDateTime(DateTime dateTime)
{
if (dateTime.Kind == DateTimeKind.Local || dateTime.Kind == DateTimeKind.Unspecified)
return new W3CDateTime(dateTime, CurrentTimeZoneOffset);
else
return new W3CDateTime(dateTime, TimeSpan.Zero);
}
public static string ToString(DateTime dateTime)
{
return FromDateTime(dateTime).ToString();
}
}
}
this is outline of structure.
it's not full source. i ignored some functions (properties and some TryParse function and etc)
this structure keeps two parts. the time and tzd(time zone offset)
please remember that ToLocalTime function convert to YOUR local time. but tzd part of w3c date format is not yours. it's timezone offset of THEIR(issuer or publisher).
if you need tzd part of 'their' local time zone, you can call Parse function to parse to W3CDateTime and you can access that property.
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
W3CDateTime googlefeed = W3CDateTime.Parse("2009-11-02T24:39:06Z");
W3CDateTime sameTime1 = W3CDateTime.Parse("1994-11-05T08:15:30-05:00");
W3CDateTime sameTime2 = W3CDateTime.Parse("1994-11-05T13:15:30Z");
if (sameTime1.ToUniversalTime() == sameTime2.ToUniversalTime())
Console.WriteLine("good");
Console.WriteLine(googlefeed.ToLocalTime());
}
}
}
this example shows parse w3c date string that contains "24" Hour.
and prove equality of "1994-11-05T08:15:30-05:00" and "1994-11-05T13:15:30Z"
you can write w3c date string from your time. for example W3CDateTime.ToString(DateTime.Now). DateTime.Now will be expressed by local time with timezone offset.
when you call ToString if you provide utc DateTime, it will be converted to "Z" format.
public static W3CDateTime Parse(string W3CDateTimeString)
{
const string W3CDateFormat =
@"^(? \d\d\d\d)" +
@"(-(? \d\d)(-(? \d\d)(T(? \d\d):(? \d\d)(:(? \d\d)(? \.\d+)?)?" +
@"(? (Z|[+\-]\d\d:\d\d)))?)?)?$";
Regex regex = new Regex(W3CDateFormat);
Match match = regex.Match(W3CDateTimeString);
if (!match.Success)
{
// Didn't match either expression. Throw an exception.
throw new FormatException("String is not a valid date time stamp.");
}
int year = int.Parse(match.Groups["year"].Value);
int month = (match.Groups["month"].Success) ? int.Parse(match.Groups["month"].Value) : 1;
int day = match.Groups["day"].Success ? int.Parse(match.Groups["day"].Value) : 1;
int hour = match.Groups["hour"].Success ? int.Parse(match.Groups["hour"].Value) : 0;
int min = match.Groups["min"].Success ? int.Parse(match.Groups["min"].Value) : 0;
int sec = match.Groups["sec"].Success ? int.Parse(match.Groups["sec"].Value) : 0;
int ms = match.Groups["ms"].Success ? (int)Math.Round((1000 * double.Parse(match.Groups["ms"].Value))) : 0;
//for google mail feed
if (hour == 24)
hour = 0;
TimeSpan tzd = TimeSpan.Zero;
if (match.Groups["tzd"].Success)
tzd = ParseW3COffset(match.Groups["tzd"].Value);
DateTime time = new DateTime(year, month, day, hour, min, sec, ms);
return new W3CDateTime(time, tzd);
}
http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=172
I used and modify some source from that article. a regular expression works very well. To avoid exception from gmail atom feed, code minus one hour when a hour is 24 and add one hour after convert to DateTime structure. so it will use 0~23 hour. it was wrong.
i found that they just use "24" instead of "0". (it's from a lots of time logs of gmail atom feeds)
for example, the next of "2009-11-03T23:59:59Z" is "2009-11-04T24:00:00Z".
so i don't need to "plus one hour" and "minus one hour" (it's the cause of "plus one day" problem and it was my mistake)
I don't know why the google use that weird hour range.
Is... they want to reserve "0" for some reason like a default value or null? - i don't sure.
Parse function. there was big bug...OTL
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 3 Nov 2009 Editor: |
Copyright 2009 by heebaek-choi Everything else Copyright © CodeProject, 1999-2009 Web19 | Advertise on the Code Project |