Where is the DateTime 'Z' format specifier?

[ Update : formatting specifiers are not the same as format strings; the format specifier is part of a custom format string, where the format string is β€œstock” and does not provide customization. My problem is with qualifiers, not formats]

I am trying to do DateTime roundtrip conversions with a format string that uses the zzz format specifier, which, as I know, is bound to local time. So, if I try to get around a trip with a UTC date, it throws a DateTimeInvalidLocalFormat exception, which should be with this text:

A UTC DateTime is converted to text in a format that is correct only for local times. This can happen when DateTime.ToString is called using the format specifier "z", which will include the local time zone offset at the output. In this case, either use the format specifier "Z", which indicates the time UTC , or use the format string "o", which is the recommended way to save the DateTime in the text. This can also happen when passing a DateTime to serialize an XmlConvert or DataSet. If you are using XmlConvert.ToString, go to XmlDateTimeSerializationMode.RoundtripKind to serialize correctly. If you are using a DataSet, set the DateTimeMode in the DataColumn object to DataSetDateTime.Utc.

Based on this assumption, all I have to do to get my code to work is to replace "zzz" with "ZZZ" so that I can stand in UTC. The problem is that β€œZ” is not found anywhere in the documentation, and any combination of the β€œZ” format that I try, that is, β€œZ”, β€œZZ”, β€œZZZ”, always just converts the DateTime instance with those processed by Z as literals.

Someone forgot to implement "Z" without telling the author about the exception, or am I missing how to replace the current local time offset with "+0000" without hacking?

Code example:

// This is the format with 'zzzzz' representing local time offset const string format = "ddd MMM dd HH:mm:ss zzzzz yyyy"; // create a UTC time const string expected = "Fri Dec 19 17:24:18 +0000 2008"; var time = new DateTime(2008, 12, 19, 17, 24, 18, 0, DateTimeKind.Utc); // If you're using a debugger this will rightfully throw an exception // with .NET 3.5 SP1 because 'z' is for local time only; however, the exception // asks me to use the 'Z' specifier for UTC times, but it doesn't exist, so it // just spits out 'Z' as a literal. var actual = time.ToString(format, CultureInfo.InvariantCulture); Assert.AreEqual(expected, actual); 
+45
c # datetime format utc
May 07 '09 at 6:09
source share
6 answers

Maybe the format specifier "K" would be useful. This is the only one that apparently mentions the use of capital β€œZ”.

"Z" is a unique case for DateTimes. The literal "Z" is actually part of the standard ISO 8601 standard for UTC time. When β€œZ” (Zulu) is tied to the end of the time, it indicates that it is UTC, so the literal Z is part of the time. This probably creates several problems for the .NET date format library, as it is actually a literal, not a format specifier.

+51
May 07, '09 at 6:23
source share

When you use DateTime, you can save the date and time inside a variable.

The date can be local time or UTC, it is up to you.

For example, I am in Italy (+2 UTC)

 var dt1 = new DateTime(2011, 6, 27, 12, 0, 0); // store 2011-06-27 12:00:00 var dt2 = dt1.ToUniversalTime() // store 2011-06-27 10:00:00 

So what happens when I print dt1 and dt2, including the time zone?

 dt1.ToString("MM/dd/yyyy hh:mm:ss z") // Compiler alert... // Output: 06/27/2011 12:00:00 +2 dt2.ToString("MM/dd/yyyy hh:mm:ss z") // Compiler alert... // Output: 06/27/2011 10:00:00 +2 

dt1 and dt2 contain only date and time information. dt1 and dt2 do not contain a time zone offset.

So, where does β€œ+2” come from if it is not contained in dt1 and dt2?

It comes from the settings of your clockwork.

The compiler tells you that when using the "zzz" format, you write a string that combines "DATE ​​+ TIME" (which are stored in dt1 and dt2) + "TIMEZONE OFFSET" (this is not contained in dt1 and dt2 because they are of type DateTyme ), and it will use the server machine offset to execute the code.

The compiler tells you: "Warning: the output of your code depends on the offset of the clock of the machine"

If I run this code on a server located in London (+1 UTC), the result will be completely different: instead of " +2 ", it will write " +1 "

 ... dt1.ToString("MM/dd/yyyy hh:mm:ss z") // Output: 06/27/2011 12:00:00 +1 dt2.ToString("MM/dd/yyyy hh:mm:ss z") // Output: 06/27/2011 10:00:00 +1 

The correct solution is to use the DateTimeOffset data type instead of DateTime. It is available in sql Server since version 2008 and in the .Net environment since version 3.5

+5
Jun 29 2018-11-11T00:
source share

The closing dates of the round line by line were always sick ... but the documents indicate that the specifier "o" is the one used for a round trip that fixes the UTC state. In the analysis, the result will usually be == Utc if the original was UTC. I found that the best thing to do is always normalize dates either from UTC or local before serialization, and then instruct the parser on which you selected normalization.

 DateTime now = DateTime.Now; DateTime utcNow = now.ToUniversalTime(); string nowStr = now.ToString( "o" ); string utcNowStr = utcNow.ToString( "o" ); now = DateTime.Parse( nowStr ); utcNow = DateTime.Parse( nowStr, null, DateTimeStyles.AdjustToUniversal ); Debug.Assert( now == utcNow ); 
+4
May 7 '09 at 6:41 a.m.
source share

This MSDN page lists standard DateTime strings that do not contain strings using "Z".

Update: you need to make sure that the rest of the date string also matches the correct template (you did not provide an example of what you are sending it, so it’s hard to say whether you did it or not). For the UTC format to work, it should look like this:

 // yyyy'-'MM'-'dd HH':'mm':'ss'Z' DateTime utcTime = DateTime.Parse("2009-05-07 08:17:25Z"); 
+2
May 07 '09 at 6:14
source share
 Label1.Text = dt.ToString("dd MMM yyyy | hh:mm | ff | zzz | zz | z"); 

will output:

 07 Mai 2009 | 08:16 | 13 | +02:00 | +02 | +2 

I am in Denmark, my offset is GMT +2 hours, the witch is correct.

if you need to receive a CUSTOMER MESSAGE , I recommend that you check out the little trick I did, The page is on a server in the UK, where GMT + 00: 00, and as you can see, you will receive a local GMT Offset.




Regarding your comment, I did:

 DateTime dt1 = DateTime.Now; DateTime dt2 = dt1.ToUniversalTime(); Label1.Text = dt1.ToString("dd MMM yyyy | hh:mm | ff | zzz | zz | z"); Label2.Text = dt2.ToString("dd MMM yyyy | hh:mm | FF | ZZZ | ZZ | Z"); 

and I get the following:

 07 Mai 2009 | 08:24 | 14 | +02:00 | +02 | +2 07 Mai 2009 | 06:24 | 14 | ZZZ | ZZ | Z 

I am not getting an exception, just ... it does nothing with capital Z :(

Sorry, but am I missing something?




Read MSDN carefully on Custom Date and Time Format Strings

no uppercase "Z" support.

+2
May 7, '09 at 6:17
source share

I was dealing with DateTimeOffset and unfortunately, "o" prints "+0000", not "Z".

So, I ended up with:

 dateTimeOffset.UtcDateTime.ToString("o") 
0
Mar 13 '14 at 2:35
source share



All Articles