如何使用Dateformat ISO 8601创建.NET CultureInfo?

时间:2017-11-06 23:48:42

标签: c# datetime string-formatting cultureinfo

是否可以让.NET创建以下输出?

DateTime.UtcNow.ToString() --> "2017-11-07T00:40:00.123456Z"

当然总是有可能使用ToString(“s”)或ToString(“yyyy-MM-ddTHH:mm:ss.fffffffK”)。但有没有办法将无参数ToString-Method的默认行为调整为所需的输出?

我尝试更改CurrentCulture。但我得到的最好的是“2017-11-07 00:40:00.123456Z”。我没有找到一种方法来更改从空格到“T”的日期和时间之间的分隔符。

2 个答案:

答案 0 :(得分:4)

这是可能的,但只能通过反射访问内部字段,但不能保证在所有情况下都能正常工作。

var culture = (CultureInfo) CultureInfo.InvariantCulture.Clone();
var field = typeof(DateTimeFormatInfo).GetField("generalLongTimePattern",
                                           BindingFlags.NonPublic | BindingFlags.Instance);
if (field != null)
{
    // we found the internal field, set it
    field.SetValue(culture.DateTimeFormat, "yyyy-MM-dd'T'HH:mm:ss.FFFFFFFK");
}
else
{
    // fallback to setting the separate date and time patterns
    culture.DateTimeFormat.ShortDatePattern = "yyyy-MM-dd";
    culture.DateTimeFormat.LongTimePattern = "HH:mm:ss.FFFFFFFK";
}
CultureInfo.CurrentCulture = culture;

Console.WriteLine(DateTime.UtcNow);  // "2017-11-07T00:53:36.6922843Z"

请注意,ISO 8601规范 允许使用空格而不是T。使用T 只是首选

答案 1 :(得分:1)

Scott Hanselmann在博客上发表了here

  

一点Reflectoring向我们显示System.DateTime的默认格式字符串是System.DateTime.ToString(“G”)中的“G”,其中G是预设之一。

     

[...]

     

获得他期望的输出,表明“G”是 ShortDate 组合 LongTime

因此,您应该覆盖ShortDatePatternLongTimePattern

我将代码转换为C#,是的,它正在运行:

var customCulture = new CultureInfo("en-US")
{
    DateTimeFormat =
    {
        ShortDatePattern = "yyyy-MM-dd",
        LongTimePattern = "HH:mm:ss.FFFFFFFK"
    }
};

Console.WriteLine(DateTime.Now);

System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;
System.Threading.Thread.CurrentThread.CurrentUICulture = customCulture;
Console.WriteLine(DateTime.Now);

Console.ReadLine();

然而,斯科特将其帖子命名为 Enabling Evil 。这样做之前要三思而后行!

不需要T,但也无法提供。如果您仍然需要它,则需要使用Reflection,Matt answered