81

I have a DateTime stored in universal time (UTC) of value 2010-01-01 01:01:01.

I would like to display it in EST in this format 2010-01-01 04:01:01GMT-04:00, however the 'K' formatter for timezone doesn't work in ToString

Lance U. Matthews
  • 15,725
  • 6
  • 48
  • 68
Comma
  • 1,567
  • 3
  • 15
  • 22
  • Do you have the time in universal time (UTC) or Greenwich Mean Time (GMT)? – Guffa Jul 23 '10 at 23:46
  • 1
    If you use the 'K' as a part of your formatter string on `DateTime.UtcNow`, it doesn't show the offset, because you're already on the GMT timezone and instead 'Z' is appended to your string. But, if you call it on a local time, it shows the offset correctly. The code for ISO8601 format would be `DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss.fff'GMT'K", CultureInfo.InvariantCulture)` – Siavash Mortazavi Mar 26 '21 at 16:57

5 Answers5

99

Use the "zzz" format specifier to get the UTC offset. For example:

        var dt = new DateTime(2010, 1, 1, 1, 1, 1, DateTimeKind.Utc);
        string s = dt.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss \"GMT\"zzz");
        Console.WriteLine(s);

Output: 2009-12-31 19:01:01 GMT-06:00

I'm in the CDT timezone. Make sure the DateTime is unambiguously DateTimeKind.Utc.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 2
    Keep in mind that all "zzz" does is tack the current environment's timezone offset on the end of the datetime being formatted. It does NOT take into account the DateTimeKind value set for the DateTime. It works for this particular case, but if you're formatting a UTC date, it likely won't turn out like you planned. – jpt Dec 20 '21 at 15:37
21

If like myself you happen to need a format like 2018-03-31T01:23:45.678-0300 (no colon in the timezone part), you can use this:

datetime.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz").Remove(26,1)
Andrew
  • 7,602
  • 2
  • 34
  • 42
  • 2
    This is quite similar to IS08601 format, for which you can likely just use the `O` format specifier (`O` includes the colon and seems to have microsecond precision by default) – Gert van den Berg Jul 31 '19 at 16:07
  • 2
    Right, that format is exactly like `"yyyy-MM-ddTHH:mm:ss.fffffffzzz"`. – Andrew Jul 31 '19 at 21:14
14

This method will return the specified time in Eastern Standard Time (as the question requested), even if EST is not the local time zone:

public string GetTimeInEasternStandardTime(DateTime time)
{
    TimeZoneInfo easternStandardTime = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
    DateTimeOffset timeInEST = TimeZoneInfo.ConvertTime(time, easternStandardTime);
    return timeInEST.ToString("yyyy-MM-dd hh:mm:ss tt\" GMT\"zzz");
}

Note: I haven't tested this in a non-English OS. See the MSDN documentation on TimeZoneInfo.FindSystemTimeZoneById.

Jon Schneider
  • 25,758
  • 23
  • 142
  • 170
  • 1
    @Sasha That's a good point, this answer before didn't disambiguate between AM and PM. I added the "tt" to the time format string to add the AM/PM. Per your comment, you could alternatively replace "hh" with "HH" to output the hours using a 24-hour clock (from 00 to 23). – Jon Schneider Mar 06 '17 at 14:46
6

Something like this works. You could probably clean it up a bit more:

string newDate = string.Format("{0:yyyy-MM-dd HH:mm:ss} GMT {1}", dt.ToLocalTime(), dt.ToLocalTime().ToString("%K"));
Robaticus
  • 22,857
  • 5
  • 54
  • 63
  • 2
    You, probably, meant `HH`, not `hh`. – Sasha Mar 06 '17 at 10:42
  • Probably... the "hh" gives the 12-hour-clock result where "HH" gives the military-time result. – Robaticus Mar 07 '17 at 13:31
  • 2
    Robaticus, I meant that 12-hour format is incompatible with the rest of your answer, because you don't specify AM/PM. I.e. either `t`/`tt` should be added to make `hh` meaningful (e.g. `02:00 AM`, `03:00 PM`), or `hh` should be replaced with `HH` to produce 24-hour format (e.g. `02:00`, `15:00`). So the `yyyy-MM-dd hh:mm:ss` format produces ambiguous output that can't be decoded back :(. – Sasha Mar 07 '17 at 14:04
  • 1
    I agree. I'll modify my answer to have the caps... though it is probably a low value change, since the selected answer has "HH" – Robaticus Mar 08 '17 at 17:32
2

I think you are looking for the TimeZoneInfo class (see http://msdn.microsoft.com/en-us/library/system.timezoneinfo_members.aspx). It has many static methods to convert dates between time zones.

Philip Smith
  • 2,741
  • 25
  • 32