.NET Framework 提供了可自定义的、适于常规用途的格式化机制,可将值转换为适合显示的字符串。
例如,可以将数值格式化为十六进制、科学记数法或者由用户指定的标点符号分隔成组的一系列数字。
可以将日期和时间格式化为适合于特定的国家、地区或区域性。可以将枚举常数格式化为它的数值或名称。
您可以通过实现 IFormattable 接口来重写 .NET Framework 解释格式化字符串的方法;
通过实现 IFormatProvider 接口来提供您自己的格式提供程序;通过实现 ICustomFormatter 接口来执行您自己的格式化。
.NET Framework 提供了名为复合格式化的功能,它使用一个或多个格式字符串将一个或多个格式化值嵌入输出字符串。
输出字符串可用于进行进一步处理,显示到系统控制台或者写入到流。
分析和格式说明符
格式化将类型的值转化为字符串表示形式;分析则与格式化相反,它是从字符串表示形式创建数据类型。
格式提供程序控制如何执行分析,一些方法(例如 DateTime.ParseExact)采用格式说明符参数,可指示字符串表示形式的预期格式。
数字格式字符串
1、标准数字格式字符串
标准数字格式字符串用于格式化通用数值类型。标准格式字符串采取“Axx”形式,其中“A”为单个字母字符(被称为格式说明符),“xx”是可选的整数(被称为精度说明符)。
格式说明符必须是某个内置格式符。精度说明符的范围从 0 到 99,它控制有效位数或小数点右边零的个数。格式字符串不能包含空白。
如果格式字符串不包含某个标准格式说明符,则引发 FormatException。
C或c 货币 数字转换为表示货币金额的字符串。转换由用于格式化数字的 NumberFormatInfo 对象的货币格式信息控制。精度说明符指示所需的小数位数。如果省略精度说明符,则使用 NumberFormatInfo 给定的默认货币精度。
D或d 十进制数 只有整型才支持此格式。数字转换为十进制数字 (0-9) 的字符串,如果数字为负,则前面加负号。精度说明符指示结果字符串中所需的最少数字个数。如果需要的话,则用零填充该数字的左侧,以产生精度说明符给定的数字个数。
E或e 科学计数法(指数) 数字转换为“-d.ddd…E+ddd”或“-d.ddd…e+ddd”形式的字符串,其中每个“d”表示一个数字 (0-9)。如果该数字为负,则该字符串以减号开头。小数点前总有一个数字。精度说明符指示小数点后所需的位数。如果省略精度说明符,则使用默认值,即小数点后六位数字。格式说明符的大小写指示在指数前加前缀“E”还是“e”。指数总是由正号或负号以及最少三位数字组成。如果需要,用零填充指数以满足最少三位数字的要求。
F或f 固定点 数字转换为“-ddd.ddd…”形式的字符串,其中每个“d”表示一个数字 (0-9)。如果该数字为负,则该字符串以减号开头。精度说明符指示所需的小数位数。如果忽略精度说明符,则使用 NumberFormatInfo 给定的默认数值精度。
G或g 常规 根据数字类型以及是否存在精度说明符,数字会转换为固定点或科学记数法的最紧凑形式。如果精度说明符被省略或为零,则数字的类型决定默认精度,
N或n 数字 数字转换为“-d,ddd,ddd.ddd…”形式的字符串,其中每个“d”表示一个数字 (0-9)。如果该数字为负,则该字符串以减号开头。小数点左边每三个数字之间插入一个千位分隔符。精度说明符指示所需的小数位数。
P或p 百分比 数字转换为由 NumberFormatInfo.PercentNegativePattern 属性或 NumberFormatInfo.PercentPositivePattern 属性定义的、表示百分比的字符串。如果数字为负,则产生的字符串由 PercentNegativePattern 定义并以负号开头。已转换的数字乘以 100 以表示为百分比。精度说明符指示所需的小数位数。如果省略精度说明符,则使用 NumberFormatInfo 给定的默认数值精度。
R或r 往返过程 往返过程说明符保证转换为字符串的数值再次被分析为相同的数值。使用此说明符格式化数值时,首先使用常规格式对其进行测试:Double 使用 15 位精度,Single 使用 7 位精度。如果此值被成功地分析回相同的数值,则使用常规格式说明符对其进行格式化。但是,如果此值未被成功地分析为相同数值,则它这样格式化:Double 使用 17 位精度,Single 使用 9 位精度。虽然精度说明符可以追加到往返过程格式说明符,但它将被忽略。使用此说明符时,往返过程优先于精度。此格式仅受浮点型支持。
X或x 十六进制数 数字转换为十六进制数字的字符串。格式说明符的大小写指示对大于 9 的十六进制数字使用大写字符还是小写字符。例如,使用“X”产生“ABCDEF”,使用“x”产生“abcdef”。精度说明符指示结果字符串中所需的最少数字个数。如果需要的话,则用零填充该数字的左侧,以产生精度说明符给定的数字个数。只有整型才支持此格式。 2/
2、自定义数字格式字符串
如果标准数字格式说明符未提供所需的格式化类型,可以使用自定义格式字符串进一步增强字符串输出。标准格式字符串包含一个字母字符,后面可能会跟有数字序列(形成一个 0 到 99 的值);而所有其他格式字符串都是自定义格式字符串。
下表显示可以用于创建自定义数字格式字符串及其定义的字符。请注意,与当前线程关联的 NumberFormatInfo 对象的“区域选项”控制面板的设置会影响这些字符中的某些所产生的输出字符串。使用不同区域性的计算机将生成不同的输出字符串。
0 零占位符 如果格式化的值在格式字符串中出现“0”的位置有一个数字,则此数字被复制到输出字符串中。小数点前最左边的“0”的位置和小数点后最右边的“0”的位置确定总在输出字符串中出现的数字范围。“00”说明符使得值被舍入到小数点前最近的数字,其中零位总被舍去。例如,用“00”格式化 34.5 将得到值 35。
# 数字占位符 如果格式化的值在格式字符串中出现“#”的位置有一个数字,则此数字被复制到输出字符串中。否则,输出字符串中的此位置不存储任何值。请注意,如果“0”不是有效数字,此说明符永不显示“0”字符,即使“0”是字符串中唯一的数字。如果“0”是所显示的数字中的有效数字,则显示“0”字符。“##”格式字符串使得值被舍入到小数点前最近的数字,其中零总被舍去。例如,用“##”格式化 34.5 将得到值 35。
. 小数点 格式字符串中的第一个“.”字符确定格式化的值中的小数点分隔符的位置;任何其他“.”字符被忽略。用作小数点分隔符的实际字符由控制格式化的 NumberFormatInfo 的 NumberDecimalSeparator 属性确定。
, 千位分隔符和数字比例换算 “,”字符有两种用途。首先,如果格式字符串在小数点(如果有)左边的两个数字占位符(0 或 #)之间包含“,”字符,则输出将在小数点分隔符左边的每三个数字之间插入千位分隔符。输出字符串中用作小数点分隔符的实际字符由控制格式化的当前 NumberFormatInfo 的 NumberGroupSeparator 属性确定。
其次,如果格式字符串在紧邻小数点的左侧包含一个或多个“,”字符,则数字在格式化之前将被“,”字符数除然后乘以 1000。例如,格式字符串“0,,”将 100,000,000 简单表示为 100。使用“,”字符指示比例换算在格式化数字中不包括千位分隔符。因此,若要将数字缩小 1,000,000 倍并插入千位分隔符,应使用格式字符串“#,##0,,”。
% 百分比占位符 在格式字符串中出现“%”字符将导致数字在格式化之前乘以 100。适当的符号插入到数字本身在格式字符串中出现“%”的位置。使用的百分比字符由当前的 NumberFormatInfo 类确定。
E0 E+0 E-0 e0 e+0 e-0 科学计数法 如果“E”、“E+”、“E-”、“e”、“e+”或“e-”中的任何一个字符串出现在格式字符串中,而且后面紧跟至少一个“0”字符,则数字用科学计数法来格式化,在数字和指数之间插入“E”或“e”。跟在科学计数法指示符后面的“0”字符数确定指数输出的最小位数。“E+”和“e+”格式指示符号字符(正号或负号)应总是置于指数前面。“E”、“E-”、“e”或“e-”格式指示符号字符仅置于负指数前面。
/ 转义符 在 C# 和 C++ 中,反斜杠字符使格式字符串中的下一个字符被解释为转义序列。它与传统的格式化序列一起使用,如“/n”(换行)。在某些语言中,转义符本身用作文本时必须跟在转义符之后。否则,编译器将该字符理解为转义符。使用字符串“//”显示“/”。
"ABC" 字符串 引在单引号或双引号中的字符被原样复制到输出字符串中,而且不影响格式化。
; 部分分隔符 “;”字符用于分隔格式字符串中的正数、负数和零各部分。
其他 所有其他字符 所有其他字符以文本形式复制到输出字符串中它们出现的位置。
日期与时间格式字符串
1、标准 DateTime 格式字符串
d 短日期模式 2007-1-9
D 长日期模式 2007年1月9日
t 短时间模式 0:12
T 长时间模式 0:12:32
f 完整日期/时间模式(短时间) 2007年1月9日 0:12
F 完整日期/时间模式(长时间) 2007年1月9日 0:12:32
g 常规日期/时间模式(短时间) 2007-1-9 0:12
G 常规日期/时间模式(长时间) 2007-1-9 0:12:32
M 或 m 月日模式 1月9日
R 或 r RFC1123 模式 Tue, 09 Jan 2007 00:12:32 GMT
s 可排序的日期/时间模式;符合 ISO 8601 2007-01-09T00:12:32
u 通用的可排序日期/时间模式 2007-01-09 00:12:32Z
U 通用的可排序日期/时间模式 2007年1月8日 16:12:32
Y 或 y 年月模式 2007年1月
任何其他单个字符
2、自定义 DateTime 格式字符串
d 显示月份的当前日期,以 1 到 31 之间的一个数字表示,包括 1 和 31。如果日期只有一位数字 (1-9),则它显示为一位数字。
请注意,如果“d”格式说明符单独使用,没有其他自定义格式字符串,则它被解释为标准短日期模式格式说明符。如果“d”格式说明符与其他自定义格式说明符或者“%”字符一起传递,则它被解释为自定义格式说明符。
dd 显示月份的当前日期,以 1 到 31 之间的一个数字表示,包括 1 和 31。如果日期只有一位数字 (1-9),则将其格式化为带有前导 0 (01-09)。
ddd 显示指定的 DateTime 的日期部分缩写名称。如果未提供特定的有效格式提供程序(实现具有预期属性的 IFormatProvider 的非空对象),则使用 DateTimeFormat 的 AbbreviatedDayNames 属性及其与当前所使用线程关联的当前区域性。否则,使用来自指定格式提供程序的 AbbreviatedDayNames 属性。
dddd(外加任意数量的附加“d”字符) 显示指定的 DateTime 的日期全名。如果未提供特定的有效格式提供程序(一个非空对象,可实现具有预期属性的 IFormatProvider),则使用 DateTimeFormat 的 DayNames 属性及其与当前所使用线程关联的当前区域性。否则,使用来自指定格式提供程序的 DayNames 属性。
f 显示秒部分的最高有效位。请注意,如果“f”格式说明符单独使用,没有其他自定义格式字符串,则它被解释为完整的(长日期 + 短时间)格式说明符。如果“f”格式说明符与其他自定义格式说明符或“%”字符一起传递,则它被解释为自定义格式说明符。
使用 System.DateTime.ParseExact 方法进行分析时,所使用的“f”格式说明符的位数指示要分析的秒部分的最高有效位的位数。
ff 显示秒部分的两个最高有效位。
fff 显示秒部分的三个最高有效位。
ffff 显示秒部分的四个最高有效位。
fffff 显示秒部分的五个最高有效位。
ffffff 显示秒部分的六个最高有效位。
fffffff 显示秒部分的七个最高有效位。
F 显示秒部分的最高有效位。如果该位为零,则不显示任何信息。使用 System.DateTime.ParseExact(System.String,System.String,System.IFormatProvider) 方法进行分析时,所使用的“F”格式说明符的位数指示要分析的秒部分的最高有效位最大数。
FF 显示秒部分的两个最高有效位。但不显示尾随零(或两个零位)。
FFF 显示秒部分的三个最高有效位。但不显示尾随零(或三个零位)。
FFFF 显示秒部分的四个最高有效位。但不显示尾随零(或四个零位)。
FFFFF 显示秒部分的五个最高有效位。但不显示尾随零(或五个零位)。
FFFFFF 显示秒部分的六个最高有效位。但不显示尾随零(或六个零位)。
FFFFFFF 显示秒部分的七个最高有效位。但不显示尾随零(或七个零位)。
g 或 gg(外加任意数量的附加“g”字符)显示指定的 DateTime 的年代部分(例如 A.D.)。如果未提供特定的有效格式提供程序(一个非空对象,可实现具有预期属性的 IFormatProvider),则年代由与 DateTimeFormat 关联的日历及其与当前线程关联的当前区域性确定。
请注意,如果“g”格式说明符单独使用,没有其他自定义格式字符串,则它被解释为标准常规格式说明符。如果“g”格式说明符与其他自定义格式说明符或“%”字符一起传递,则它被解释为自定义格式说明符。
h 以 1 到 12 范围中的一个数字显示指定的 DateTime 的小时数,该小时数表示自午夜(显示为 12)或中午(也显示为 12)后经过的整小时数。如果单独使用这种格式,则无法区别某一小时是中午以前还是中午以后的时间。如果该小时是单个数字 (1-9),则它显示为单个数字。显示小时时不发生任何舍入。例如,DateTime 为 5:43 时返回 5。
hh, hh(外加任意数量的附加“h”字符) 以 1 到 12 范围中的一个数字显示指定的 DateTime 的小时数,该小时数表示自午夜(显示为 12)或中午(也显示为 12)后经过的整小时数。如果单独使用这种格式,则无法区别某一小时是中午以前还是中午以后的时间。如果该小时是单个数字 (1-9),则将其格式化为前面带有 0 (01-09)。
H 以 0 到 23 范围中的一个数字显示指定的 DateTime 的小时数,该小时数表示自午夜(显示为 0)后经过的整小时数。如果该小时是单个数字 (0-9),则它显示为单个数字。
HH, HH(外加任意数量的附加“H”字符) 以 0 到 23 范围中的一个数字显示指定的 DateTime 的小时数,该小时数表示自午夜(显示为 0)后经过的整小时数。如果该小时是单个数字 (0-9),则将其格式化为前面带有 0 (01-09)。
m 以 0 到 59 范围中的一个数字显示指定的 DateTime 的分钟数,该分钟数表示自上一小时后经过的整分钟数。如果分钟是一位数字 (0-9),则它显示为一位数字。
请注意,如果“m”格式说明符单独使用,没有其他自定义格式字符串,则它被解释为标准的月日模式格式说明符。如果“m”格式说明符与其他自定义格式说明符或“%”字符一起传递,则它被解释为自定义格式说明符。
mm, mm(外加任意数量的附加“m”字符) 以 0 到 59 范围中的一个数字显示指定的 DateTime 的分钟数,该分钟数表示自上一小时后经过的整分钟数。如果分钟是一位数字 (0-9),则将其格式化为带有前导 0 (01-09)。
M 显示月份,以 1 到 12 之间(包括 1 和 12)的一个数字表示。如果月份是一位数字 (1-9),则它显示为一位数字。
请注意,如果“M”格式说明符单独使用,没有其他自定义格式字符串,则它被解释为标准的月日模式格式说明符。如果“M”格式说明符与其他自定义格式说明符或“%”字符一起传递,则它被解释为自定义格式说明符。
MM 显示月份,以 1 到 12 之间(包括 1 和 12)的一个数字表示。如果月份是一位数字 (1-9),则将其格式化为带有前导 0 (01-09)。
MMM 显示指定的 DateTime 的月部分缩写名称。如果未提供特定的有效格式提供程序(一个非空对象,可实现具有预期属性的 IFormatProvider),则使用 DateTimeFormat 的 AbbreviatedMonthNames 属性及其与当前线程关联的当前区域性。否则,使用来自指定格式提供程序的 AbbreviatedMonthNames 属性。
MMMM 显示指定的 DateTime 的月的全名。如果未提供特定的有效格式提供程序(一个非空对象,可实现具有预期属性的 IFormatProvider),则使用 DateTimeFormat 的 MonthNames 属性及其与当前线程关联的当前区域性。否则,使用来自指定格式提供程序的 MonthNames 属性。
s 以 0 到 59 范围中的一个数字显示指定的 DateTime 的秒数,该秒数表示自上一分钟后经过的整秒数。如果秒是一位数字 (0-9),则它仅显示为一位数字。
请注意,如果“s”格式说明符单独使用,没有其他自定义格式字符串,则它被解释为标准的可排序日期/时间模式格式说明符。如果“s”格式说明符与其他自定义格式说明符或“%”字符一起传递,则它被解释为自定义格式说明符。
ss, ss(外加任意数量的附加“s”字符)以 0 到 59 范围中的一个数字显示指定的 DateTime 的秒数,该秒数表示自上一分钟后经过的整秒数。如果秒是一位数字 (0-9),则将其格式化为带有前导 0 (01-09)。
t 显示指定的 DateTime 的 A.M./P.M. 指示项的第一个字符。如果未提供特定的有效格式提供程序(一个非空对象,可实现具有预期属性的 IFormatProvider),则使用 DateTimeFormat 的 AMDesignator(或 PMDesignator)属性及其与当前线程关联的当前区域性。否则,使用来自指定 IFormatProvider 的 AMDesignator(或 PMDesignator)属性。如果对于指定的 DateTime 所经过的总整小时数小于 12,则使用 AMDesignator。否则,使用 PMDesignator。
请注意,如果“t”格式说明符单独使用,没有其他自定义格式字符串,则它被解释为标准的长时间模式格式说明符。如果“t”格式说明符与其他自定义格式说明符或“%”字符一起传递,则它被解释为自定义格式说明符。
tt, tt(外加任意数量的附加“t”字符)显示指定的 DateTime 的 A.M./P.M. 指示项。如果未提供特定的有效格式提供程序(一个非空对象,可实现具有预期属性的 IFormatProvider),则使用 DateTimeFormat 的 AMDesignator(或 PMDesignator)属性及其与当前线程关联的当前区域性。否则,使用来自指定 IFormatProvider 的 AMDesignator(或 PMDesignator)属性。如果对于指定的 DateTime 所经过的总整小时数小于 12,则使用 AMDesignator。否则,使用 PMDesignator。
y 最多用两位数字显示指定的 DateTime 的年份。忽略年的前两位数字。如果年份是一位数字 (1-9),则它显示为一位数字。
请注意,如果“y”格式说明符单独使用,没有其他自定义格式字符串,则它被解释为标准短日期模式格式说明符。如果“y”格式说明符与其他自定义格式说明符或“%”字符一起传递,则它被解释为自定义格式说明符。
yy 最多用两位数字显示指定的 DateTime 的年份。忽略年的前两位数字。如果年份是一位数字 (1-9),则将其格式化为带有前导 0 (01-09)。
yyyy 显示指定的 DateTime 的年份部分(包括纪元)。如果年份长度小于四位,则按需要在前面追加零以使显示的年份长度达到四位。
z 仅以整小时数为单位显示系统当前时区的时区偏移量。偏移量总显示为带有前导符号(零显示为“+0”),指示早于格林威治时间 (+) 或迟于格林威治时间 (-) 的小时数。值的范围是 -12 到 +13。如果偏移量为一位数 (0-9),则将其显示为带有合适前导符号的一位数。时区设置以 +X 或 –X 的形式指定,其中 X 是相对于 GMT 的小时偏差。显示的偏差受夏时制的影响。
zz 仅以整小时数为单位显示系统当前时区的时区偏移量。偏移量总显示为带有前导或尾随符号(零显示为“+00”),指示早于格林威治时间 (+) 或迟于格林威治时间 (-) 的小时数。值范围为 -12 到 +13。如果偏移量为一位数 (0-9),则将其格式化为前面带有 0 (01-09) 并带有适当的前导符号。时区设置以 +X 或 –X 的形式指定,其中 X 是相对于 GMT 的小时偏差。显示的偏差受夏时制的影响。
zzz, zzz(外加任意数量的附加“z”字符) 以小时和分钟为单位显示系统当前时区的时区偏移量。偏移量总是显示为带有前导或尾随符号(零显示为“+00:00”),指示早于格林威治时间 (+) 或迟于格林威治时间 (-) 的小时数。值范围为 -12:00 到 +13:00。如果偏移量为一位数 (0-9),则将其格式化为前面带有 0 (01-09) 并带有适当的前导符号。时区设置以 +X 或 –X 的形式指定,其中 X 是相对于 GMT 的小时偏差。显示的偏差受夏时制的影响。
: 时间分隔符。
/ 日期分隔符。
" 带引号的字符串。显示转义符 (/) 之后两个引号之间的任何字符串的文本值。
' 带引号的字符串。显示两个“'”字符之间的任何字符串的文本值。
%c 其中 c 既是标准格式说明符又是自定义格式说明符,显示与格式说明符关联的自定义格式模式。
请注意,如果格式说明符作为单个字符来单独使用,它将被解释成标准格式说明符。只有包含两个或更多字符的格式说明符被解释为自定义格式说明符。说明符可以被同时定义为标准和自定义格式说明符,要显示此种说明符的自定义格式,请在说明符之前加“%”符号。
/c 其中 c 是任意字符,转义符将下一个字符显示为文本。在此上下文中,转义符不能用于创建转义序列(如“/n”表示换行)。
任何其他字符 其他字符作为文本直接写入输出字符串。
枚举格式字符串
G 或 g 如有可能,将枚举项显示为字符串值,否则显示当前实例的整数值。如果枚举定义中设置了 Flags 属性,则串联每个有效项的字符串值并将各值用逗号分开。如果未设置 Flags 属性,则将无效值显示为数字项。
F 或 f 如有可能,将枚举项显示为字符串值。如果值可以完全显示为枚举项的总和(即使未提供 Flags 属性),则串联每个有效项的字符串值并将各值用逗号分开。如果值不能完全由枚举项确定,则将值格式化为整数值。
D 或 d 以尽可能短的表示形式将枚举项显示为整数值。
X 或 x 将枚举项显示为十六进制值。按需要将值表示为带有前导零,以确保值的长度最少有八位。