全球化(9):时间格式
就象日期和日历格式一样,时间格式在全球各地也不是一成不变的。虽然每种时间表示基本上都显示小时、分钟和秒,但其显示顺序和分隔符相差很大。实际上,同一国家/地区的各地域之间也可能存在许多差异。不同地域之间的时间格式设置差异表现在以下三个方面中:
1、使用12小时或24小时时钟:大多数欧洲和亚洲区域设置采用 24 小时时钟,而美国采用 12 小时 A.M./P.M. 模型。在国家/地区的语言中也可以出现 A.M./P.M.,在一些语言中,它位于时间之前而不是时间之后。
2、用于分隔小时、分钟和秒的字符。虽然冒号 (:) 是分隔小时、分钟和秒最常用的字符,但一些亚洲语言使用的是象形字符。另外,一些区域设置要求显示 "h"、"m" 和 "s"。
3、时区的存储和显示。显示时区的一种最常见方式是以 GMT(格林尼治标准时间)或目前的 UTC(世界协调时间)为基础。后面紧跟着时区,表示为以小时和分钟计的正负偏移量。(一些时区使用 30 分钟或 45 分钟偏移量。)例如,印度班格洛尔的时区将显示为 UTC +5:30,而对于新西兰的查塔姆群岛,时区将为 UTC +12:45。另一种显示时区的方式是使用当地时区的名称。如果您采用这种方法,必须要考虑以下几个方面:
- 并非所有国家/地区都是使用当地名称。
- 时区缩写并不是唯一的。
- 并非所有国家/地区都使用夏令时,而且各国家/地区的夏令时的开始和结束日期并不相同。
- 一个时区可能具有许多不同的名称,具体取决于国家/地区和语言。
时区
时区是使用同一时间的地理区域。通常情况下,两个相邻时区之间相差一个小时,但情况并非总是如此。 世界上任何时区的时间都可以表示为协调世界时 (UTC) 的一个偏移量。
夏时制
世界上的很多时区都支持夏时制。夏时制会在春季或初夏将时间向前调一个小时,而在夏末或秋季将时间调回正常(或标准)时间,从而来尽量延长白昼时间。这些在夏时制和标准时间之间的来回变更称为调整规则。
在特定的时区中,夏时制的来回转换既可以由固定调整规则定义,也可以由浮动调整规则定义。固定调整规则会指定一个特定的日期,并在每年的这一天进行夏时制的来回转换。 例如,夏时制在每年的 10 月 25 日转换为标准时间,这遵循的便是固定调整规则。 更为常见的是浮动调整规则,这种规则会指定特定月份中特定星期的一个特定日期,并在这一天进行夏时制的来回转换。例如,如果规定在3月的第三个星期日从标准时间转换为夏时制,这遵循的便是浮动调整规则。
TimeZone
可以使用TimeZone 类来检索有关当前时区的信息,并将时间从本地时间转换为协调世界时 (UTC),反之亦然。 但不可使用TimeZone 类来表示本地时区以外的时区,或者将日期和时间从一个时区转换到另一个时区。TimeZone 类只支持本地时区的单个夏时制调整规则。因此TimeZone 类只有在最新调整规则有效期间才能准确报告夏时制信息,或者在 UTC 和本地时间之间进行转换。相反,TimeZoneInfo 类支持多个调整规则,因而可以处理历史时区数据。
Timezone简单示例:
1: using System;
2: using System.Globalization;
3: using System.Threading;
4:
5: class Program
6: {
7: static void Main(string[] args)
8: {
9: DateTime dt = DateTime.Now;
10: TimeZone localZone = TimeZone.CurrentTimeZone;
11:
12: Console.WriteLine("StandardName:"+localZone.StandardName);
13: Console.WriteLine("DaylightName:" + localZone.DaylightName);
14: Console.WriteLine("Current data and time:"+dt);
15: Console.WriteLine("UTC Time:"+localZone.ToUniversalTime(dt));
16: Console.WriteLine("UTC offset:"+localZone.GetUtcOffset(dt));
17: Console.Read();
18: }
19: }
运行结果:
TimeZoneInfo
TimeZoneInfo是.NET 3.5新增的类,对TimeZone类进行了显著增强。TimeZone 类只识别本地时区,但可以在协调世界时 (UTC) 和本地时间之间转换时间。TimeZoneInfo 对象可以表示任意时区,且TimeZoneInfo 类的方法可用于将一个时区的时间转换为其他任意时区的相应时间。 TimeZoneInfo 类的成员支持以下操作:
-
检索操作系统已定义的时区。
-
枚举系统上可用的时区。
-
在不同时区之间转换时间。
-
创建操作系统尚未定义的新时区。
-
序列化时区。
TimeZoneInfo 类的实例是不可变的。 一旦实例化对象后,就无法修改其值。
TimeZoneInfo的静态成员:
静态成员名 |
说明 |
---|---|
使用应用程序提供的数据创建自定义时区。 |
|
根据时区的标识符实例化在系统注册表中定义的时区。 |
|
反序列化一个字符串值,以重新创建先前已序列化的 TimeZoneInfo 对象。 |
|
返回 TimeZoneInfo 对象的可枚举的 ReadOnlyCollection<T>,它表示本地系统上可用的所有时区。 |
|
Local 属性 |
实例化表示本地时区的 TimeZoneInfo 对象。 |
Utc 属性 |
实例化表示 UTC 时区的 TimeZoneInfo 对象。 |
简单示例:
1: using System;
2: using System.Globalization;
3: using System.Threading;
4:
5: class Program
6: {
7: static void Main(string[] args)
8: {
9: DateTime dt = DateTime.Now;
10:
11: //获取系统支持的TimeZoneInfo列表
12: var zones=TimeZoneInfo.GetSystemTimeZones();
13: foreach (var zone in zones)
14: {
15: Console.WriteLine(zone.Id);
16: }
17:
18: Console.WriteLine("local date and time:"+dt);
19: //ConvertTimeToUtc
20: Console.WriteLine("utc date and time:"+TimeZoneInfo.ConvertTimeToUtc(dt));
21:
22: DateTime timeUtc = DateTime.UtcNow;
23:
24: //创建中国标准时间的TimeZoneInfo
25: TimeZoneInfo chinaZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
26:
27: //ConvertTimeFromUtc
28: Console.WriteLine("utc date and time:" + timeUtc);
29: Console.WriteLine("distination date and time:"+TimeZoneInfo.ConvertTimeFromUtc(timeUtc,chinaZone));
30:
31: TimeZoneInfo localZone = TimeZoneInfo.Local;
32: Console.WriteLine("TimeZoneInfo.Local:"+localZone.Id);
33:
34: Console.Read();
35: }
36: }
DateTimeOffset
DateTimeOffset类提供了多种创建新的DateTimeOffset值的方法。其中的许多方法都直接与可用于实例化新的 DateTime值的方法相对应,只是增加了增强功能,允许您指定日期和时间值相对于协调世界时 (UTC) 的偏移量。具体而言,可以使用下列方式实例化 DateTimeOffset 值:
-
使用日期和时间文本。
-
调用DateTimeOffset构造函数。
-
将某个值隐式转换为DateTimeOffset值。
-
分析日期和时间的字符串表示形式。
简单示例:
1: using System;
2: using System.Globalization;
3: using System.Threading;
4:
5: class Program
6: {
7: static void Main(string[] args)
8: {
9: DateTimeOffset dateAndTime;
10:
11: dateAndTime = new DateTimeOffset(2010, 12, 21, 22, 09, 30, new TimeSpan(1, 0, 0));
12: Console.WriteLine(dateAndTime);
13: //2010-12-21 22:09:30 +01:00
14:
15: DateTimeOffset targetTime;
16: DateTime sourceDate = new DateTime(2010, 12, 21, 22, 09, 30);
17: targetTime = sourceDate;
18: Console.WriteLine(targetTime);
19: //2010-12-21 22:09:30 +08:00
20:
21: DateTime utcTime = DateTime.SpecifyKind(sourceDate, DateTimeKind.Utc);
22: targetTime = utcTime;
23: Console.WriteLine(targetTime);
24: //2010-12-21 22:09:30 +00:00
25:
26: DateTime localTime = DateTime.SpecifyKind(sourceDate, DateTimeKind.Local);
27: targetTime = localTime;
28: Console.WriteLine(targetTime);
29: //2010-12-21 22:09:30 +08:00
30: Console.Read();
31: }
32: }
DateTime.Kind 属性
DateTime.Kind属性获取一个值,该值指示由此实例表示的时间是基于本地时间、协调世界时 (UTC),还是两者皆否。
Unspecified:表示的时间既未指定为本地时间,也未指定为协调通用时间 (UTC)。
Utc :表示的时间为 UTC。
Local:表示的时间为本地时间。
1: using System;
2:
3: class Program
4: {
5: public static void Main()
6: {
7: DateTime saveNow = DateTime.Now;
8: DateTime saveUtcNow = DateTime.UtcNow;
9: DateTime myDt;
10:
11: DisplayNow("UtcNow: ..........", saveUtcNow);
12: DisplayNow("Now: .............", saveNow);
13: Console.WriteLine();
14:
15: myDt = DateTime.SpecifyKind(saveNow, DateTimeKind.Utc);
16: Display("Utc: .............", myDt);
17:
18: myDt = DateTime.SpecifyKind(saveNow, DateTimeKind.Local);
19: Display("Local: ...........", myDt);
20:
21: myDt = DateTime.SpecifyKind(saveNow, DateTimeKind.Unspecified);
22: Display("Unspecified: .....", myDt);
23:
24: Console.Read();
25: }
26:
27: public static string datePatt = @"yyyy/MM/dd hh:mm:ss tt";
28: public static void Display(string title, DateTime inputDt)
29: {
30: DateTime dispDt = inputDt;
31: string dtString;
32:
33: dtString = dispDt.ToString(datePatt);
34: Console.WriteLine("{0} {1}, Kind = {2}",
35: title, dtString, dispDt.Kind);
36:
37: dispDt = inputDt.ToLocalTime();
38: dtString = dispDt.ToString(datePatt);
39: Console.WriteLine(" ToLocalTime: {0}, Kind = {1}",
40: dtString, dispDt.Kind);
41:
42: dispDt = inputDt.ToUniversalTime();
43: dtString = dispDt.ToString(datePatt);
44: Console.WriteLine(" ToUniversalTime: {0}, Kind = {1}",
45: dtString, dispDt.Kind);
46: Console.WriteLine();
47: }
48:
49: public static void DisplayNow(string title, DateTime inputDt)
50: {
51: string dtString = inputDt.ToString(datePatt);
52: Console.WriteLine("{0} {1}, Kind = {2}",
53: title, dtString, inputDt.Kind);
54: }
55: }
运行结果: