简体   繁体   中英

ASP.NET MVC convert DateTime to UTC to send to API

I need to send a start date and end date to an API in UTC format, I have tried the following:

DateTime startDate = Convert.ToDateTime(start + "T00:00:00Z").ToUniversalTime();
DateTime endDate = Convert.ToDateTime(end + "T23:59:59Z").ToUniversalTime();

But it appears they are not converting to UTC, what would be the proper way to take startDate and endDate and convert them over to UTC?

start is a string and is 2018-08-31 and end date is also a string and is 2018-08-31 I added the times in the code above to cover the full date.

Assuming you want endDate to represent the last possible moment on the given date in UTC:

DateTime startDate = DateTime.ParseExact(start, "yyyy-MM-dd", CultureInfo.InvariantCulture,
                        DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);

DateTime endDate = DateTime.ParseExact(end, "yyyy-MM-dd", CultureInfo.InvariantCulture,
                        DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)
                        .AddDays(1).AddTicks(-1);

A few other things:

  • ToUniversalTime converts to UTC from the computer's local time zone (unless .Kind == DateTimeKind.Utc ). You should generally avoid it unless the computer's local time zone is relevant to your situation.

  • In the above code, you need both AssumeUniversal to indicate that the input date is meant to be interpreted as UTC, and AdjustToUniversal to indicate that you want the output value to be kept in terms of UTC and not the computer's local time zone.

  • UTC is not a "format". Your combined date and time strings would be in ISO 8601 extended format (also RFC 3339 compliant).

  • Generally, try not to use Convert.ToDateTime . It is equivalent to DateTime.Parse with CultureInfo.CurrentCulture and no DateTimeStyles . That may work for some scenarios, but it is usually better to be more specific.

  • .AddDays(1).AddTicks(-1) is there to get you to the last representable tick on that date. That allows for inclusive comparison between start and end, however it comes with the disadvantage of not being able to subtract the two values and get a whole 24 hours. Thus, it is usually better to simply track 00:00 of one day to 00:00 of the next day, then use exclusive comparison on the end date. (Only the start date should be compared inclusively.)

    In other words, instead of:

     2018-08-31T00:00:00.0000000Z <= someValueToTest <= 2018-08-31T23:59:59.9999999Z 

    Do this:

     2018-08-31T00:00:00.0000000Z <= someValueToTest < 2018-09-01T00:00:00.0000000Z 

Remove the Z

        string start = "2018-08-31";
        string end = "2018-08-31";

        DateTime startDate = Convert.ToDateTime(start + "T00:00:00");
        DateTime endDate = Convert.ToDateTime(end + "T23:59:59");

        Console.WriteLine(startDate);                   // 8/31/2018 12:00:00 (Local)
        Console.WriteLine(startDate.ToUniversalTime()); // 8/31/2018 5:00:00 (UTC)
        Console.WriteLine(endDate);                     // 8/31/2018 11:59:59 (Local)
        Console.WriteLine(endDate.ToUniversalTime());   // 9/1/2018 4:59:59 (UTC)

First install below package from NuGet package manager and referenced it in your project:

Install-Package Newtonsoft.Json

Now you can easily use JsonConvert.SerializeObject(object value) method for serialize any objects to Json.

For converting DateTime to UTC use TimeZoneInfo.ConvertTimeToUtc(DateTime dateTime) method.

In your case:

DateTime date = DateTime.Parse("2018-08-31");
DateTime dateTimeToUtc = TimeZoneInfo.ConvertTimeToUtc(date);
string dateInJson = JsonConvert.SerializeObject(dateTimeToUtc);

the variable dateInJson will have value like 2018-08-30T19:30:00Z .

In case you are sending dynamic linq like me, you'd need datetime in a text form. If you are dealing with UTC then:

//specify utc just to avoid any problem
DateTime dateTime = yourDateTime.SetKindUtc();

var filterToSendToApi = $"CreatedTime>={dateTime.ToStringUtc()}"

helpers:

      public static string ToStringUtc(this DateTime time)
        {
            return $"DateTime({time.Ticks}, DateTimeKind.Utc)";
        }

      public static DateTime SetKindUtc(this DateTime dateTime)
        {
            if (dateTime.Kind == DateTimeKind.Utc)
            {
                return dateTime;
            }

            return DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM