I'm attempting to integrate with the TeamCity REST API. It contains timestamps of the form 20100804T104413+0100
. It's almost ISO 8601, but doesn't contain the hyphens.
How do I convert this from a string
to a DateTime
in .NET? I've tried:
DateTime.ParseExact(s, "yyyyMMddTHHmmss+zzzz", CultureInfo.InvariantCulture);
(and without the +zzzz), but I get String was not recognized as a valid DateTime.
This works for me:
using System;
using System.Globalization;
class Test
{
static void Main()
{
string text = "20100804T104413+0100";
DateTime dt = DateTime.ParseExact
(text,
"yyyyMMdd'T'HHmmsszzz",
CultureInfo.InvariantCulture);
Console.WriteLine(dt);
}
}
You don't actually need the quotes around the "T", but I tend to put them in to make the pattern clearer. Likewise the "zzz" can be "zzzz" - but I think the problem was the "+" you had before the "zzz".
Note that if you reformat it using the same format, you'll end up with a ":" in the middle of the offset specifier :(
I know the q. is already answered, but I believe a few notes are in place, if I may:
I would advice against using DateTime in your scenario, as it seems likely that you want the representation to be equal when roundtripped (i.e., when converted back again to a string, the representation must be equal). The problem with DateTime is that it doesn't keep the exact time zone information.
With the proposed solution, the timezone information may change. This depends on input, but using the invariant culture, you will receive a DateTime object of {4-8-2010 11:44:13}
. I thought this could be remedied by using DateTimeStyles.RoundtripKind
as in the following example, but, considering that there is no timezone information in DateTime
, this will still not work:
// DON'T DO THIS, dangerous code ahead:
DateTime time = DateTime.ParseExact(
"20100804T104413+0100",
"yyyyMMdd'T'HHmmssK",
CultureInfo.InvariantCulture,
DateTimeStyles.RoundtripKind);
// loosing data when converting back:
string convertedBack = time.ToString("yyyyMMdd'T'HHmmssK");
// convertedBack now contains "20100804T114413+02:00"
This problem goes away when you use DateTimeOffset
for your tasks instead. The idea remains the same, but all of a sudden, roundtripping works:
// DO THIS instead:
DateTimeOffset parsedDate = DateTimeOffset.ParseExact(
"20100804T104413+0100",
"yyyyMMdd'T'HHmmsszzz",
CultureInfo.InvariantCulture,
DateTimeStyles.RoundtripKind);
// converting back is now easy:
convertedBack = parsedDate.ToString("yyyyMMdd'T'HHmmssK");
// convertedBack contains the string "20100804T104413+01:00"
Of course, it depends on your situation whether the timezone information is important. But it wouldn't be the first time that 10 o'clock changed to 11 o'clock and finding the bug then can be hard.
As Jon Skeet mentioned, there's colon ":" in your output that wasn't there in the input. So, full roundtripping seems impossible. Unfortunately, while DateTimeFormatInfo
in any culture can modified to change just about every appearance, i.e., you can set TimeSeparator
to an empty string and the colons disappear in formatted times, this level of granularity is not available in the timezone offset. Even worse, Reflector shows that it is deliberately hard-coded (I once had the same issue with removing the "+" for positive offsets):
if (offset >= TimeSpan.Zero)
{
result.Append('+');
}
else
{
result.Append('-');
offset = offset.Negate();
}
result.AppendFormat(CultureInfo.InvariantCulture, "{0:00}:{1:00}", new object[] { offset.Hours, offset.Minutes });
The solution is to either provide your own IFormatProvider
, or to be pragmatic and just remove that colon:
convertedBack = parsedDate.ToString("yyyyMMdd'T'HHmmssK").Replace(":", "");
This is a little off topic in this old post but since I found the post when googling for parsing of Teamcity api dates, here's a Javascript version for the benefit of anyone else interested in the same thing:
moment("20150107T085108+0100", 'YYYYMMDDTHHmmssZ').format('YYYY-MM-DD HH:mm:ss')
It's using the excellent Moment.js library for the parsing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With