使用模板和模式设置日期和时间格式

使用 Windows.Globalization.DateTimeFormatting 命名空间中的类,自定义模板和模式,按照你希望的格式显示日期和时间。

介绍

DateTimeFormatter 类提供了各种方法来正确设置世界各地的语言和区域的日期和时间的格式。 可以对年、月、日等使用标准格式。 或者,可以将格式模板传递给 DateTimeFormatter 构造函数的 formatTemplate 参数,例如“longdate”或“month day”。

但是,如果希望更好地控制要显示的 DateTime 对象的组件的顺序和格式,可以将格式模式传递给构造函数的 formatTemplate 参数。 格式模式使用特殊语法,使你能够获取 DateTime 对象的单个组件(仅获取月份名称或仅年份值),以便以所选的任何自定义格式显示它们。 此外,该模式可以本地化以适应其他语言和区域。

注意 这只是格式模式的概述。 有关格式模板和格式模式的更完整讨论,请参阅 DateTimeFormatter 类的“备注”部分。

格式模板和格式模式之间的差异

格式模板是与区域性无关的格式字符串。 因此,如果使用格式模板构造 DateTimeFormatter ,则格式化程序会按当前语言的正确顺序显示格式组件。 相反,格式模式特定于文化。 如果使用格式模式构造 DateTimeFormatter,格式化程序将使用完全相同的模式。 因此,模式不一定跨文化有效。

让我们用一个示例来说明这一区别。 我们将简单的格式模板(而不是模式)传递给 DateTimeFormatter 构造函数。 这是格式模板“月 日”。

var dateFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("month day");

这会基于当前上下文的语言和区域值创建格式化程序。 格式模板中的组件顺序并不重要;格式化程序按当前语言的正确顺序显示它们。 因此,它将英语(美国)显示为“January 1”,法语(法国)为“1 janvier”,日语为“1月1日”。

另一方面,格式模式特定于文化。 让我们访问格式模板的格式模式。

IReadOnlyList<string> monthDayPatterns = dateFormatter.Patterns;

这会产生不同的结果,具体取决于运行时语言和区域。 不同的区域可能以不同的顺序使用不同的组件,使用时有或没有附加字符和间距。

En-US: "{month.full} {day.integer}"
Fr-FR: "{day.integer} {month.full}"
Ja-JP: "{month.integer}月{day.integer}日"

在上面的示例中,我们输入了与文化无关的格式字符串,并得到了一个特定于文化的格式字符串(这是基于调用 dateFormatter.Patterns时有效的语言和区域的结果)。 因此,如果从文化特定的格式模式构造一个 DateTimeFormatter,那么它仅对特定语言/区域有效。

var dateFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("{month.full} {day.integer}");

上面的格式化程序为括号内的各个组件 {}返回文化特定的值。 但是,采用格式模式的组件顺序是固定的。 你确切地得到了你要求的东西,但在文化上可能合适,也可能不合适。 此格式化程序对英语(美国)有效,但不适用于法语(法国)和日语。

En-US: January 1
Fr-FR: janvier 1 (inappropriate for France; non-standard order)
Ja-JP: 1月1 (inappropriate for Japan; the day symbol 日 is missing)

此外,目前正确的模式将来可能不正确。 国家或地区可能会更改其日历系统,从而更改格式模板。 Windows 根据格式模板更新格式化器的输出,以适应这些更改。 因此,应仅在其中一个或多个条件下使用模式语法。

  • 你不依赖于某种输出格式。
  • 您的格式不必遵循特定的文化标准。
  • 你特别想让这种模式在不同文化中保持一致。
  • 你打算对实际格式模式字符串本身进行本地化。

下面是格式模板和格式模式之间的区别摘要。

格式模板,如“月日”

  • DateTime 格式的抽象表示形式,格式包括月份、日等的值(按任意顺序)。
  • 保证跨 Windows 支持的所有语言区域值返回有效的标准格式。
  • 确保为特定语言区域提供文化适宜的格式化字符串。
  • 并非所有组件组合都有效。 例如,“dayofweek day”是无效的。

格式模式,如“{month.full} {day.integer}”

  • 按照显式顺序的字符串,其内容为完整月份名称,后跟空格,再接日期整数,依此顺序,或按照您指定的任何特定格式模式。
  • 可能不符合任何语言区域配对的有效标准格式。
  • 不保证在文化上适当。
  • 可以按任意顺序指定组件的任意组合。

例子

假设你想要以特定格式显示当前月份和日期以及当前时间。 例如,你希望美国英语用户看到如下所示的内容:

June 25 | 1:38 PM

日期部分对应于“月日”格式模板,时间部分对应于“小时分钟”格式模板。 因此,可以为相关的日期和时间格式模板构造格式化程序,然后使用可本地化的格式字符串将其输出连接在一起。

var dateToFormat = System.DateTime.Now;
var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();

var dateFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("month day");
var timeFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("hour minute");

var date = dateFormatter.Format(dateToFormat);
var time = timeFormatter.Format(dateToFormat);

string output = string.Format(resourceLoader.GetString("CustomDateTimeFormatString"), date, time);

CustomDateTimeFormatString 是引用资源文件(.resw)中可本地化资源的资源标识符。 对于英语(美国)的默认语言,此值将设置为“{0} | {1}”,以及指示“{0}”“为日期的注释,”{1}“是时间。 这样,翻译人员就可以根据需要调整格式项。 例如,他们可以更改项的顺序,如果对于某些语言或地区来说在日期之前显示时间更自然的话。 或者,它们可以将“|”替换为其他分隔符。

实现此示例的另一种方法是查询两个格式化程序的格式模式,将其格式模式连接在一起,然后根据生成的格式模式构造第三个格式化程序。

var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();

var dateFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("month day");
var timeFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("hour minute");

string dateFormatterPattern = dateFormatter.Patterns[0];
string timeFormatterPattern = timeFormatter.Patterns[0];

string pattern = string.Format(resourceLoader.GetString("CustomDateTimeFormatString"), dateFormatterPattern, timeFormatterPattern);

var patternFormatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter(pattern);

string output = patternFormatter.Format(System.DateTime.Now);

重要 API