考虑到:

DateTime.UtcNow

我如何获得一个字符串,它表示在ISO 8601兼容的格式相同的值?

请注意,ISO 8601定义了许多类似的格式。我想要的具体格式是:

yyyy-MM-ddTHH:mm:ssZ

当前回答

使用Newtonsoft。Json,你可以这样做

JsonConvert.SerializeObject(DateTime.UtcNow)

例如:https://dotnetfiddle.net/O2xFSl

其他回答

Use:

private void TimeFormats()
{
    DateTime localTime = DateTime.Now;
    DateTime utcTime = DateTime.UtcNow;
    DateTimeOffset localTimeAndOffset = new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime));

    //UTC
    string strUtcTime_o = utcTime.ToString("o");
    string strUtcTime_s = utcTime.ToString("s");
    string strUtcTime_custom = utcTime.ToString("yyyy-MM-ddTHH:mm:ssK");

    //Local
    string strLocalTimeAndOffset_o = localTimeAndOffset.ToString("o");
    string strLocalTimeAndOffset_s = localTimeAndOffset.ToString("s");
    string strLocalTimeAndOffset_custom = utcTime.ToString("yyyy-MM-ddTHH:mm:ssK");

    //Output
    Response.Write("<br/>UTC<br/>");
    Response.Write("strUtcTime_o: " + strUtcTime_o + "<br/>");
    Response.Write("strUtcTime_s: " + strUtcTime_s + "<br/>");
    Response.Write("strUtcTime_custom: " + strUtcTime_custom + "<br/>");

    Response.Write("<br/>Local Time<br/>");
    Response.Write("strLocalTimeAndOffset_o: " + strLocalTimeAndOffset_o + "<br/>");
    Response.Write("strLocalTimeAndOffset_s: " + strLocalTimeAndOffset_s + "<br/>");
    Response.Write("strLocalTimeAndOffset_custom: " + strLocalTimeAndOffset_custom + "<br/>");

}

输出

UTC
    strUtcTime_o: 2012-09-17T22:02:51.4021600Z
    strUtcTime_s: 2012-09-17T22:02:51
    strUtcTime_custom: 2012-09-17T22:02:51Z

Local Time
    strLocalTimeAndOffset_o: 2012-09-17T15:02:51.4021600-07:00
    strLocalTimeAndOffset_s: 2012-09-17T15:02:51
    strLocalTimeAndOffset_custom: 2012-09-17T22:02:51Z

来源:

标准日期和时间格式字符串(MSDN) 自定义日期和时间格式字符串(MSDN)

你可以用下面的代码得到“Z”(ISO 8601 UTC):

Dim tmpDate As DateTime = New DateTime(Now.Ticks, DateTimeKind.Utc)
Dim res as String = tmpDate.toString("o") '2009-06-15T13:45:30.0000000Z

原因如下:

ISO 8601有一些不同的格式:

DateTimeKind。当地的

2009-06-15T13:45:30.0000000-07:00

DateTimeKind。Utc

2009-06-15T13:45:30.0000000Z

DateTimeKind。未指明的

2009-06-15T13:45:30.0000000

.NET为我们提供了一个包含这些选项的枚举:

'2009-06-15T13:45:30.0000000-07:00
Dim strTmp1 As String = New DateTime(Now.Ticks, DateTimeKind.Local).ToString("o")

'2009-06-15T13:45:30.0000000Z
Dim strTmp2 As String = New DateTime(Now.Ticks, DateTimeKind.Utc).ToString("o")

'2009-06-15T13:45:30.0000000
Dim strTmp3 As String = New DateTime(Now.Ticks, DateTimeKind.Unspecified).ToString("o")

注意:如果你将Visual Studio 2008的“watch utility”应用到toString(“o”)部分,你可能会得到不同的结果,我不知道这是否是一个bug,但在这种情况下,如果你正在调试,使用String变量会得到更好的结果。

来源:标准日期和时间格式字符串(MSDN)

正如在其他回答中提到的,DateTime在设计上存在问题。

野田时间

我建议使用NodaTime来管理日期/时间值:

本地时间,日期,datetime 全球时间 带时区的时间 期 持续时间

格式化

因此,要创建并格式化ZonedDateTime,您可以使用以下代码片段:

var instant1 = Instant.FromUtc(2020, 06, 29, 10, 15, 22);

var utcZonedDateTime = new ZonedDateTime(instant1, DateTimeZone.Utc);
utcZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
// 2020-06-29T10:15:22Z


var instant2 = Instant.FromDateTimeUtc(new DateTime(2020, 06, 29, 10, 15, 22, DateTimeKind.Utc));

var amsterdamZonedDateTime = new ZonedDateTime(instant2, DateTimeZoneProviders.Tzdb["Europe/Amsterdam"]);
amsterdamZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
// 2020-06-29T12:15:22Z

对我来说,NodaTime代码看起来相当冗长。但是类型真的很有用。它们有助于正确处理日期/时间值。

Newtonsoft。Json

使用Newtonsoft的NodaTime。您需要添加引用到NodaTime.Serialization.JsonNet NuGet包并配置Json选项。

services
    .AddMvc()
    .AddJsonOptions(options =>
    {
        var settings=options.SerializerSettings;
        settings.DateParseHandling = DateParseHandling.None;
        settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    });

转换DateTime。UtcNow转换为yyyy-MM-ddTHH:mm:ssZ的字符串表示形式,您可以使用DateTime结构的ToString()方法与自定义格式化字符串。在使用带有DateTime的自定义格式字符串时,重要的是要记住需要使用单引号转义分隔符。

下面将返回你想要的字符串表示:

DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", DateTimeFormatInfo.InvariantInfo)

像2018-06-22T13:04:16这样的格式可以在API的URI中传递:

public static string FormatDateTime(DateTime dateTime)
{
    return dateTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
}