Unix时间是一种UNIX或类UNIX系统使用的时间表示方式,定义为从协调世界时UTC 1970年01月01日00时00分00秒起至现在的总秒数。相关知识请参考博文UNIX时间及相关概念
UNIX时间的转换在本章中这里更像是一个引子,引出了.Net中关于时间、时区和时差相关知识点。
在.Net时将某一时区时间转换成UNIX时间涉及到以下几个方面:
TimeSpan
用于表示一个时间间隔,即时间差
其中TotalSeconds属性以秒为单位表示当前TimeSpan结构值,Ticks属性以Tick为单位表示当前TimeSpan结构值
Tick中译为滴答也称为刻度,TimeSpan.TicksPerSecond常量字段用于表示一秒的刻度(滴答)数
一滴答 = 1000万分之一秒 = 万分之一毫秒 = 100纳秒
DateTime dt1 = Convert.ToDateTime("2014/05/06 10:10:00");
DateTime dt2 = Convert.ToDateTime("2014/05/06 10:15:00");
TimeSpan ts = dt2 - dt1;
Debug.WriteLine("TotalSeconds:{0} \t Ticks:{1} \t TicksPerSecond:{2}", ts.TotalSeconds, ts.Ticks, TimeSpan.TicksPerSecond);
//output:
// TotalSeconds:300 Ticks:3000000000 TicksPerSecond:10000000
DateTime
表示时间上的一刻,通常以日期和当天的时间表示。
时间最重要的一个属性是时区,没有时区属性的时间不是一个完整的时间,有了时区就能得到时差,而后才能+-时差最终得到标准UTC时间
DateTime中与时区相关的属性和方法有Now、UtcNow、ToLocalTime()、ToUniversalTime()和Kind等
Now属性:获取一个 DateTime 对象,该对象设置为此计算机上的当前日期和时间,表示为本地时间。
UtcNow属性:获取一个 DateTime 对象,该对象设置为此计算机上的当前日期和时间,表示为协调通用时间 (UTC)。
ToLocalTime()方法:将当前 DateTime 对象的值转换为本地时间。
ToUniversalTime()方法:用于将当前 DateTime 对象的值转换为协调世界时 (UTC)。
那么,如何知道一个时间是本地时间还是UTC时间呢,这取决于DateTime的Kind属性
Kind属性:获取一个值,该值指示由此实例表示的时间是基于本地时间、协调世界时 (UTC),还是两者皆否。
Kind属性是一个枚举类型DateTimeKind,DateTimeKind枚举有三个成员
DateTimeKind.Local 表示的时间为本地时间
DateTimeKind.Unspecified 表示的时间既未指定为本地时间,也未指定为协调通用时间 (UTC)。
DateTimeKind.Utc 表示的时间为 UTC。
直接赋值、Now、UtcNow 三种不同的时间输入方式得到三种不同的Kind及时间
DateTime dt1 = Convert.ToDateTime("2014/05/06 10:10:00");
DateTime dt2 = DateTime.Now;
DateTime dt3 = DateTime.UtcNow;
Debug.WriteLine("dt1.kind:{0} \t dt2.kind:{1} \t dt3.kind:{2}", dt1.Kind, dt2.Kind, dt3.Kind);
Debug.WriteLine("dt1:{0} \t dt2:{1} \t dt3:{2}", dt1, dt2, dt3);
//output:
// dt1.kind:Unspecified dt2.kind:Local dt3.kind:Utc
// dt1:05/06/2014 10:10:00 dt2:05/15/2014 11:31:48 dt3:05/15/2014 03:31:48
而ToUniversalTime()和ToLocalTime()的转换也依赖于Kind,这里需要注意的是
当待转DateTime的Kind为Unspecified时,ToLocalTime()假定待转DateTime为UTC时间,转换等同于Kind为UTC,ToUniversalTime()假定待转DateTime为Local时间,转换等同于Kind为Local
当待转DateTime的Kind为Local时,ToUniversalTime()方法什么也不作,直接返回原待转时间
当待转DateTime的Kind为UTC时,ToUniversalTime()方法什么也不作,直接返回原待转时间
DateTime dt1 = Convert.ToDateTime("2014/05/06 10:10:00");
DateTime dt2 = dt1.ToLocalTime();
DateTime dt3 = dt1.ToUniversalTime();
Debug.WriteLine("dt1.kind:{0} \t dt2.kind:{1} \t dt3.kind:{2}", dt1.Kind, dt2.Kind, dt3.Kind);
Debug.WriteLine("dt1:{0} \t dt2:{1} \t dt3:{2}", dt1, dt2, dt3);
//output:
// dt1.kind:Unspecified dt2.kind:Local dt3.kind:Utc
// dt1:05/06/2014 10:10:00 dt2:05/06/2014 18:10:00 dt3:05/06/2014 02:10:00
dt1 = DateTime.Now;
dt2 = dt1.ToLocalTime();
Debug.WriteLine("dt1.kind:{0} \t dt2.kind:{1}", dt1.Kind, dt2.Kind);
Debug.WriteLine("dt1:{0} \t dt2:{1}", dt1, dt2);
//output:
// dt1.kind:Local dt2.kind:Local
// dt1:05/15/2014 11:33:46 dt2:05/15/2014 11:33:46
dt1 = DateTime.UtcNow;
dt2 = dt1.ToUniversalTime();
Debug.WriteLine("dt1.kind:{0} \t dt2.kind:{1}", dt1.Kind, dt2.Kind);
Debug.WriteLine("dt1:{0} \t dt2:{1}", dt1, dt2);
//output:
// dt1.kind:Utc dt2.kind:Utc
// dt1:05/15/2014 03:33:46 dt2:05/15/2014 03:33:46
DateTime也有一个Ticks属性,与TimeSpa不同的是,它表示的是自 0001 年 1 月 1 日午夜 12:00:00(DateTime.MinValue)以来经过的以Tick为单位的间隔数。
Local和UTC之间的转换涉及到时区即时差,在.Net中DateTimeOffset、TimeZoneInfo等类型用于时区时差
DateTimeOffset
DateTimeOffset 结构包括一个 DateTime 值以及一个 Offset 属性,该属性用于确定当前 DateTimeOffset 实例的日期和时间与协调世界时 (UTC) 之间的差值。 因为 DateTimeOffset 结构确切地定义了相对于 UTC 的日期和时间,所以它不包括 Kind 成员,这一点与 DateTime 结构相同。
DateTimeOffset构造函数更好的说明了它的作用
public DateTimeOffset(
DateTime dateTime
)
使用指定的 DateTime 值初始化 DateTimeOffset 结构的新实例。
此构造函数的行为取决于 dateTime 参数的 DateTime.Kind 属性值:
如果 DateTime.Kind 的值为 DateTimeKind.Utc,则新实例的 DateTime 属性被设置为 dateTime,Offset 属性被设置为 Zero。
如果 DateTime.Kind 的值为 DateTimeKind.Local 或 DateTimeKind.Unspecified,则新实例的 DateTime 属性被设置为 dateTime,Offset 属性被设置为本地系统当前时区的偏移量。
DateTimeOffset dtf1 = new DateTimeOffset(Convert.ToDateTime("2014/05/06 10:10:00"));
DateTimeOffset dtf2 = DateTimeOffset.Now;
DateTimeOffset dtf3 = DateTimeOffset.UtcNow;
Debug.WriteLine("dtf1:{0} dtf1.Offset:{1} df1.DateTime.Kind:{2}", dtf1, dtf1.Offset, dtf1.DateTime.Kind);
Debug.WriteLine("dtf2:{0} dtf2.Offset:{1} df2.DateTime.Kind:{2}", dtf2, dtf2.Offset, dtf2.DateTime.Kind);
Debug.WriteLine("dtf3:{0} dtf3.Offset:{1} df3.DateTime.Kind:{2}", dtf3, dtf3.Offset, dtf3.DateTime.Kind);
//output:
// dtf1:05/06/2014 10:10:00 +08:00 dtf1.Offset:08:00:00 df1.DateTime.Kind:Unspecified
// dtf2:05/15/2014 11:43:28 +08:00 dtf2.Offset:08:00:00 df2.DateTime.Kind:Unspecified
// dtf3:05/15/2014 03:43:28 +00:00 dtf3.Offset:00:00:00 df3.DateTime.Kind:Unspecified
TimeZoneInfo(TimeZone的替代)
表示世界上的任何时区。 其中BaseUtcOffset属性为TimeSpan类型,用于获取对象所处时区的标准时间与协调世界时 (UTC) 之间的时差。
DateTime dt1 = Convert.ToDateTime("2014/05/06 10:10:00");
TimeZoneInfo tziCN = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
DateTime dt2 = TimeZoneInfo.ConvertTime(dt1, tziCN, TimeZoneInfo.Utc);
Debug.WriteLine("dt1:{0} \t dt2:{1} \t BaseUtcOffset:{2}", dt1, dt2, tziCN.BaseUtcOffset);
Debug.WriteLine("id:{0} \t DaylightName:{1} \t DisplayName:{2}", tziCN.Id, tziCN.DaylightName, tziCN.DisplayName);
//output:
// dt1:05/06/2014 10:10:00 dt2:05/06/2014 02:10:00 BaseUtcOffset:08:00:00
// id:China Standard Time DaylightName:中国夏令时 DisplayName:(UTC+08:00)北京,重庆,香港特别行政区,乌鲁木齐
foreach (TimeZoneInfo tzi in TimeZoneInfo.GetSystemTimeZones())
{
Debug.WriteLine("id:{0} \t DaylightName:{1} \t DisplayName:{2}", tzi.Id, tzi.DaylightName, tzi.DisplayName);
}
// etc..
综上,将某一时区时间转换为UNIX时间有多种方式,但时间、时区或时差是必不可少的参数。
TimeSpan 结构 (System)
http://msdn.microsoft.com/zh-cn/library/system.timespan.aspx
DateTime 结构 (System)
http://msdn.microsoft.com/zh-cn/library/system.datetime.aspx
DateTimeOffset 结构 (System)
http://msdn.microsoft.com/zh-cn/library/system.datetimeoffset.aspx
TimeZoneInfo 类 (System)
http://msdn.microsoft.com/zh-cn/library/system.timezoneinfo.aspx
纳秒
http://baike.baidu.com/view/187741.htm?fr=aladdin