Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTimeConverter converting from UTC string

I have a date serialized as a string "2012-06-20T13:19:59.1091122Z"

Using the DateTimeConverter, this gets converted to a DateTime object {22:49:59.1091122} with the Kind property set to "Local".

eg. The following test fails:

    private static readonly DateTime UtcDate = new DateTime(634757951991091122, DateTimeKind.Utc);
    private const string UtcSerialisedDate = "2012-06-20T13:19:59.1091122Z";

    [Test]
    public void DateTimeConverter_Convert_From_Utc_String()
    {
        // Arrange
        var converter = TypeDescriptor.GetConverter(typeof(DateTime));

        // Act
        var result = converter.ConvertFrom(UtcSerialisedDate);

        // Assert
        Assert.AreEqual(UtcDate, result);
        Assert.AreEqual(DateTimeKind.Utc, ((DateTime)result).Kind);
    }

I'm a bit surprised by this... I would have expected that the DateTime object returned by the converter would be in UTC.

The docs do say that DateTimeConverter uses DateTime.Parse, but I'm guessing it must not use the DateTimeStyles.RoundtripKind option.

Is there any way around this?

like image 790
David Gardiner Avatar asked Jun 21 '12 02:06

David Gardiner


People also ask

How do you convert UTC to string?

To convert a JavaScript date object to a UTC string, you can use the toUTCString() method of the Date object. The toUTCString() method converts a date to a string, using the universal time zone. Alternatively, you could also use the Date.

How do you convert UTC to local time?

Add the local time offset to the UTC time. For example, if your local time offset is -5:00, and if the UTC time is shown as 11:00, add -5 to 11. The time setting when adjusted for offset is 06:00 (6:00 A.M.).

How do you convert UTC to local in Python?

This datetime object will have no timezone associated with it. Therefore assign the UTC timezone to this datetime object using replace(tzinfo=pytz. UTC) function. Convert the timezone of the datetime object to local timezone by calling the astimezone() function on datetime object.

How do you convert UTC time to local time in typescript?

var utcDate = '2011-06-29T16:52:48.000Z'; // ISO-8601 formatted date returned from server var localDate = new Date(utcDate);


1 Answers

The real bug here is that DateTime.Parse() without any DateTimeStyles passed should still see the "Z" and recognize that it should be parsed as UTC. But good luck getting MS to acknowledge or fix that.

The particular problem illustrated by your code sample is that the DateTimeConverter has to override methods from TypeConverter, and thus has no ability to pass extra parameters such as DateTimeStyles. It's too bad it doesn't implement some sort of static or threadstatic property for this. It does indeed take advantage of the thread's Culture.CurrentCulture, but DateTimeStyles are a separate thing from culture, so alas - that's another dead end.

I assume you are locked in to using a converter, rather than just calling parse directly? Is this a hard requirement? If not, you could do the following:

public static object ConvertFrom<T>(string value)
{
  if (typeof(T) == typeof(DateTime))
    return DateTime.Parse(value, null, DateTimeStyles.RoundtripKind);

  var converter = TypeDescriptor.GetConverter(typeof(T));
  return converter.ConvertFrom(value);
}

Another approach would be to use a DateTimeOffsetConverter instead - it understands the Z timezone properly. You could then use the .UtcDateTime property of the result to get back to a DateTime with a UTC kind.

like image 182
Matt Johnson-Pint Avatar answered Sep 18 '22 15:09

Matt Johnson-Pint