C # string parse (no timezone) to DateTime respecting DST

I've read a lot of SO articles, but I can't seem to find a good answer to this problem. The suggestions added include functions that convert dates to and from strings more than once, concatenating a bit at the end, and it all just seems ... messy

So to the problem:

We have servers all over the world. All servers operate at their local time and keep time logs that are local to the server. Some servers are in DST monitoring areas, others arent

Suppose I have these lines from the log: 2013-01-01 12:34:56, 2013-07-01 12:34:56 And I know this server is in New York, so UTC-5 or UTC-4 when DST is running.

And I have the same lines from a log on a server in Hong Kong where DST does not apply and timezone is +8

What I need is a block of code where I can say this:

  • Here is a string representing the time
  • Here is the timezone: a line from
  • Daylight Saving Time should be applied where appropriate

And the code will parse the string into DateTimeOffset where the offset is adjusted according to DST if the parsed time is DST

For example: NY server log says "2013-01-01 ..." DST does NOT apply to this date in JANUARY, so the parsed date should be: 12:34:56 pm at new york time, aka 17:34:56 at UTC (because he is -5, not DST)

The NY server log says: "2013-07-01 ..." DST DOES applies to this date in June, so the syntax date should be: 12:34:56 PM in New York time, aka 16:34:56 in UTC ( because he is -4, with DST)

HK server, both time parameters are bred to 04:34:56 UTC

Thanks guys,

+3


source to share


2 answers


To get UTC times of the time recorded in different log files, you need the local time zone names. Then you can use DateTimeOffset

-struktsiyu
TimeZoneInfo

-class
to calculate the UTC-time:



public DateTime ParseAsUtc(string logDate, string timezoneName)
{
    var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timezoneName);
    var localDate = DateTime.Parse(logDate);
    var offset = new DateTimeOffset(localDate, timeZone.GetUtcOffset(localDate));
    return offset.ToUniversalTime().DateTime;
}

ParseAsUtc("2013-01-01 12:34:56", "Eastern Standard Time"); //01.01.2013 17:34:56
ParseAsUtc("2013-07-01 12:34:56", "Eastern Standard Time"); //01.07.2013 16:34:56
ParseAsUtc("2013-01-01 12:34:56", "China Standard Time");   //01.01.2013 04:34:56
ParseAsUtc("2013-01-01 12:34:56", "China Standard Time");   //01.07.2013 04:34:56

      

+5


source


First, I highly recommend that you change your system to enter UTC everywhere. It will make your life so much easier.

If you really stick with what you have, you should use DateTime.TryParseExact

with DateTimeStyles

just 0 (the default). This will give you the value DateTimeKind

Unspecified

you need. (It's not UTC, and it's not local to the parsing machine.)



Then you can use TimeZoneInfo.GetUtcOffset

(with the correct timezone for that log) to work out the offset and create DateTimeOffset

from the two together.

As completely aside, you can also change the use of the Noda Time project , which will make your code much easier to understand :)

+6


source







All Articles