C#格式化数值结果表
字符 | 说明 | 示例 | 输出 |
C | 货币 | string.Format("{0:C3}", 2) | $2.000 |
D | 十进制 | string.Format("{0:D3}", 2) | 002 |
E | 科学计数法 | 1.20E+001 | 1.20E+001 |
G | 常规 | string.Format("{0:G}", 2) | 2 |
N | 用分号隔开的数字 | string.Format("{0:N}", 250000) | 250,000.00 |
X | 十六进制 | string.Format("{0:X000}", 12) | C |
string.Format("{0:000.000}", 12.2) | 012.200 |
Strings
There really isn't any formatting within a strong, beyond it's alignment. Alignment works for any argument being printed in a String.Format call.
Sample | Generates |
String.Format("->{1,10}<-", "Hello"); | -> Hello<- |
String.Format("->{1,-10}<-", "Hello"); | ->Hello <- |
Numbers
Basic number formatting specifiers:
Specifier | Type | Format | Output | Output |
c | Currency | {0:c} | $1.42 | -$12,400 |
d | Decimal (Whole number) | {0:d} | System. FormatException | -12400 |
e | Scientific | {0:e} | 1.420000e+000 | -1.240000e+004 |
f | Fixed point | {0:f} | 1.42 | -12400.00 |
g | General | {0:g} | 1.42 | -12400 |
n | Number with commas for thousands | {0:n} | 1.42 | -12,400 |
r | Round trippable | {0:r} | 1.42 | System. FormatException |
x | Hexadecimal | {0:x4} | System. FormatException | cf90 |
Custom number formatting:
Specifier | Type | Example | Output (Passed Double 1500.42) | Note |
0 | Zero placeholder | {0:00.0000} | 1500.4200 | Pads with zeroes. |
# | Digit placeholder | {0:(#).##} | (1500).42 | |
. | Decimal point | {0:0.0} | 1500.4 | |
, | Thousand separator | {0:0,0} | 1,500 | Must be between two zeroes. |
,. | Number scaling | {0:0,.} | 2 | Comma adjacent to Period scales by 1000. |
% | Percent | {0:0%} | 150042% | Multiplies by 100, adds % sign. |
e | Exponent placeholder | {0:00e+0} | 15e+2 | Many exponent formats available. |
; | Group separator | see below |
The group separator is especially useful for formatting currency values which require that negative values be enclosed in parentheses. This currency formatting example at the bottom of this document makes it obvious:
Dates
Note that date formatting is especially dependant on the system's regional settings; the example strings here are from my local locale.
Specifier | Type | Example (Passed System.DateTime.Now) |
d | Short date | 10/12/2002 |
D | Long date | December 10, 2002 |
t | Short time | 10:11 PM |
T | Long time | 10:11:29 PM |
f | Full date & time | December 10, 2002 10:11 PM |
F | Full date & time (long) | December 10, 2002 10:11:29 PM |
g | Default date & time | 10/12/2002 10:11 PM |
G | Default date & time (long) | 10/12/2002 10:11:29 PM |
M | Month day pattern | December 10 |
r | RFC1123 date string | Tue, 10 Dec 2002 22:11:29 GMT |
s | Sortable date string | 2002-12-10T22:11:29 |
u | Universal sortable, local time | 2002-12-10 22:13:50Z |
U | Universal sortable, GMT | December 11, 2002 3:13:50 AM |
Y | Year month pattern | December, 2002 |
The 'U' specifier seems broken; that string certainly isn't sortable.
Custom date formatting:
Specifier | Type | Example | Example Output |
dd | Day | {0:dd} | 10 |
ddd | Day name | {0:ddd} | Tue |
dddd | Full day name | {0:dddd} | Tuesday |
f, ff, ... | Second fractions | {0:fff} | 932 |
gg, ... | Era | {0:gg} | A.D. |
hh | 2 digit hour | {0:hh} | 10 |
HH | 2 digit hour, 24hr format | {0:HH} | 22 |
mm | Minute 00-59 | {0:mm} | 38 |
MM | Month 01-12 | {0:MM} | 12 |
MMM | Month abbreviation | {0:MMM} | Dec |
MMMM | Full month name | {0:MMMM} | December |
ss | Seconds 00-59 | {0:ss} | 46 |
tt | AM or PM | {0:tt} | PM |
yy | Year, 2 digits | {0:yy} | 02 |
yyyy | Year | {0:yyyy} | 2002 |
zz | Timezone offset, 2 digits | {0:zz} | -05 |
zzz | Full timezone offset | {0:zzz} | -05:00 |
: | Separator | {0:hh:mm:ss} | 10:43:20 |
/ | Separator | {0:dd/MM/yyyy} | 10/12/2002 |
Datetime.ToString(String, IFormatProvider)
参数format格式详细用法:
格式字符 | 关联属性/说明 |
d | ShortDatePattern |
D | LongDatePattern |
f | 完整日期和时间(长日期和短时间) |
F | FullDateTimePattern(长日期和长时间) |
g | 常规(短日期和短时间) |
G | 常规(短日期和长时间) |
m、M | MonthDayPattern |
r、R | RFC1123Pattern |
s | 使用当地时间的 SortableDateTimePattern(基于ISO 8601) |
t | ShortTimePattern |
T | LongTimePattern |
u | UniversalSortableDateTimePattern用于显示通用时间的格式 |
U | 使用通用时间的完整日期和时间(长日期和长时间) |
y、Y | YearMonthPattern |
下表列出了可被合并以构造自定义模式的模式。这些模式是区分大小写的;例如,识别“MM”,但不识别“mm”。如果自定义模式包含空白字符或用单引号括起来的字符,则输出字符串页也将包含这些字符。未定义为格式模式的一部分或未定义为格式字符的字符按其原义复制。
格式模式 | 说明 |
d | 月中的某一天。一位数的日期没有前导零。 |
dd | 月中的某一天。一位数的日期有一个前导零。 |
ddd | 周中某天的缩写名称,在 AbbreviatedDayNames 中定义。 |
dddd | 周中某天的完整名称,在 DayNames 中定义。 |
M | 月份数字。一位数的月份没有前导零。 |
MM | 月份数字。一位数的月份有一个前导零。 |
MMM | 月份的缩写名称,在 AbbreviatedMonthNames 中定义。 |
MMMM | 月份的完整名称,在 MonthNames 中定义。 |
y | 不包含纪元的年份。如果不包含纪元的年份小于 10,则显示不具有前导零的年份。 |
yy | 不包含纪元的年份。如果不包含纪元的年份小于 10,则显示具有前导零的年份。 |
yyyy | 包括纪元的四位数的年份。 |
gg | 时期或纪元。如果要设置格式的日期不具有关联的时期或纪元字符串,则忽略该模式。 |
h | 12小时制的小时。一位数的小时数没有前导零。 |
hh | 12小时制的小时。一位数的小时数有前导零。 |
H | 24小时制的小时。一位数的小时数没有前导零。 |
HH | 24小时制的小时。一位数的小时数有前导零。 |
m | 分钟,一位数的分钟数没有前导零。 |
mm | 分钟,一位数的分钟数有一个前导零。 |
s | 秒,一位数的秒数没有前导零。 |
ss | 秒,一位数的秒数有一个前导零。 |
f | 秒的小数精度为一位。其余数字被截断。 |
ff | 秒的小数精度为两位。其余数字被截断。 |
fff | 秒的小数精度为三位。其余数字被截断。 |
ffff | 秒的小数精度为四位。其余数字被截断。 |
fffff | 秒的小数精度为五位。其余数字被截断。 |
ffffff | 秒的小数精度为六位。其余数字被截断。 |
fffffff | 秒的小数精度为七位。其余数字被截断。 |
t | 在AMDesignator或PMDesignator中定义的AM/PM指示项的第一个字符(如果存在)。 |
tt | 在AMDesignator或PMDesignator中定义的AM/PM指示项(如果存在)。 |
z | 时区偏移量(“+”或“-”后面仅跟小时)。一位数的小时数没有前导零。例如,太平洋标准时间是“-8”。 |
zz | 时区偏移量(“+”或“-”后面仅跟小时)。一位数的小时数有前导零。例如,太平洋标准时间是“-08”。 |
zzz | 完整时区偏移量(“+”或“-”后面跟有小时和分钟)。一位数的小时数和分钟数有前导零。例如,太平洋标准时间是“-08:00”。 |
: | 在TimeSeparator中定义的默认时间分隔符。 |
/ | 在DateSeparator中定义的默认日期分隔符。 |
%c | 其中c是格式模式(如果单独使用)。如果格式模式与原义字符或其他格式模式合并,则可以省略“%”字符。 |
c | 其中c是任意字符。照原义显示字符。若要显示反斜杠字符,请使用“\”。 |
只有上面第二个表中列出的格式模式才能用于创建自定义模式;在第一个表中列出的标准格式字符不能用于创建自定义模式。自定义模式的长度至少为两个字符;例如,
DateTime.ToString( "d") 返回 DateTime 值;“d”是标准短日期模式。
DateTime.ToString( "%d") 返回月中的某天;“%d”是自定义模式。
DateTime.ToString( "d ") 返回后面跟有一个空白字符的月中的某天;“d”是自定义模式。
Enumerations
Specifier | Type |
g | Default (Flag names if available, otherwise decimal) |
f | Flags always |
d | Integer always |
x | Eight digit hex. |
Some Useful Examples
String.Format("{0:$#,##0.00;($#,##0.00);Zero}", value);
This will output "$1,240.00" if passed 1243.50. It will output the same format but in parentheses if the number is negative, and will output the string "Zero" if the number is zero.
String.Format("{0:(###) ###-####}", 18005551212);
This will output "(800) 555-1212".
1、Math.Round(0.333333,2);//按照四舍五入的国际标准
2、double dbdata=0.335333; string str1=String.Format("{0:F}",dbdata);//默认为保留两位
3、float i=0.333333; int j=(int)(i * 100); i = j/100;
4、decimal.Round(decimal.Parse("0.3333333"),2)
5、private System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo(); float test=0.333333f; nfi.NumberDecimalDigits=2; string result=test.ToString("N", nfi);
6、string result= String.Format("{0:N2}",Convert.ToDecimal("0.333333").ToString());
7、Convert.ToDecimal("0.33333333").ToString("0.00");
变量.ToString()
字符型转换 转为字符串
12345.ToString("n"); //生成 12,345.00
12345.ToString("C"); //生成 ¥12,345.00
12345.ToString("e"); //生成 1.234500e+004
12345.ToString("f4"); //生成 12345.0000
12345.ToString("x"); //生成 3039 (16进制)
12345.ToString("p"); //生成 1,234,500.00%
C#中 decimal 的四舍五入
当:decimal sum = 123456.784M;
sum = decimal.Round(sum, 2 , MidpointRounding.AwayFromZero);
sum 的值为:123456.78
当:decimal sum = 123456.785M;
sum = decimal.Round(sum, 2 , MidpointRounding.AwayFromZero);
sum 的值为:123456.79public static string DecimalToString(decimal d)
{
return d.ToString("#0.######");
}这个的显示很简单给几个例子就懂了,注意第一个结果,是会四舍五入的
private void button1_Click(object sender, EventArgs e)
{
decimal d0 = 0.0000006m;
decimal d1 = 0.005000m;
decimal d2 = 1.00005m;
decimal d3 = 200.00000m;
decimal d4 = 200.00006m;
Console.WriteLine(DecimalToString(d0));
Console.WriteLine(DecimalToString(d1));
Console.WriteLine(DecimalToString(d2));
Console.WriteLine(DecimalToString(d3));
Console.WriteLine(DecimalToString(d4));
}结果如下:
0.000001
0.005
1.00005
200
200.00006后面的0会给去除,如果小于0的数,0个位还是0,这样就比较符合用户的需求的习惯。
再附加上#和0这两个符号的说明:
5、零占位符和数字占位符
string.Format("{0:0000.00}", 12394.039) 结果为:12394.04
string.Format("{0:0000.00}", 194.039) 结果为:0194.04
string.Format("{0:###.##}", 12394.039) 结果为:12394.04
string.Format("{0:####.#}", 194.039) 结果为:194
下面的这段说明比较难理解,多测试一下实际的应用就可以明白了。
零占位符:
如果格式化的值在格式字符串中出现“0”的位置有一个数字,则此数字被复制到结果字符串中。小数点前最左边的“0”的位置和小数点后最右边的“0”的位置确定总在结果字符串中出现的数字范围。
“00”说明符使得值被舍入到小数点前最近的数字,其中零位总被舍去。数字占位符:
如果格式化的值在格式字符串中出现“#”的位置有一个数字,则此数字被复制到结果字符串中。否则,结果字符串中的此位置不存储任何值。
请注意,如果“0”不是有效数字,此说明符永不显示“0”字符,即使“0”是字符串中唯一的数字。如果“0”是所显示的数字中的有效数字,则显示“0”字符。
“##”格式字符串使得值被舍入到小数点前最近的数字,其中零总被舍去。decimal(C#)
decimal 关键字指示 128 位数据类型。 与浮点型相比,decimal 类型具有更高的精度和更小的范围,这使它适合于财务和货币计算。decimal 类型的大致范围和精度如下所示。
类型
大致范围
精度
.NET Framework 类型
decimal
(-7.9 x 1028 - 7.9 x 1028) / (100 - 28)
28-29 个有效位
如果希望实数被视为 decimal 类型,请使用后缀 m 或 M,例如:
decimal myMoney = 300.5m;
如果没有后缀 m,则数字将被视为 double 类型并会生成编译器错误。
整型将被隐式转换为 decimal 类型,其计算结果为decimal。 因此,可以使用整数文本初始化十进制变量而不使用后缀,如下所示:
decimal myMoney = 300;
在浮点型和 decimal 类型之间不存在隐式转换;因此,必须使用强制转换以在这两个类型之间转换。例如:
decimal myMoney = 99.9m; double x = (double)myMoney; myMoney = (decimal)x;
还可以在同一表达式中混合使用 decimal 和数值整型。但是,不进行强制转换就混合使用 decimal 和浮点型将导致编译错误。
下面的示例尝试添加double 和decimal 变量,这会导致编译器错误。
double dub = 9;
Console.WriteLine(dec + dub); // error:"+"运算符不能用于连接decimal和double类型
Console.WriteLine(dec + (decimal)dub); //正确
Console.WriteLine((double)dec + dub); // 正确
在下面的示例中,同一个表达式中混合使用了decimal 和 int。计算结果为 decimal 类型。没有问题
publicclass TestDecimal
{
static void Main()
{
decimal d = 9.1m;
int y = 3;
Console.WriteLine(d + y);// 结果会被隐式转换为decimal类型
}
}
// 输出12.1
设置十进制输出的格式
可以通过使用 String.Format 方法或Console.Write 方法(其调用String.Format())来设置结果的格式。 货币格式是使用标准货币格式字符串“C”或“c”指定的,如下示例所示:
在此示例中,通过使用货币格式字符串来设置输出的格式。请注意,x 被舍入,因为其小数位数超出了 $0.99。表示最大精确位数的变量 y 严格按照正确的格式显示。
public class TestDecimalFormat
{
static void Main()
{
decimal x = 0.999m;
decimal y = 9999999999999999999999999999m;
Console.WriteLine("My amount = {0:C}", x);
Console.WriteLine("Your amount = {0:C}", y);
}
}
/*输出: My amount = $1.00
Your amount = $9,999,999,999,999,999,999,999,999,999.00
*/
decimal拥有比float更高的精度,最高能处理到小数点后面的28位。适合用在财务类等对数字精确度要求比较高的场合。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace cxx { class test { static void Main(string[] args) { decimal price; decimal discount; decimal discount_price; //注意:必须要带“m”,否则将和标准的浮点类型一样。而我们要求的却是 //用来计算货币类的浮点数,但是可以给其赋整数值。 // decimal 对小数的运算更加的准确。 price = 19.95m; discount = 0.15m; //discount rate is 15% discount_price = price - (price * discount); Console.WriteLine("Discounted price :$ " + discount_price); Console.ReadKey(); } } }
结果:
//时间
System.DateTime GetTime(int seconds)
{
System.DateTime original = new System.DateTime(1970, 1, 1, 8, 0, 0, 0);
System.TimeSpan ts = System.TimeSpan.FromSeconds(seconds);
return original + ts;
}m_strTime = GetTime(info.m_startTime).ToString("yyyy-MM-dd");
//检测中文
int CheckStringChinese(string str)
{
int count=0;
for(int i=0; i<str.Length;i++)
{
if(str[i]>127)
{
count += 1;
}
}
return count;
}int CheckStringChinese2(string str)
{
int count = 0;
char[] c = str.ToCharArray();
for (int i = 0; i < c.Length; i++)
{
if (c[i] >= 0x4e00 && c[i] <= 0x9fbb)
{
count += 1;
}
}
return count;
}
bool CheckAllChinese(string str)
{
bool res = true;
char[] c = str.ToCharArray();
for (int i = 0; i < c.Length; i++)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(c[i].ToString(), @"[\u4e00-\u9fbb]+$"))
{
res = false;
}
else
{
continue;
}
}
return res;
}
//反转时间格式
TimeSpan ts = new TimeSpan(0,0,0,1389753949);
DateTime now = Convert.ToDateTime("2014-01-15 10:45:49");
DateTime baseTime = now - ts;
Response.Write(baseTime.ToString());
Response.Write("<br/>");
baseTime = Convert.ToDateTime("1970-1-1 8:00:00");
ts = DateTime.Now - baseTime;
long intervel = (long)ts.TotalSeconds;
Response.Write("当前时间转换为:" + intervel.ToString());
string curDate = DateTime.Now.ToString("yyyy-MM-dd");
string cur = UTTools.ConvertToTimeFormat(time).ToString("HH:mm:ss");
DateTime curDT = Convert.ToDateTime(curDate + " " + cur);
DateTime baseTime = new DateTime(1970, 1, 1, 8, 0, 0);
TimeSpan ts = curDT - baseTime;
return (int)ts.TotalSeconds;
System.DateTime original = new System.DateTime(1970, 1, 1, 8, 0, 0);
DateTime dt = original + System.TimeSpan.FromSeconds(seconds);
return dt;
public string GetTimeStamp()
{
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
DateTime nowTime = DateTime.Now;
long unixTime = (long)System.Math.Round((nowTime - startTime).TotalMilliseconds, MidpointRounding.AwayFromZero);
return unixTime.ToString();
}
public static DateTime GetTime(string timeStamp)
{
DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
long lTime = long.Parse(timeStamp + "0000000");
TimeSpan toNow = new TimeSpan(lTime);
return dtStart.Add(toNow);
}
public static int ConvertDateTimeInt(System.DateTime time)
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
return (int)(time - startTime).TotalSeconds;
}
static double ToTimestamp(DateTime value)
{
TimeSpan span = (value - new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime());
return (double)span.TotalSeconds;
}
static DateTime ConvertTimestamp(double timestamp)
{
DateTime converted = new DateTime(1970, 1, 1, 0, 0, 0, 0);
DateTime newDateTime = converted.AddSeconds(timestamp);
return newDateTime.ToLocalTime();
}
long
unixTimeStamp = 1478162177;
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(
new
System.DateTime(1970, 1, 1));
// 当地时区
DateTime dt = startTime.AddSeconds(unixTimeStamp);
System.Console.WriteLine(dt.ToString(
"yyyy/MM/dd HH:mm:ss:ffff"
));
System.DateTime.UtcNow.Ticks => s -> *1000 = ms à *10000 = ticks
- 24*60*60 * 1000 * 10000
string openTime = “2017-06-06 10:30:00” ;
DateTime tmpTime;
DateTime.TryParse(openTime.Replace(“\””,””), out tmpTime);
tmpTime.ToString(“yyyy-MM-dd HH:mm:ss (ffff)”)
var tmpAAA = (tmpTime - TimeZone.CurrentTimeZone.ToLocalTime(
new
System.DateTime(1970, 1, 1))).TotalSeconds;
//这个时间,从1970年来的 总秒数(时间戳) 注意不是ticks
formatTime(t) {
var timeStr = new Date(t).toLocaleString();
var arr1 = timeStr.split(" ");
var arr2 = arr1[0].split("/");
for(var i = 1; i <= 2; i++) {
if(parseInt(arr2[i], 10) < 10) {
arr2[i] = "0" + arr2[i];
}
}
var str1 = arr2.join("-");
var arr3 = arr1[1].split(":");
if(arr3[0].indexOf("AM") !== -1) {
if(parseInt(arr3[0].replace(/AM/g, ""), 10) < 10) {
arr3[0] = "0" + arr3[0].replace(/AM/g, "");
} else {
arr3[0] = arr3[0].replace(/AM/g, "");
}
}
if(arr3[0].indexOf("PM") !== -1) {
arr3[0] = (12 + parseInt(arr3[0].replace(/PM /g, ""), 10)).toString();
}
var str2 = arr3.join(":");
return str1 + " " + str2;
}
DateTime time = DateTime.Now;string s = time.ToString("yyyy.MM.dd hh:mm:ss t\\M");Console.WriteLine(s);
using System.IO;
using System;
using System.Globalization;
using System.Threading.Tasks;
class Program
{
static void Main()
{
var cultures = new string[] {null, "en-NZ", "en-US", "en-AU", "en-GB"};
foreach (var culture in cultures) {
if (culture != null) {
var c = CultureInfo.GetCultureInfo(culture);
System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = c;
}
DateTime dt = new DateTime(2015, 1, 2, 3, 4, 5, DateTimeKind.Utc);
Console.WriteLine("selection: {0} CurrentThread.CurrentCulture.Name: {1} CurrentThread.CurrentUICulture.Name: {2} Value: {3}",
culture ?? "ambient",
System.Threading.Thread.CurrentThread.CurrentCulture.Name,
System.Threading.Thread.CurrentThread.CurrentUICulture.Name,
dt.ToString("hhh:mm tt"));
}
}
}
以前版本的Windows的输出是:
selection: ambient CurrentThread.CurrentCulture.Name: en-NZ CurrentThread.CurrentUICulture.Name: en-NZ Value: 03:04 a.m.
selection: en-NZ CurrentThread.CurrentCulture.Name: en-NZ CurrentThread.CurrentUICulture.Name: en-NZ Value: 03:04 a.m.
selection: en-US CurrentThread.CurrentCulture.Name: en-US CurrentThread.CurrentUICulture.Name: en-US Value: 03:04 AM
selection: en-AU CurrentThread.CurrentCulture.Name: en-AU CurrentThread.CurrentUICulture.Name: en-AU Value: 03:04 AM
selection: en-GB CurrentThread.CurrentCulture.Name: en-GB CurrentThread.CurrentUICulture.Name: en-GB Value: 03:04 am
而在Windows 10中:
selection: ambient (windows 10) CurrentThread.CurrentCulture.Name: en-NZ CurrentThread.CurrentUICulture.Name: en-US Value: 03:04 a.m.
selection: en-NZ CurrentThread.CurrentCulture.Name: en-NZ CurrentThread.CurrentUICulture.Name: en-NZ Value: 03:04 AM
selection: en-US CurrentThread.CurrentCulture.Name: en-US CurrentThread.CurrentUICulture.Name: en-US Value: 03:04 AM
selection: en-AU CurrentThread.CurrentCulture.Name: en-AU CurrentThread.CurrentUICulture.Name: en-AU Value: 03:04 AM
selection: en-GB CurrentThread.CurrentCulture.Name: en-GB CurrentThread.CurrentUICulture.Name: en-GB Value: 03:04 AM
iOS有DateFormatter显示AM PM,可以设置格式
let formatter: DateFormatter = DateFormatter()
formatter.dateFormat = "hh:mm a"
let dateString = formatter.string(from: date)
这样就显示上下午了,不过只是这样还不行,因为手机语言用的是汉语,所以是显示的‘上午’和‘下午’,如果想显示的是‘AM’和‘PM’,就可以这样设置:
let formatter: DateFormatter = DateFormatter()
formatter.dateFormat = "hh:mm a"
formatter.amSymbol = "AM"
formatter.pmSymbol = "PM"
let dateString = formatter.string(from: date)
真机测试也是显示,这样在我的手机上正常显示,但是在测试的手机上还是不显示,查到是手机设置的问题,在手机设置->通用->日期与时间->24小时制,必须手机把24小时制关闭,系统才可以显示AM和PM.