DateTime.Parse(2012-09-30T23:00:00.0000000Z) always converts to DateTimeKind.Local
I would use my Noda Time project personally. (Admittedly I'm biased as the author, but it would be cleaner...) But if you can't do that...
Either use DateTime.ParseExact
specifying the exact format you expect, and include DateTimeStyles.AssumeUniversal
and DateTimeStyles.AdjustToUniversal
in the parse code:
using System;
using System.Globalization;
class Test
{
static void Main()
{
var date = DateTime.ParseExact("2012-09-30T23:00:00.0000000Z",
"yyyy-MM-dd'T'HH:mm:ss.fffffff'Z'",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal |
DateTimeStyles.AdjustToUniversal);
Console.WriteLine(date);
Console.WriteLine(date.Kind);
}
}
(Quite why it would adjust to local by default without AdjustToUniversal
is beyond me, but never mind...)
EDIT: Just to expand on my objections to mattytommo's suggestion, I aimed to prove that it would lose information. I've failed so far - but in a very peculiar way. Have a look at this - running in the Europe/London time zone, where the clocks go back on October 28th in 2012, at 2am local time (1am UTC):
DateTime local1 = DateTime.Parse("2012-10-28T00:30:00.0000000Z");
DateTime local2 = DateTime.Parse("2012-10-28T01:30:00.0000000Z");
Console.WriteLine(local1 == local2); // True
DateTime utc1 = TimeZoneInfo.ConvertTimeToUtc(local1);
DateTime utc2 = TimeZoneInfo.ConvertTimeToUtc(local2);
Console.WriteLine(utc1 == utc2); // False. Hmm.
It looks like there's a "with or without DST" flag being stored somewhere, but I'll be blowed if I can work out where. The docs for TimeZoneInfo.ConvertTimeToUtc
state
If dateTime corresponds to an ambiguous time, this method assumes that it is the standard time of the source time zone.
That doesn't appear to be the case here when converting local2
...
EDIT: Okay, it gets even stranger - it depends which version of the framework you're using. Consider this program:
using System;
using System.Globalization;
class Test
{
static void Main()
{
DateTime local1 = DateTime.Parse("2012-10-28T00:30:00.0000000Z");
DateTime local2 = DateTime.Parse("2012-10-28T01:30:00.0000000Z");
DateTime utc1 = TimeZoneInfo.ConvertTimeToUtc(local1);
DateTime utc2 = TimeZoneInfo.ConvertTimeToUtc(local2);
Console.WriteLine(utc1);
Console.WriteLine(utc2);
DateTime utc3 = local1.ToUniversalTime();
DateTime utc4 = local2.ToUniversalTime();
Console.WriteLine(utc3);
Console.WriteLine(utc4);
}
}
So this takes two different UTC values, parses them with DateTime.Parse
, then converts them back to UTC in two different ways.
Results under .NET 3.5:
28/10/2012 01:30:00 // Look - we've lost information
28/10/2012 01:30:00
28/10/2012 00:30:00 // But ToUniversalTime() seems okay...
28/10/2012 01:30:00
Results under .NET 4.5 beta:
28/10/2012 00:30:00 // It's okay!
28/10/2012 01:30:00
28/10/2012 00:30:00
28/10/2012 01:30:00
How to convert string with a T and Z to DateTime
You could try something like this:
var dateString = "20150521T205510Z";
var date = DateTime.ParseExact(dateString,
"yyyyMMdd'T'HHmmss'Z'",
CultureInfo.InvariantCulture);
I referenced the answer from: DateTime.Parse("2012-09-30T23:00:00.0000000Z") always converts to DateTimeKind.Local
Time.parse and DateTime.parse returns different results
There is no timezone information in the input String
. DateTime.parse
therefore assumes UTC. Time.parse
assumes local time, and I guess you're in UTC+2.
>> time = "13:30:0"
=> "13:30:0"
>> DateTime.parse(time).to_s
=> "2013-10-13T13:30:00+00:00"
>> Time.parse(time).to_s
=> "2013-10-13 13:30:00 +0200"
C# DateTime.Parse(String) returns different value in different system
A string in the yyyy-MM-ddTHH:mm:ssZ
format represents a date in UTC.
It is correctly parsed as such, but unfortunately, the resulting DateTime
value is DatetimeKind.Local
, and its value is adjusted accordingly to the time zone of the computer.
As stated in the comment in the beginning of the DateTime
source code file,
Starting from V2.0, DateTime also stored some context about its time
zone in the form of a 3-state value representing Unspecified, Utc or
Local. This is stored in the two top bits of the 64-bit numeric value
with the remainder of the bits storing the tick count. This information
is only used during time zone conversions and is not part of the
identity of the DateTime. Thus, operations like Compare and Equals
ignore this state. This is to stay compatible with earlier behavior
and performance characteristics and to avoid forcing people into dealing
with the effects of daylight savings. Note, that this has little effect
on how the DateTime works except in a context where its specific time
zone is needed, such as during conversions and some parsing and formatting
cases.
Thus, the Ticks
property of a DatetimeKind.Local
date is relative to the local 12:00:00 midnight, January 1, 0001
, not to the UTC 12:00:00 midnight, January 1, 0001
.
This is documented in the remarks for the Ticks
property.
This also means that the two date instances obtained via this kind of DateTime.Parse
on different servers in different timezones, would compare as "unequal" even though they originate from the same string that describes the same UTC date. This is for backward compatibility.
In order to compare the ticks directly, you need to convert both dates to Kind.UTC
first.
DateTime.ParseExact with string in format 2012-08-17T04:39:51.215Z
string stringdate = "2012-09-14T04:42:25.117Z";
DateTime date = new DateTime();
DateTime.TryParse(stringdate,out date);
MessageBox.Show(date.ToShortDateString());
eg:
MessageBox.Show(date.ToLocalTime().ToString());
Edit:
In the MSDN DateTime.TryParseExact Method:
The string parameter is parsed using default values. No white space
other than that present in format is allowed. If string lacks a date
component, the date of the returned DateTime value is set to 1/1/0001.
I see you are suppplying the Date component. My only guess is that I'm in Australia and it works and we use DD-MM-YYYY and in the US its MM-DD-YYYY. Perhaps flip it around and see if that works, eg:
"2012-17-08T04:39:52.878Z"
c# convert string to date - what kind of format is this?
This is the format that applies to your string
, although it is not a valid string according to the ISO 8601 standard:
var date = DateTime.ParseExact("2014-11-03 08:44:00:082467 Z",
"yyyy-MM-dd' 'HH:mm:ss:ffffff' Z'",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal |
DateTimeStyles.AdjustToUniversal);
Dotnetfiddle
Related Topics
Access Form Component from Another Class
How to Embed Gecko or Webkit in a Windows Form Just Like a Webview
C# Generic Type Inference with Multiple Types
Login Using Google Oauth 2.0 with C#
Html.Enumdropdownlistfor: Showing a Default Text
Why Does Environment.Exit() Not Terminate the Program Any More
Recommend a Library/API to Unzip File in C#
Adding and Removing Anonymous Event Handler
C# Speech Recognition - Is This What the User Said
Will a Future Version of .Net Support Tuples in C#
What to Use: Var or Object Name Type
Getmanifestresourcestream Returns Null
Argumentoutofrangeexception on Initialized List
Dbset.Attach(Entity) VS Dbcontext.Entry(Entity).State = Entitystate.Modified
Learning Single Responsibility Principle with C#