I'm placed in a situation where my program has 2 integratio开发者_开发问答ns towards 3rd party systems. The integrations consists of 1) XML protocol over TCP/IP and 2) Webservices made in WCF.
In either case the integration partner needs the TimeStamps / DateTimes I pass to them to contain information about the TimeZone and Daylight Savings, so they can display the correct time regardless of their customers TimeZone / Position.
I'd rather not change the current protocol, in either cases they expect DateTime, so my question is: Is it possible to pass the TimeZone and Daylight Savings information as a part of the DateTime?
Right now my timestamps looks like this:
2011-04-27T15:14:13.963
I would love to have it look something like this (I'm located in Denmark so we use CEST) and be able to transfer the information with a DateTime object
2011-04-27T15:14:13.963 +01:00
However I do not know how I should accomplish this nor take into account the Daylight Savings Factor
If you need to know both the date/time and the time zone, you'll have to come up with your own encapsulation:
DateTime
only contains the date/time and information as to whether it's "local" (in the system time zone) or UTCDateTimeOffset
contains information about the date/time and its offset to UTC, but that's not the same as its time zone
You could combine TimeZoneInfo
and DateTimeOffset
in a struct though.
Alternatively, if you're happy to use beta-quality, API-could-still-change software, you could use Noda Time, a project I started to basically port the Joda Time API to .NET.
That's in terms of in-process representation... as for passing the information around, you need to find out what your integration partners use. For example, they might want the UTC time and an Olsen time zone name... or they may just want the offset.
Including the "current" offset from UTC may be enough, rather than including full time zone information, if you only need to know what the local time was for the user at the time the timestamp was created. It just means you don't know what the local time was 2 seconds later...
Instead of DateTime
use DateTimeOffset
, which contains timezone offset information.
As for daylight savings time - you will need to use the Olsen database.
See this related question.
Use UTC time and you can stick with DateTime. UTC is converted to local (or any other time) in-place. Also this solves problem with Daylight Saving Time. Using UTC is the best solution, I have had some expirience with it.
Small demo:
namespace TimeZoneTest
{
using System;
using System.Globalization;
class Program
{
static void Main(string[] args)
{
// get local time
DateTime localTime = DateTime.Now;
Console.WriteLine(string.Format(
CultureInfo.CurrentCulture,
"localTime = {0}, localTime.Kind = {1}",
localTime,
localTime.Kind));
// get local time zone, or use TimeZoneInfo to get any time zone you want
TimeZone ltz = TimeZone.CurrentTimeZone;
Console.WriteLine(string.Format("local time zone = {0}", ltz.StandardName));
// convert local time to UTC
DateTime utcTime = ltz.ToUniversalTime(localTime);
Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
"utcTime = {0}, utcTime.Kind = {1}",
utcTime,
utcTime.Kind));
// transfer date via service, as ISO time string
string isoUtc = utcTime.ToString("o");
Console.WriteLine("...");
Console.WriteLine(string.Format("transfer: isoUtc = {0}", isoUtc));
Console.WriteLine("...");
// now on the other side
DateTime utcTimeRecieved = DateTime.ParseExact(
isoUtc,
"o",
CultureInfo.InvariantCulture,
DateTimeStyles.RoundtripKind);
Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
"utcTimeRecieved = {0}, utcTimeRecieved.Kind = {1}",
utcTimeRecieved,
utcTimeRecieved.Kind));
// client time zone, or use TimeZoneInfo to get any time zone you want
TimeZone ctz = TimeZone.CurrentTimeZone;
Console.WriteLine(string.Format("client time zone = {0}", ctz.StandardName));
// get local time from utc
DateTime clientLocal = ctz.ToLocalTime(utcTimeRecieved);
Console.WriteLine(string.Format(
CultureInfo.CurrentCulture,
"clientLocal = {0}, clientLocal.Kind = {1}",
clientLocal,
clientLocal.Kind));
Console.WriteLine("\nPress any key to exit..");
Console.ReadKey();
}
}
}
精彩评论