100

我有一个日期时间,我想将其格式化为“ 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")

任何想法如何使它工作?

4

8 回答 8

189
string foo = yourDateTime.ToUniversalTime()
                         .ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
于 2009-11-30T16:45:21.683 回答
77

为什么不直接使用往返 ("O", "o") 格式说明符

“O”或“o”标准格式说明符表示自定义日期和时间格式字符串,使用保留时区信息并发出符合 ISO 8601 的结果字符串的模式。对于 DateTime 值,此格式说明符旨在保留日期和时间值以及文本中的 DateTime.Kind 属性。如果样式参数设置为 DateTimeStyles.RoundtripKind,则可以使用 DateTime.Parse(String, IFormatProvider, DateTimeStyles) 或 DateTime.ParseExact 方法解析格式化的字符串。

"O" 或 "o" 标准格式说明符对应于 DateTime 值的 "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK" 自定义格式字符串和"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffzzz" DateTimeOffset 值的自定义格式字符串。在此字符串中,分隔单个字符的单引号对(例如连字符、冒号和字母“T”)表示单个字符是无法更改的文字。撇号不会出现在输出字符串中。

O" 或 "o" 标准格式说明符(以及 "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK" 自定义格式字符串)利用了这三种方式ISO 8601 表示时区信息以保留 DateTime 值的 Kind 属性:

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
于 2014-09-16T17:26:58.327 回答
25
string.Format("{0:yyyy-MM-ddTHH:mm:ss.FFFZ}", DateTime.UtcNow)

返回 2017-02-10T08:12:39.483Z

于 2017-02-10T08:13:40.550 回答
9

有人指出“ToUniversalTime”有点不安全,因为它可能会导致意外的不正确时间显示。在此基础上,我提供了一个更详细的解决方案示例。此处的示例为 DateTime 对象创建了一个扩展,该对象安全地返回一个 UTC DateTime,您可以在其中根据需要使用 ToString……。

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();
    }
}
于 2016-12-01T19:07:49.030 回答
6

最好使用的格式是“yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK”。

如果日期为 UTC,则字符串上的最后一个 K 将更改为“Z”,如果是本地日期,则将更改为时区 (+-hh:mm)。(http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

正如 LukeH 所说,如果您希望所有日期都是 UTC,那么使用 ToUniversalTime 是很好的选择。

最终代码是:

string foo = yourDateTime.ToUniversalTime()
                         .ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK");
于 2013-05-23T04:12:01.387 回答
6

这段代码对我有用:

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);
于 2017-10-27T12:50:16.710 回答
5

您想使用DateTimeOffset类。

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

抱歉,我错过了毫秒的原始格式

var stringDate = date.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'");
于 2009-11-30T16:45:52.417 回答
-4

试试这个:

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

以前问的问题

于 2009-11-30T16:41:57.073 回答