如何确保 NodaTime 对象始终获得 'stringified' ISO 格式?

How can I ensure NodaTime objects always get 'stringified' to ISO formats?

当我们使用NodaTime对象时,很容易弄错格式。 例如,我们使用字符串插值来构造 uri,但我们确实想要 yyyy-MM-dd 格式。日志记录也是如此,我们真的不想要任何其他格式。

LocalDate date = new LocalDate(2020, 8, 10);
string toString = $"{date}"; // "den 10 augusti 2020"
logger.LogInformation("Date: {Date}", date); // "Date: Monday, 10 August 2020"

ToString(用于上面第二行)的文档指出:
“默认格式模式(“D”)中的当前实例的值,使用 当前线程的文化以获取格式提供程序。"

如果我将当前区域性更改为 InvariantCulture,我现在让以上两行都显示“2020 年 8 月 10 日,星期一”,这样更好,因为它们是一致的,但 yyyy-MM-dd 格式也不一致。

System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;

理想情况下,我只想自定义 NodaTime 对象的“字符串化”方式,以避免改变文化的任何其他不良副作用。到这里有什么帮助还是我卡住了?

编辑:

我制作了一个控制台应用程序以包含一个最小的可重现示例

Console.WriteLine(new LocalDate(2020,8,13));
Console.WriteLine(ZonedDateTime.FromDateTimeOffset(DateTimeOffset.Now));
Console.WriteLine(DateTime.Now);
Console.WriteLine(DateTimeOffset.Now);

然后我得到了以下输出:

den 13 augusti 2020
2020-08-13T08:39:16 UTC+02 (+02)
2020-08-13 08:39:16
2020-08-13 08:39:16 +02:00

我希望 LocalDate 的默认输出为 2020-08-13,这在日志和字符串插值中更有用,例如:var uri = $"api/orders?date={localDate}"

实现此目的的最简单方法是使用默认为 ISO-8601 格式的 CultureInfo。从不变文化开始,创建它相当容易:

using NodaTime;
using System;
using System.Globalization;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        var isoCulture = (CultureInfo) CultureInfo.InvariantCulture.Clone();
        var format = isoCulture.DateTimeFormat;
        format.ShortDatePattern = "yyyy-MM-dd";
        format.ShortTimePattern = "HH:mm:ss";
        format.LongTimePattern = "HH:mm:ss.FFFFFFF";
        format.FullDateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.FFFFFFF";
        format.LongDatePattern = format.ShortDatePattern;

        Thread.CurrentThread.CurrentCulture = isoCulture;
        Console.WriteLine(new LocalDate(2020, 8, 13));
        Console.WriteLine(ZonedDateTime.FromDateTimeOffset(DateTimeOffset.Now));
        Console.WriteLine(DateTime.Now);
        Console.WriteLine(DateTimeOffset.Now);
    }
}

输出:

2020-08-13
2020-08-13T09:52:18 UTC+01 (+01)
2020-08-13 09:52:18.7351962
2020-08-13 09:52:18.7356716 +01:00

我相信 .NET 在格式化 DateTime 时只是使用“日期模式”{space}“时间模式”,所以我 认为 有一种方法可以在其中获取 T。但是,嘿,LocalDate 输出就是你想要的:)