在.net Framework中,有一个比较重要的概念就是日期和时间格式化字符串。我们可以通过这个格式化字符串将DateTime类型转换成我们想要的格式。还记得上个暑假里,一个可以说是我师傅的学长,在自己写的一个监控软件里写错了格式化字符串,导致最后记录文件名的日期是12小时制的,在实际运行中,下午的记录文件会把上午的记录文件全部覆盖掉,被我嘲讽了许久。
标准日期和时间格式化字符串
首先是微软官方对标准日期和时间格式化字符串的解释和定义:
摘自:https://msdn.microsoft.com/zh-cn/library/az4se3k1%28v=vs.110%29.aspx
下表描述了标准日期和时间格式说明符。除非另行说明,否则,特定的标准日期和时间格式说明符将产生相同的字符串表示形式,这与它是与 DateTime 值还是 DateTimeOffset 值一起使用无关。
格式说明符 | 描述 | 示例 |
"d" | 短日期模式。 | 2009-06-15T13:45:30 -> 6/15/2009 (en-US)
2009-06-15T13:45:30 -> 15/06/2009 (fr-FR) 2009-06-15T13:45:30 -> 2009/06/15 (ja-JP) |
“D” | 长日期模式。 | 2009-06-15T13:45:30 -> Monday, June 15, 2009 (en-US)
2009-06-15T13:45:30 -> 15 июня 2009 г.(ru-RU) 2009-06-15T13:45:30 -> Montag, 15.Juni 2009 (de-DE) |
“f” | 完整日期/时间模式(短时间)。 | 2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45 PM (en-US)
2009-06-15T13:45:30 -> den 15 juni 2009 13:45 (sv-SE) 2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 1:45 μμ (el-GR) |
“F” | 完整日期/时间模式(长时间)。 | 2009-06-15T13:45:30 -> Monday, June 15, 2009 1:45:30 PM (zh-CN)
2009-06-15T13:45:30 -> den 15 juni 2009 13:45:30 (sv-SE) 2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 1:45:30 μμ (el-GR) |
“g” | 常规日期/时间模式(短时间)。 | 2009-06-15T13:45:30 -> 6/15/2009 1:45 PM (en-US)
2009-06-15T13:45:30 -> 15/06/2009 13:45 (es-ES) 2009-06-15T13:45:30 -> 2009/6/15 13:45 (zh-CN) |
“G” | 常规日期/时间模式(长时间)。 | 2009-06-15T13:45:30 -> 6/15/2009 1:45:30 PM (en-US)
2009-06-15T13:45:30 -> 15/06/2009 13:45:30 (es-ES) 2009-06-15T13:45:30 -> 2009/6/15 13:45:30 (zh-CN) |
“M”、“m” | 月/日模式。 | 2009-06-15T13:45:30 -> June 15 (en-US)
2009-06-15T13:45:30 -> 15.juni (da-DK) 2009-06-15T13:45:30 -> 15 Juni (id-ID) |
“O”、“o” | 往返日期/时间模式。 | DateTime 值:
2009-06-15T13:45:30 (DateTimeKind.Local) --> 2009-06-15T13:45:30.0000000-07:00 2009-06-15T13:45:30 (DateTimeKind.Utc) --> 2009-06-15T13:45:30.0000000Z 2009-06-15T13:45:30 (DateTimeKind.Unspecified) --> 2009-06-15T13:45:30.0000000 DateTimeOffset 值: 2009-06-15T13:45:30-07:00 --> 2009-06-15T13:45:30.0000000-07:00 |
“R”、“r” | RFC1123 模式。 | 2009-06-15T13:45:30 -> Mon, 15 Jun 2009 20:45:30 GMT |
“s” | 可排序日期/时间模式。 | 2009-06-15T13:45:30 (DateTimeKind.Local) -> 2009-06-15T13:45:30
2009-06-15T13:45:30 (DateTimeKind.Utc) -> 2009-06-15T13:45:30 |
“t” | 短时间模式。 | 2009-06-15T13:45:30 -> 1:45 PM (en-US)
2009-06-15T13:45:30 -> 13:45 (hr-HR) 2009-06-15T13:45:30 -> 01:45 م (ar-EG) |
“T” | 长时间模式。 | 2009-06-15T13:45:30 -> 1:45:30 PM (en-US)
2009-06-15T13:45:30 -> 13:45:30 (hr-HR) 2009-06-15T13:45:30 -> 01:45:30 م (ar-EG) |
“u” | 通用可排序日期/时间模式。 | 2009-06-15T13:45:30 -> 2009-06-15 20:45:30Z |
“U” | 通用完整日期/时间模式。 | 2009-06-15T13:45:30 -> Monday, June 15, 2009 8:45:30 PM (en-US)
2009-06-15T13:45:30 -> den 15 juni 2009 20:45:30 (sv-SE) 2009-06-15T13:45:30 -> Δευτέρα, 15 Ιουνίου 2009 8:45:30 μμ (el-GR) |
“Y”、“y” | 年月模式。 | 2009-06-15T13:45:30 -> June, 2009 (en-US)
2009-06-15T13:45:30 -> juni 2009 (da-DK) 2009-06-15T13:45:30 -> Juni 2009 (id-ID) |
任何其他单个字符 | 未知说明符。 | 引发运行时 FormatException。 |
标准格式字符串的工作原理
在格式设置操作中,标准格式字符串只是自定义格式字符串的别名。使用别名引用自定义格式字符串的优点是:尽管别名保持固定不变,自定义格式字符串自身也可以变化。这很重要,因为日期和时间值的字符串表示形式通常会因区域性而异。例如,“d”标准格式字符串指示应使用短日期模式显示日期和时间值。对于固定区域性,此模式为“MM/dd/yyyy”。对于 fr-FR 区域性,此模式为“dd/MM/yyyy”。对于 ja-JP 区域性,此模式为“yyyy/MM/dd”。
如果格式设置操作中的标准格式字符串映射到某个特定区域性的自定义格式字符串,则应用程序可定义该特定区域性,并通过以下方式之一使用其自定义格式字符串:
自定义模式日期和时间格式化字符串
上面的格式化字符串并不齐全,很多时候我们会碰上一些奇怪的需求,微软官方提供的帮助文档里并没有,但这并不代表不能实现,其实还有一些自定义模式格式化字符串可以用于格式化日期时间。这些自定义模式格式化字符串还可以相互自由组合来实现日期时间的格式化,非常的方便。
注:表格中的例子结果会随着不同的系统版本、区域语言、.net Framework版本而随之变动,故仅供参考。本例中我是用的系统是Windows 7 Service Pack 1 x64 + 中文(简体,中国) + .net Framework 4.0,测试时使用时间为2016年2月12日 15:16:17
格式模式 |
说明 | DateTime.Now.ToString(“格式模式”) |
d | 月中的某一天。一位数的日期没有前导零。【注意:不能单独使用,因为会和微软官方定义中的短日期模式相冲突】 | 12 |
dd | 月中的某一天。一位数的日期有一个前导零。 | 12 |
ddd | 周中某天的缩写名称,在 AbbreviatedDayNames 中定义。 | 周五 |
dddd | 周中某天的完整名称,在 DayNames 中定义。 | 星期五 |
M | 月份数字。一位数的月份没有前导零。【注意:不能单独使用,因为会和微软官方定义中的月/日模式相冲突】
|
2 |
MM | 月份数字。一位数的月份有一个前导零。 | 02 |
MMM | 月份的缩写名称,在 AbbreviatedMonthNames 中定义。 | 二月 |
MMMM | 月份的完整名称,在 MonthNames 中定义。 | 二月【中文中这里没什么区别,如果是英语解会有区别,英语中,“MMM”会输出“Feb.”,“MMMM”会输出“February”】 |
y | 不包含纪元的年份。如果不包含纪元的年份小于 10,则显示不具有前导零的年份。【注意:不能单独使用,因为会和微软官方定义中的年月模式相冲突】 | 16 |
yy | 不包含纪元的年份。如果不包含纪元的年份小于 10,则显示具有前导零的年份。 | 16 |
yyyy | 包括纪元的四位数的年份。 | 2016 |
gg | 时期或纪元。如果要设置格式的日期不具有关联的时期或纪元字符串,则忽略该模式。 | 公元 |
h | 12 小时制的小时。一位数的小时数没有前导零。【注意:不能单独使用,因为会和微软官方定义中的任何其他单个字符相冲突,从而引发System.FormatException异常】 | 3 |
hh | 12 小时制的小时。一位数的小时数有前导零。 | 03 |
H | 24 小时制的小时。一位数的小时数没有前导零。。【注意:不能单独使用,因为会和微软官方定义中的任何其他单个字符相冲突,从而引发System.FormatException异常】 | 15 |
HH | 24 小时制的小时。一位数的小时数有前导零。 | 15 |
m | 分钟。一位数的分钟数没有前导零。【注意:不能单独使用,因为会和微软官方定义中的月/日模式相冲突】 | 16 |
mm | 分钟。一位数的分钟数有一个前导零。 | 16 |
s | 秒。一位数的秒数没有前导零。【注意:不能单独使用,因为会和微软官方定义中的可排序日期/时间模式相冲突】 | 17 |
ss | 秒。一位数的秒数有一个前导零。 | 17 |
f | 秒的小数精度为一位。其余数字被截断。【注意:不能单独使用,因为会和微软官方定义中的完整日期/时间模式(短时间)相冲突】 | 0 |
ff | 秒的小数精度为两位。其余数字被截断。 | 00 |
fff | 秒的小数精度为三位。其余数字被截断。 | 000 |
ffff | 秒的小数精度为四位。其余数字被截断。 | 0000 |
fffff | 秒的小数精度为五位。其余数字被截断。 | 00000 |
ffffff | 秒的小数精度为六位。其余数字被截断。 | 000000 |
fffffff | 秒的小数精度为七位。其余数字被截断。 | 0000000 |
t | 在 AMDesignator 或 PMDesignator 中定义的 AM/PM 指示项的第一个字符(如果存在)。【注意:不能单独使用,因为会和微软官方定义中的短时间模式相冲突】 | 下 |
tt | 在 AMDesignator 或 PMDesignator 中定义的 AM/PM 指示项(如果存在)。 | 下午 |
z | 时区偏移量(“+”或“-”后面仅跟小时)。一位数的小时数没有前导零。例如,太平洋标准时间是“-8”。【注意:不能单独使用,因为会和微软官方定义中的任何其他单个字符相冲突,从而引发System.FormatException异常】 | +8 |
zz | 时区偏移量(“+”或“-”后面仅跟小时)。一位数的小时数有前导零。例如,太平洋标准时间是“-08”。 | +08 |
zzz | 完整时区偏移量(“+”或“-”后面跟有小时和分钟)。一位数的小时数和分钟数有前导零。例如,太平洋标准时间是“-08:00”。 | +08:00 |
: | 在 TimeSeparator 中定义的默认时间分隔符。 | - |
/ | 在 DateSeparator 中定义的默认日期分隔符。 | - |
%c | 其中 c 是格式模式(如果单独使用)。如果格式模式与原义字符或其他格式模式合并,则可以省略“%”字符。 | - |
\c | 其中 c 是任意字符。照原义显示字符。若要显示反斜杠字符,请使用“\\”。 |
- |
由上表中我红色的注释可以看出,自定义模式格式化字符串必须要有两个字符及以上,单独的一个字符会被认为是标准格式化字符串。
下面我举几个例子
例如:
初始化DateTime类型dt:
DateTime dt = DateTime.Parse("2016/2/12 15:16:17");
1.将dt转为“2016年02月12日 15时16分17秒”
解:
string result = dt.ToString("yyyy年MM月dd日 HH时mm分ss秒");
2.将dt转为“2016年02月12日 03时16分17秒 下午”
解:
string result = dt.ToString("yyyy年MM月dd日 hh时mm分ss秒 tt");
3.将dt转为“2”(月份)
解:
string result = dt.ToString("%M");
小柊
2016年2月12日 15:45:23
1 条评论发布于 “.net 日期和时间格式字符串”