Having problems with converting my DateTime to UTC

前端 未结 5 769
抹茶落季
抹茶落季 2020-12-23 13:25

I am storing all my dates in UTC format in my database. I ask the user for their timezone and I want to use their time zone plus what I am guessing is the server time to fig

相关标签:
5条回答
  • 2020-12-23 13:45

    UTC is just a time zone that everyone agreed on as the standard time zone. Specifically, it's a time zone that contains London, England. EDIT: Note that it's not the exact same time zone; for example, UTC has no DST. (Thanks, Jon Skeet)

    The only special thing about UTC is that it's much easier to use in .Net than any other time zone (DateTime.UtcNow, DateTime.ToUniversalTime, and other members).

    Therefore, as others have mentioned, the best thing for you to do is store all dates in UTC within your database, then convert to the user's local time (by writing TimeZoneInfo.ConvertTime(time, usersTimeZone) before displaying.


    If you want to be fancier, you can geolocate your users' IP addresses to automatically guess their time zones.

    0 讨论(0)
  • 2020-12-23 13:52

    The DateTime structure supports only two timezones:

    • The local timezone the machine is running in.
    • and UTC.

    Have a look at the DateTimeOffset structure.

    var info = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
    
    DateTimeOffset localServerTime = DateTimeOffset.Now;
    
    DateTimeOffset usersTime = TimeZoneInfo.ConvertTime(localServerTime, info);
    
    DateTimeOffset utc = localServerTime.ToUniversalTime();
    
    Console.WriteLine("Local Time:  {0}", localServerTime);
    Console.WriteLine("User's Time: {0}", usersTime);
    Console.WriteLine("UTC:         {0}", utc);
    

    Output:

    Local Time:  30.08.2009 20:48:17 +02:00
    User's Time: 31.08.2009 03:48:17 +09:00
    UTC:         30.08.2009 18:48:17 +00:00
    
    0 讨论(0)
  • 2020-12-23 13:56

    You need to set the Kind to Unspecified, like this:

    DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified);
    var utc = TimeZoneInfo.ConvertTimeToUtc(now , zone);
    

    DateTimeKind.Local means the in local time zone, and not any other time zone. That's why you were getting the error.

    0 讨论(0)
  • 2020-12-23 13:56

    Everyone else's answer seems overly complex. I had a specific requirement and this worked fine for me:

    void Main()
    {
        var startDate = DateTime.Today;
        var StartDateUtc = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.SpecifyKind(startDate.Date, DateTimeKind.Unspecified), "Eastern Standard Time", "UTC");
        startDate.Dump();
        StartDateUtc.Dump();
    }
    

    Which outputs (from linqpad) what I expected:

    12/20/2013 12:00:00 AM

    12/20/2013 5:00:00 AM

    Props to Slaks for the Unspecified kind tip. That's what I was missing. But all the talk about there being only two kinds of dates (local and UTC) just muddled the issue for me.

    FYI -- the machine I ran this on was in Central Time Zone and DST was not in effect.

    0 讨论(0)
  • 2020-12-23 14:02

    As dtb says, you should use DateTimeOffset if you want to store a date/time with a specific time zone.

    However, it's not at all clear from your post that you really need to. You only give examples using DateTime.Now and you say you're guessing that you're using the server time. What time do you actually want? If you just want the current time in UTC, use DateTime.UtcNow or DateTimeOffset.UtcNow. You don't need to know the time zone to know the current UTC time, precisely because it's universal.

    If you're getting a date/time from the user in some other way, please give more information - that way we'll be able to work out what you need to do. Otherwise we're just guessing.

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