简体   繁体   中英

DateTime.ToString() not converting time

Looks like time is automatically getting changed during conversion. My input is 17:15:25 . However, it gets converted to 13:15:25 What could be the reason?

string testDate = Convert.ToDateTime("2016-03-24T17:15:25.879Z")
                         .ToString("dd-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture);

The result I get for testDate is : 24-Mar-2016 13:15:25

The Z in your input indicates a UTC time, but the default behaviour of Convert.ToDateTime is to convert the result to your local time. If you look at the result of Convert.ToDateTime("2016-03-30T17:15:25.879Z").Kind you'll see it's Local .

I would suggest using DateTime.ParseExact , where you can specify the exact behaviour you want, eg preserving the UTC time:

var dateTime = DateTime.ParseExact(
    "2016-03-30T17:15:25.879Z",
    "yyyy-MM-dd'T'HH:mm:ss.FFF'Z'",
    CultureInfo.InvariantCulture,
    DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal);
Console.WriteLine(dateTime);      // March 30 2016 17:15 (...)
Console.WriteLine(dateTime.Kind); // Utc

You can then convert that value to a string however you want to.

Of course I'd really suggest using my Noda Time project instead, where you'd parse to either an Instant or a ZonedDateTime which would know it's in UTC... IMO, DateTime is simply broken , precisely due to the kind of problems you've been seeing.

When you use Convert.ToDateTime (which uses DateTime.Parse internally) with Z (which means Zulu time ), this method adds your current time zone offset to that DateTime value.

Looks like your current time zone is UTC -04:00 right now and that's why method returns 4 hours back as a result.

I would suggest to use DateTime.ParseExact with AdjustToUniversal and AssumeUniversal styles for prevent Kind conversion as Jon answered .

From AdjustToUniversal

Date and time are returned as a Coordinated Universal Time (UTC). If the input string denotes a local time, through a time zone specifier or AssumeLocal , the date and time are converted from the local time to UTC. If the input string denotes a UTC time, through a time zone specifier or AssumeUniversal , no conversion occurs . If the input string does not denote a local or UTC time, no conversion occurs and the resulting Kind property is Unspecified .

Because of the CultureInfo.InvariantCulture. You are converting a date in your GMT

Convert.ToDateTime("2016-03-24T17:15:25.879Z")

And then you are converting it to string in an invariant culture

ToString("dd-MMM-yyyy HH:mm:ss",CultureInfo.InvariantCulture);

You should use DateTime.ParseExact, and then use the invariant culture in the conversion.

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