1
DateTime.Now.ToString(
"
yyyy-MM-dd
"
)
上边代码结果为:2011-08-03,其中y、M、d即为格式限定符,他们在DateTime.ToString具有限定格式意义,但在一些场合中我们希望这些字符能直接输出,即暂时取消格式限定符的作用,这就需要转义。
一、DateTime.ToString格式限定符转义
1.单个格式限定符转义
1
DateTime.Now.ToString(
"
year:yyyy
"
)
//
11ear:2011
2 DateTime.Now.ToString( @" \year:yyyy " ) // year:2011
2 DateTime.Now.ToString( @" \year:yyyy " ) // year:2011
可见,单个格式限定符转义只需在格式限定符前加"\"即可。
2.多个格式限定符转义
1
DateTime.Now.ToString(
"
date:yyyy
"
)
//
3a下e:2011
2 DateTime.Now.ToString( " 'date':yyyy " ) // year:2011
3 DateTime.Now.ToString( " \"date\":yyyy " ) // year:2011
2 DateTime.Now.ToString( " 'date':yyyy " ) // year:2011
3 DateTime.Now.ToString( " \"date\":yyyy " ) // year:2011
可见,将多个连续的字符放在单/双引号中可实现批量转义。
二、转义实现解析
使用Reflector查看DateTime.ToString方法,最终转到DateTimeFormat.FormatCustomized方法上,该方法相关代码片断如下:
1
case
'
\\
'
:
2 {
3 num4 = ParseNextChar(format, i);
4 if (num4 < 0 )
5 {
6 throw new FormatException(Environment.GetResourceString( " Format_InvalidString " ));
7 }
8 outputBuffer.Append(( char )num4);
9 num2 = 2 ;
10 continue ;
11 }
12 case ' \' ' :
13 case ' " ' :
14 {
15 StringBuilder result = new StringBuilder();
16 num2 = ParseQuoteString(format, i, result);
17 outputBuffer.Append(result);
18 continue ;
19 }
2 {
3 num4 = ParseNextChar(format, i);
4 if (num4 < 0 )
5 {
6 throw new FormatException(Environment.GetResourceString( " Format_InvalidString " ));
7 }
8 outputBuffer.Append(( char )num4);
9 num2 = 2 ;
10 continue ;
11 }
12 case ' \' ' :
13 case ' " ' :
14 {
15 StringBuilder result = new StringBuilder();
16 num2 = ParseQuoteString(format, i, result);
17 outputBuffer.Append(result);
18 continue ;
19 }
DateTimeFormat类中与上述代码相关的两个方法:
1
private
static
int
ParseNextChar(
string
format,
int
pos)
2 {
3 if (pos >= (format.Length - 1 ))
4 {
5 return - 1 ;
6 }
7 return format[pos + 1 ];
8 }
9
10 internal static int ParseQuoteString( string format, int pos, StringBuilder result)
11 {
12 int length = format.Length;
13 int num2 = pos;
14 char ch = format[pos ++ ];
15 bool flag = false ;
16 while (pos < length)
17 {
18 char ch2 = format[pos ++ ];
19 if (ch2 == ch)
20 {
21 flag = true ;
22 break ;
23 }
24 if (ch2 == ' \\ ' )
25 {
26 if (pos >= length)
27 {
28 throw new FormatException(Environment.GetResourceString( " Format_InvalidString " ));
29 }
30 result.Append(format[pos ++ ]);
31 }
32 else
33 {
34 result.Append(ch2);
35 }
36 }
37 if ( ! flag)
38 {
39 throw new FormatException( string .Format(CultureInfo.CurrentCulture, Environment.GetResourceString( " Format_BadQuote " ), new object [] { ch }));
40 }
41 return (pos - num2);
42 }
2 {
3 if (pos >= (format.Length - 1 ))
4 {
5 return - 1 ;
6 }
7 return format[pos + 1 ];
8 }
9
10 internal static int ParseQuoteString( string format, int pos, StringBuilder result)
11 {
12 int length = format.Length;
13 int num2 = pos;
14 char ch = format[pos ++ ];
15 bool flag = false ;
16 while (pos < length)
17 {
18 char ch2 = format[pos ++ ];
19 if (ch2 == ch)
20 {
21 flag = true ;
22 break ;
23 }
24 if (ch2 == ' \\ ' )
25 {
26 if (pos >= length)
27 {
28 throw new FormatException(Environment.GetResourceString( " Format_InvalidString " ));
29 }
30 result.Append(format[pos ++ ]);
31 }
32 else
33 {
34 result.Append(ch2);
35 }
36 }
37 if ( ! flag)
38 {
39 throw new FormatException( string .Format(CultureInfo.CurrentCulture, Environment.GetResourceString( " Format_BadQuote " ), new object [] { ch }));
40 }
41 return (pos - num2);
42 }