如何确保 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
输出就是你想要的:)
当我们使用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
输出就是你想要的:)