简体   繁体   English

ASP.NET MVC 将 DateTime 转换为 UTC 发送到 API

[英]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:我需要将开始日期和结束日期发送到 UTC 格式的 API,我尝试了以下操作:

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?但他们似乎没有转换为 UTC,将 startDate 和 endDate 转换为 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.开始是一个字符串,是 2018-08-31,结束日期也是一个字符串,是 2018-08-31 我在上面的代码中添加了时间以涵盖完整日期。

Assuming you want endDate to represent the last possible moment on the given date in UTC: 假设您希望endDate表示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 ). ToUniversalTime 从计算机的本地时区转换为UTC(除非.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. 在上面的代码中,您既需要AssumeUniversal表示输入日期将被解释为UTC,也需要AdjustToUniversal表示希望将输出值保留为UTC而不是计算机的本地时区。

  • UTC is not a "format". UTC不是“格式”。 Your combined date and time strings would be in ISO 8601 extended format (also RFC 3339 compliant). 您合并的日期和时间字符串将采用ISO 8601扩展格式(也符合RFC 3339)。

  • Generally, try not to use Convert.ToDateTime . 通常,尽量不要使用Convert.ToDateTime It is equivalent to DateTime.Parse with CultureInfo.CurrentCulture and no DateTimeStyles . 它相当于DateTime.ParseCultureInfo.CurrentCulture并没有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. .AddDays(1).AddTicks(-1)可以使您到达该日期的最后一个可表示的价格变动。 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. 这样可以在开始和结束之间进行包含性的比较,但是它具有无法将两个值相减并不能获得完整的24小时的缺点。 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. 因此,它通常是最好只跟踪00:00一天到00:00 ,第二天,然后用在结束日期独家对比。 (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 移除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: 首先从NuGet软件包管理器安装以下软件包,并在您的项目中引用它:

Install-Package Newtonsoft.Json

Now you can easily use JsonConvert.SerializeObject(object value) method for serialize any objects to Json. 现在,您可以轻松地使用JsonConvert.SerializeObject(object value)方法将任何对象序列化为Json。

For converting DateTime to UTC use TimeZoneInfo.ConvertTimeToUtc(DateTime dateTime) method. 要将DateTime转换为UTC,请使用TimeZoneInfo.ConvertTimeToUtc(DateTime dateTime)方法。

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 . 变量dateInJson的值将类似于2018-08-30T19:30:00Z

In case you are sending dynamic linq like me, you'd need datetime in a text form.如果您像我一样发送动态 linq,则需要文本形式的日期时间。 If you are dealing with UTC then:如果您正在处理 UTC,那么:

//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);
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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