Aximili
Aximili

Reputation: 29484

C#, date from string, time zone, daylight savings

Say I have the string "1 December 2012, 8:00:00"

I know that it is AEST time (regardless where the server is), with whatever daylight saving state at that time (1st Dec), but I want to store it in the database as UTC.

How do I convert it to UTC, treating the string as AEST regardless where the server is?

Upvotes: 0

Views: 3626

Answers (3)

Aximili
Aximili

Reputation: 29484

Thanks to Picrofo EGY, esr and White Dragon, I created this function that solves it

public static DateTimeOffset CreateDateWithTimezone(string dateStr, TimeZoneInfo tzi)
{
  DateTimeOffset dtoTzi = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi);

  DateTimeOffset dto;
  if (!DateTimeOffset.TryParse(dateStr + " " + dtoTzi.ToString("zzz"), out dto))
    throw new Exception("Failed to parse date: " + dateStr + " " + dtoTzi.ToString("zzz"));

  if (tzi.SupportsDaylightSavingTime)
  {
    TimeSpan offset = tzi.GetUtcOffset(dto);
    string offsetStr = (offset.TotalHours < 0 ? "" : "+") + offset.Hours.ToString("00") + ":" + offset.Minutes.ToString("00");

    if (!DateTimeOffset.TryParse(dateStr + " " + offsetStr, out dto))
      throw new Exception("Failed to parse date: " + dateStr + " " + dtoTzi.ToString("zzz"));
  }

  return dto;
}

Usage:

string dateStr = "1 December 2012, 08:00:00";
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
DateTimeOffset dtoUtc = CreateDateWithTimezone(dateStr, tzi).ToUniversalTime();

Response.Write("dtoUtc is " + dtoUtc);

It will print out

dtoUtc is 30/11/2012 9:00:00 PM +00:00

Perfect!

Upvotes: 2

Picrofo Software
Picrofo Software

Reputation: 5571

You may first initialize a System.DateTime which gets the DateTime from the string you've specified above. Then, you may use System.DateTime.ToUniversalTime() which converts the value of the current System.DateTime object to Coordinated Universal Time and store it in the database.

Example

DateTime AEST = DateTime.Parse("1 December 2012, 8:00:00"); //Initialize a new DateTime of name AEST which gets a System.DateTime from 1 December 2012, 8:00:00
DateTime UTC = AEST.ToUniversalTime(); //Initialize a new DateTime of name UTC which converts the value from AEST to Coordinated Universal Time
System.Diagnostics.Debug.WriteLine(UTC.ToString()); //Writes 12/1/2012 6:00:00 AM

Notice: If you are willing to convert a time from one time zone to another, you may use TimeZoneInfo.ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo, destinationTimeZone) where dateTime is the DateTime you would like to convert, sourceTimeZone is the time zone of the DateTime you would like to convert and destinationTimeZone is the time zone you would to get from dateTime

Example

string _date = "1 December 2012, 8:00:00"; //Initializes a new string of name _date as "1 December 2012, 8:00:00"
string targetTimeZone = "W. Australia Standard Time"; //Initializes a new string of name targetTimeZone as "W. Australia Standard Time"
DateTime sourceDateTime = DateTime.Parse(_date); //Initializes a new DateTime of name sourceDateTime which gets a valid DateTIme object from 1 December 2012, 8:00:00
DateTime AEST = TimeZoneInfo.ConvertTime(sourceDateTime, TimeZoneInfo.Local, TimeZoneInfo.FindSystemTimeZoneById(targetTimeZone)); //Initializes a new DateTime which converts the time zone from sourceDateTime assuming that sourceDateTime's TimeZone is the local time zone of the machine to an W. Australia Standard Time time zone of name AEST  

This will convert 1 December 2012, 8:00:00 assuming that its time zone is the local time zone of the machine (e.g Egypt Standard Time: (GMT+02:00) Cairo) to W. Australia Standard Time: (GMT+08:00) Perth which will be 12/1/2012 2:00:00 PM.

For list of time zones, see Microsoft Time Zone Index Values

Thanks,
I hope you find this helpful :)

Upvotes: 2

Jim Mischel
Jim Mischel

Reputation: 134005

Assuming you can parse the date with DateTime.TryParse and get it into a DateTime structure, you can then call ToUniversalTime to convert to UTC.

For example:

DateTime dt;
DateTime utcDate;
if (DateTime.TryParse(dateTimeString, out dt))
{
    utcDate = dt.ToUniversalTime();
    // store utcDate in database
}
else
{
    // error, unable to parse the date
}

Assuming, of course, that your local time is AEST, or the date/time string that you're parsing has the timezone specifier.

If your local time is something else and there's no timezone specifier, then you need to parse the date, add or subtract the offset from your time zone to match AEST, and then call ToUniversalTime.

Upvotes: 3

Related Questions