18

There is this SOAP web service that sends me datetime objects in the following format

2016-03-29T12:20:35.093-05:00

That is day 29 of March of year 2016. Hour: 12:20:35.093 (GMT-5).

I want to be able to create a DateTime object, like this:

DateTime.Now

and get the string representation in the format described above and also the inverse operation, create a DateTime from a string like the one given above.

I've tried the following in order to create the date:

new DateTime(2016, 3, 29, 12, 20, 35, 093, DateTimeKind.Utc)

However, I can't not see how to specifie GMT-5 there...

I don't know how to convert a DateTime to the specified string format, either.

Using Nate's code I'm doing the following:

var d = new DateTimeOffset(2016, 3, 29, 12, 20, 35, 93, TimeSpan.FromHours(-3));

FormatIso8601(d)

However this call is returning: "2016-03-29T15:20:35Z" instead of :

"2016-03-29T12:20:35.093-03:00"

which is what I actually need.

I think this works:

        d.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz")
6
  • 1
    Did you even attempt to try use DateTime.Parse? Commented Mar 30, 2016 at 15:59
  • Yes, but I couldnt find the way to do it at all. Otherwise I wouldn't have come here to ask Commented Mar 30, 2016 at 16:00
  • 3
    You need to explain what you can and cannot do, exactly. Commented Mar 30, 2016 at 16:01
  • Show us what you have tried. Commented Mar 30, 2016 at 16:06
  • I've just added what I tried. Commented Mar 30, 2016 at 16:06

3 Answers 3

31

The format you're describing is ISO 8601.

Since you're working with timestamps that inclulde a time zone component, I'd strongly recommend using DateTimeOffset instead of DateTime. It makes things so much easier!

To create a DateTimeOffset for a given date, time, and time zone offset, use this syntax:

var date = new DateTimeOffset(2016, 3, 29, 12, 20, 35, 93, TimeSpan.FromHours(-5));
// March 29, 2016 at 12:20:35.93 GMT-5

This code will format a DateTimeOffset as ISO 8601:

public static string FormatIso8601(DateTimeOffset dto)
{
    string format = dto.Offset == TimeSpan.Zero
        ? "yyyy-MM-ddTHH:mm:ss.fffZ"
        : "yyyy-MM-ddTHH:mm:ss.fffzzz";

    return dto.ToString(format, CultureInfo.InvariantCulture);
}

And, to parse a string back to a DateTimeOffset:

public static DateTimeOffset ParseIso8601(string iso8601String)
{
    return DateTimeOffset.ParseExact(
        iso8601String,
        new string[] { "yyyy-MM-dd'T'HH:mm:ss.FFFK" },
        CultureInfo.InvariantCulture,
        DateTimeStyles.None);
}

If you must get back to a DateTime you can get this from the DateTimeOffset.UtcDateTime property.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks a lot. Is it safe to do this? ParseIso8601(myDate).DateTime to obtain a datetime object? In my system I would need datetimes instead of datetimeoffsets, if possible. Thanks
It's possible, but beware of unintended side effects: the time you get will depend on the local time zone of your machine. UtcDateTime will always return a UTC time, if you want to avoid that conversion.
So it's impossible to obtaina DateTime object which represents the same exact time I passed in the string to ParseIso8601?
"Exact time" in which time zone? The string may represent a different time zone than your machine is in.
Sure - UtcDateTime will be unambiguous.
|
25

A simpler way is to use the ToString method on DateTimeOffset with the "o" argument. This automatically prints the date in ISO8601 format

DateTimeOffset.Now.ToString("o");

The static parse method is also capable of correctly parsing a date in ISO8601 format.

DateTimeOffset.Parse("2016-25-12T20:45:30.3124+01:00");
DateTimeOffset.Parse("2016-25-12T20:45:30.3124Z");

Comments

1

Simple answer: DateTime.UtcNow.ToString("o")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.