How to convert a date to UTC properly and then convert it back?

后端 未结 5 2043
心在旅途
心在旅途 2021-02-13 19:48

I\'m struggling with converting DateTime to UTC, the concept and all, something I\'m not understanding correctly.

When I get a date time string, say \"7/10/2013\", I si

相关标签:
5条回答
  • I have had the same issue and i made the following extension methods.

        public const string UTC = "UTC";
    
       public static DateTime Convert(this DateTime date, string fromZone, string toZone)
        {
            TimeZoneInfo to = TimeZoneInfo.FindSystemTimeZoneById(toZone);
            TimeZoneInfo from = TimeZoneInfo.FindSystemTimeZoneById(fromZone);
            return new DateTime(TimeZoneInfo.ConvertTime(date, from, to).Ticks, DateTimeKind.Unspecified); 
        }
    
        public static bool IsDayLightSaving(this DateTime date, string zone)
        {
            TimeZoneInfo to = TimeZoneInfo.FindSystemTimeZoneById(zone);
            return to.IsDaylightSavingTime(date);
        }
    
        public static DateTime ConvertToUTC(this DateTime date, string fromZone)
        {
            return date.Convert(fromZone, DateTime_Extension.UTC);
        }
    
        public static DateTime ConvertToLocal(this DateTime date, string toZone)
        {
            return date.Convert(DateTime_Extension.UTC, toZone);
        }
    

    The problem I found is actually finding the current users Time Zone. As this is not passed in the Header (you can get it via JavaScript) I have decided to ask the user to select their time zones when they register

    Hope this helps

    0 讨论(0)
  • 2021-02-13 20:22

    Do you want to store the date in local time? If you only care ablut the date portion, then you probably want to force the parsed time to Utc before saving it to the database:

    DateTime utcDate = DateTime.SpecifyKind(Convert.ToDateTime("7/10/2013"),DateTimeKind.Utc);
    

    That way when it's saved to the database it's already in UTC and will not include the time component.

    0 讨论(0)
  • 2021-02-13 20:28

    You convert back to local time using ToLocalTime(). It will see that the date/time is in July, so with DST, and hence it will shift by 4 hours and not by 5.

    If you have a client (e.g. Web browser) connecting to the server you will ultimately want the date/time converted to the local time of the client, not of the server. To do this the best way is to use TimeZone.ToLocalTime(): send to the served the time-zone the client is in and then convert directly to that time-zone all the time.

    NEVER add/subtract hours - always go through the time zone and use TimeZoone.ToLocalTime(). Adding/subtracting hours won't work when DST is involved.

    Note that it is not possible to get the current (local) time-zone from inside a browser. If your client is a browser you need to get the time-zone from some sort of configuration or have the user enter it.

    Note also that once you start to handle different time zones you no longer have just dates - you always have to deal with complete date-times: if you strip or loose the time part all the conversions won't work any more.

    Concerning question 2: UTC time is universal, not based on any specific time zone, hence once you convert to UTC you don't have to worry any more about the time-zone of the servers.

    0 讨论(0)
  • 2021-02-13 20:28

    If you want to store a local time in your database as UTC, you need to first convert it to universal time:

     DateTime dbDateTime = localDateTime.ToUniversalTime();
     ... store dbDateTime in the database ...
    

    When you read it back from the database, it will have its Kind property set to Unspecified. You will need to explicitly set its Kind property to UTC:

    dbDateTime = ... get from database, e.g. (DateTime) reader["SomeDateTimeColumn"]
    dbDateTime = DateTime.SpecifyKind(dbDateTime, DateTimeKind.Utc);
    

    If you then want to convert it to local time, you can use:

    DateTime localDateTime = dbDateTime.ToLocalTime();
    
    0 讨论(0)
  • 2021-02-13 20:34

    Perhaps it's too early in the morning and I need another cup of coffee, but (at least for display) isn't the solution just using TimeZoneInfo.ConvertTimeFromUtc and specifying the user's desired TZ? Or is the point that ConvertTimeFromUtc does not take into account the date/time at which the conversion back to the desired TZ is being performed? Thinking deeper: even if it does, does anyone know if it takes into account the edge case where the server has shifted to DST but the user's desired TZ has not yet?

    0 讨论(0)
提交回复
热议问题