Zasz
Zasz

Reputation: 12538

What is causing this behavior, in our C# DateTime type?

[Test]
public void Sadness()
{
   var dateTime = DateTime.UtcNow;
   Assert.That(dateTime, Is.EqualTo(DateTime.Parse(dateTime.ToString())));
}

Failed :

 Expected: 2011-10-31 06:12:44.000
 But was:  2011-10-31 06:12:44.350

I wish to know what is happening behind the scenes in ToString() etc to cause this behavior.

EDIT After seeing Jon's Answer :

[Test]
public void NewSadness()
{
    var dateTime = DateTime.UtcNow;
    Assert.That(dateTime, Is.EqualTo(DateTime.Parse(dateTime.ToString("o"))));
}

Result :

Expected: 2011-10-31 12:03:04.161
But was:  2011-10-31 06:33:04.161

Same result with capital and small 'o' . I'm reading up the docs, but still unclear.

Upvotes: 5

Views: 257

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1062600

The default format specifier is "G" - the general-purpose format - which has limited fidelity. If you want to reproduce exactly the same thing, use the roundtrip specifier, "O".

string s = dateTime.ToString("O", CultureInfo.InvariantCulture);
Assert.That(dateTime, Is.EqualTo(DateTime.ParseExact(
       s, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind)));

Upvotes: 6

Jon Skeet
Jon Skeet

Reputation: 1500065

Have a look at what dateTime.ToString() produces - it will typically only be accurate to the second, although it depends on cultural settings. If ToString() only gives a result accurate to a second, there's no way that parsing the string can give more information...

You can use the "o" standard format string to provide a round-trippable string representation. For example, at the moment it produces something like:

2011-10-31T06:28:34.6425574Z

EDIT: You need to parse with the same specifier to get the same result back:

string text = dateTime.ToString("o");
// Culture is irrelevant when using the "o" specifier
DateTime parsed = DateTime.ParseExact(text, "o", null,
                                      DateTimeStyles.RoundtripKind);

Upvotes: 9

Related Questions