0

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.

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
user979331
  • 11,039
  • 73
  • 223
  • 418
  • Possible duplicate of [how to convert string to DateTime as UTC as simple as that](https://stackoverflow.com/questions/13254211/how-to-convert-string-to-datetime-as-utc-as-simple-as-that) – Kevin Avignon Sep 07 '18 at 20:10
  • 1
    Z means "Zulu" also known as UTC. You are trying to convert a UTC time to UTC - I imagine it is working just fine :) – Aaron Sep 07 '18 at 20:13
  • What are your incorrect results? What is your local timezone offset? – Jasen Sep 07 '18 at 20:19

4 Answers4

5

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
    
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
1

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)
Todd Skelton
  • 6,839
  • 3
  • 36
  • 48
1

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.

Sajad Afaghiy
  • 524
  • 5
  • 12
0

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);
        }
Nick Kovalsky
  • 5,378
  • 2
  • 23
  • 50