【问题标题】:How to create .NET CultureInfo with Dateformat ISO 8601?如何使用 Dateformat ISO 8601 创建 .NET CultureInfo?
【发布时间】:2017-11-06 23:48:41
【问题描述】:

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

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

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

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

【问题讨论】:

  • 我想用空格来制作格式,你做了类似c = new CultureInfo("en-US") { DateTimeFormat = { ShortDatePattern = "yyyy-MM-dd", LongTimePattern = "HH:mm:ss.FFFK" } }

标签: c# datetime string-formatting cultureinfo


【解决方案1】:

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

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

【讨论】:

  • 谢谢!无论如何我都不会这样做,因为我觉得使用它不舒服。如果有人感兴趣:上面的字段是一个内部“缓存”,用于永远不会修改的日期时间格式。 referencesource.microsoft.com/#mscorlib/system/globalization/…
  • 是的,我建议永远不要这样做。只需使用带有正确格式规范的ToString。像这样隐藏它可能不是最好的主意。也许在紧要关头有一个hacky解决方法,但尽量避免它。 :)
【解决方案2】:

Scott Hanselmann 已在博客 here.

一点反射告诉我们 System.DateTime 的默认格式字符串是“G”,如 System.DateTime.ToString("G") 其中 G 是预设之一。

[...]

并得到他期望的输出,表明“G”是ShortDateLongTime组合

所以你应该覆盖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();

不过,Scott 将他的帖子命名为 Enabling Evil 是有原因的。做之前三思而后行!

T 不需要,也不能提供。如果你还需要它,你需要使用反射,如Matt answered

【讨论】:

    猜你喜欢
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    相关资源
    最近更新 更多