如何将 DateTime 格式化为 web UTC 格式?

我有一个日期时间,我想格式化为“ 2009-09-01T00:00:00.000Z”,但下面的代码给我“ 2009-09-01T00:00:00.000+01:00”(两行) :

new DateTime(2009, 9, 1, 0, 0, 0, 0, DateTimeKind.Utc).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffzzz")
new DateTime(2009, 9, 1, 0, 0, 0, 0, DateTimeKind.Utc).ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffzzz")

有什么办法吗?

296981 次浏览

Try this:

DateTime date = DateTime.ParseExact(
"Tue, 1 Jan 2008 00:00:00 UTC",
"ddd, d MMM yyyy HH:mm:ss UTC",
CultureInfo.InvariantCulture);

Previously asked question

string foo = yourDateTime.ToUniversalTime()
.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");

You want to use DateTimeOffset class.

var date = new DateTimeOffset(2009, 9, 1, 0, 0, 0, 0, new TimeSpan(0L));
var stringDate = date.ToString("u");

sorry I missed your original formatting with the miliseconds

var stringDate = date.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");

The best format to use is "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK".

The last K on string will be changed to 'Z' if the date is UTC or with timezone (+-hh:mm) if is local. (http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx)

As LukeH said, is good to use the ToUniversalTime if you want that all the dates will be UTC.

The final code is:

string foo = yourDateTime.ToUniversalTime()
.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK");

Why don't just use The Round-trip ("O", "o") Format Specifier?

The "O" or "o" standard format specifier represents a custom date and time format string using a pattern that preserves time zone information and emits a result string that complies with ISO 8601. For DateTime values, this format specifier is designed to preserve date and time values along with the DateTime.Kind property in text. The formatted string can be parsed back by using the DateTime.Parse(String, IFormatProvider, DateTimeStyles) or DateTime.ParseExact method if the styles parameter is set to DateTimeStyles.RoundtripKind.

The "O" or "o" standard format specifier corresponds to the "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK" custom format string for DateTime values and to the "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffzzz" custom format string for DateTimeOffset values. In this string, the pairs of single quotation marks that delimit individual characters, such as the hyphens, the colons, and the letter "T", indicate that the individual character is a literal that cannot be changed. The apostrophes do not appear in the output string.

The O" or "o" standard format specifier (and the "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK" custom format string) takes advantage of the three ways that ISO 8601 represents time zone information to preserve the Kind property of DateTime values:

public class Example
{
public static void Main()
{
DateTime dat = new DateTime(2009, 6, 15, 13, 45, 30,
DateTimeKind.Unspecified);
Console.WriteLine("{0} ({1}) --> {0:O}", dat, dat.Kind);


DateTime uDat = new DateTime(2009, 6, 15, 13, 45, 30,
DateTimeKind.Utc);
Console.WriteLine("{0} ({1}) --> {0:O}", uDat, uDat.Kind);


DateTime lDat = new DateTime(2009, 6, 15, 13, 45, 30,
DateTimeKind.Local);
Console.WriteLine("{0} ({1}) --> {0:O}\n", lDat, lDat.Kind);


DateTimeOffset dto = new DateTimeOffset(lDat);
Console.WriteLine("{0} --> {0:O}", dto);
}
}
// The example displays the following output:
//    6/15/2009 1:45:30 PM (Unspecified) --> 2009-06-15T13:45:30.0000000
//    6/15/2009 1:45:30 PM (Utc) --> 2009-06-15T13:45:30.0000000Z
//    6/15/2009 1:45:30 PM (Local) --> 2009-06-15T13:45:30.0000000-07:00
//
//    6/15/2009 1:45:30 PM -07:00 --> 2009-06-15T13:45:30.0000000-07:00

Some people have pointed out that ‘ToUniversalTime’ is somewhat unsafe in that it can cause unintended incorrect time dispalys. Expanding on that I’m providing a more detailed example of a solution. The sample here creates an extension to the DateTime object that safely returns a UTC DateTime where you can use ToString as desired….

class Program
{
static void Main(string[] args)
{
DateTime dUtc = new DateTime(2016, 6, 1, 3, 17, 0, 0, DateTimeKind.Utc);
DateTime dUnspecified = new DateTime(2016, 6, 1, 3, 17, 0, 0, DateTimeKind.Unspecified);


//Sample of an unintended mangle:
//Prints "2016-06-01 10:17:00Z"
Console.WriteLine(dUnspecified.ToUniversalTime().ToString("u"));


//Prints "2016 - 06 - 01 03:17:00Z"
Console.WriteLine(dUtc.SafeUniversal().ToString("u"));


//Prints "2016 - 06 - 01 03:17:00Z"
Console.WriteLine(dUnspecified.SafeUniversal().ToString("u"));
}
}


public static class ConvertExtensions
{
public static DateTime SafeUniversal(this DateTime inTime)
{
return (DateTimeKind.Unspecified == inTime.Kind)
? new DateTime(inTime.Ticks, DateTimeKind.Utc)
: inTime.ToUniversalTime();
}
}
string.Format("{0:yyyy-MM-ddTHH:mm:ss.FFFZ}", DateTime.UtcNow)

returns 2017-02-10T08:12:39.483Z

This code is working for me:

var datetime = new DateTime(2017, 10, 27, 14, 45, 53, 175, DateTimeKind.Local);
var text = datetime.ToString("o");
Console.WriteLine(text);
--  2017-10-27T14:45:53.1750000+03:00


// datetime from string
var newDate = DateTime.ParseExact(text, "o", null);

If you don't mind using Newtonsoft.Json:

string result = JsonConvert.SerializeObject(DateTime.UtcNow, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
});