來(lái)源:https://blog.guoqianfan.com/2019/11/24/timestamp-in-csharp/
什么是時(shí)間戳
時(shí)間戳默認(rèn)是Unix時(shí)間戳。
首先要清楚JavaScript與Unix的時(shí)間戳的區(qū)別:
JavaScript時(shí)間戳:是指格林威治時(shí)間1970年01月01日00時(shí)00分00秒(北京時(shí)間1970年01月01日08時(shí)00分00秒)起至現(xiàn)在的總毫秒數(shù)肌似。
Unix時(shí)間戳:是指格林威治時(shí)間1970年01月01日00時(shí)00分00秒(北京時(shí)間1970年01月01日08時(shí)00分00秒)起至現(xiàn)在的總秒數(shù)。
可以看出JavaScript時(shí)間戳是總毫秒數(shù)力细,Unix時(shí)間戳是總秒數(shù)眠蚂。
比如同樣是的 2016/11/03 12:30:00 斗躏,轉(zhuǎn)換為JavaScript時(shí)間戳為 1478147400000;轉(zhuǎn)換為Unix時(shí)間戳為 1478147400笛臣。
從上面也可以看出時(shí)間戳與時(shí)區(qū)無(wú)關(guān)捐祠。
Unix時(shí)間戳相互轉(zhuǎn)換
C# DateTime轉(zhuǎn)換為Unix時(shí)間戳
.NET 4.6新方法
只能在 .NET 4.6及更高版本里才能使用。
long timeStamp = DateTimeOffset.Now.ToUnixTimeSeconds(); // 相差秒數(shù)
Console.WriteLine(timeStamp);
通用的老方法
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 當(dāng)?shù)貢r(shí)區(qū)
long timeStamp = (long)(DateTime.Now - startTime).TotalSeconds; // 相差秒數(shù)
System.Console.WriteLine(timeStamp);
Unix時(shí)間戳轉(zhuǎn)換為C# DateTime
.NET 4.6新方法
由時(shí)間戳轉(zhuǎn)換的DateTimeOffset
的時(shí)區(qū)默認(rèn)是+00:00
窿给,此時(shí)我們需要轉(zhuǎn)為本地時(shí)區(qū)崩泡,否則后續(xù)使用可能會(huì)有問(wèn)題角撞。
轉(zhuǎn)為本地時(shí)區(qū):DateTimeOffset.LocalDateTime
勃痴。
示例代碼如下:
//默認(rèn)為UTC時(shí)間:{2019/11/14 1:53:26 +00:00}
DateTimeOffset dto = DateTimeOffset.FromUnixTimeMilliseconds(1573696406184);
//默認(rèn)為UTC時(shí)間:{2019/11/14 1:53:26}
DateTime dt01 = dto.DateTime;
//轉(zhuǎn)為本地時(shí)區(qū):{2019/11/14 9:53:26}
DateTime dt02 = dto.LocalDateTime;
通用的老方法
long unixTimeStamp = 1478162177;
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 當(dāng)?shù)貢r(shí)區(qū)
DateTime dt = startTime.AddSeconds(unixTimeStamp);
System.Console.WriteLine(dt.ToString("yyyy/MM/dd HH:mm:ss:ffff"));
備注
DateTimeOffset使用Now還是UtcNow
對(duì)于DateTimeOffset
沛申,發(fā)現(xiàn)有2個(gè)獲取當(dāng)前時(shí)間的屬性:DateTimeOffset.Now
和DateTimeOffset.UtcNow
。
如果只是獲取時(shí)間戳尖淘,這2個(gè)使用哪個(gè)都可以著觉,得到的值是一樣的饼丘。
因?yàn)?code>DateTimeOffset里面有時(shí)區(qū)信息,獲取時(shí)間戳?xí)r會(huì)使用時(shí)區(qū)進(jìn)行轉(zhuǎn)換的镇辉,所以獲得的時(shí)間戳一樣屡穗。
而也是因?yàn)闀r(shí)區(qū)的原因村砂,DateTimeOffset
的其他操作可能會(huì)不一樣烂斋。例如DateTimeOffset.DateTime
就不一樣罕模,此時(shí)推薦使用DateTimeOffset.LocalDateTime
來(lái)獲得本地時(shí)區(qū)的時(shí)間淑掌。
測(cè)試代碼如下:
//none:2019/6/14 15:17:43 +08:00
Console.WriteLine("none:{0}", DateTimeOffset.Now);
//utc:2019/6/14 7:17:43 +00:00
Console.WriteLine("utc:{0}", DateTimeOffset.UtcNow);
//none:1560496663
Console.WriteLine("none:{0}", DateTimeOffset.Now.ToUnixTimeSeconds());
//utc:1560496663
Console.WriteLine("utc:{0}", DateTimeOffset.UtcNow.ToUnixTimeSeconds());
DateTime轉(zhuǎn)換為DateTimeOffset
可以直接把DateTime
賦值給DateTimeOffset
蝶念,內(nèi)部會(huì)自動(dòng)進(jìn)行隱式轉(zhuǎn)換。這里涉及到時(shí)區(qū)担敌,請(qǐng)往下看全封。
DateTime的時(shí)區(qū)信息(Kind屬性)
DateTime
的時(shí)區(qū)信息存放在Kind
屬性里桃犬。Kind
屬性的數(shù)據(jù)類(lèi)型是DateTimeKind
枚舉刹悴,只有3個(gè)值:
-
Unspecified
:未指定/未規(guī)定 -
Utc
:UTC
時(shí)間 -
Local
:本地時(shí)區(qū)
不同情況下得到的DateTime
的Kind
是不同的,具體如下:
DateTime.Now
:DateTime.Kind
是Local
(本地時(shí)區(qū))攒暇。DateTime.UtcNow
:DateTime.Kind
是Utc
颂跨。-
DateTime.Parse()
:【默認(rèn)】在未指定時(shí)區(qū)時(shí),
DateTime.Kind
是Unspecified
-
指定時(shí)區(qū):指定時(shí)區(qū)后
DateTime.Kind
就是相對(duì)應(yīng)的值扯饶。指定時(shí)區(qū)有2種方式:
- 【默認(rèn)+優(yōu)先】待轉(zhuǎn)換的字符串里有時(shí)區(qū)信息恒削。例如:
2019/11/24 17:40:32 +08:00
- 使用
DateTimeStyles
參數(shù)來(lái)指定時(shí)區(qū)。DateTimeStyles
是枚舉類(lèi)型尾序,更多信息自己查看定義钓丰,這里不再多說(shuō)。
- 【默認(rèn)+優(yōu)先】待轉(zhuǎn)換的字符串里有時(shí)區(qū)信息恒削。例如:
Local
和Utc
都會(huì)把相應(yīng)的時(shí)區(qū)傳遞過(guò)去每币。對(duì)于 Unspecified
(未指定)携丁,會(huì)被當(dāng)做本地時(shí)區(qū)來(lái)處理(結(jié)果已驗(yàn)證梦鉴,源碼沒(méi)看懂)。
測(cè)試代碼
//dtNow:2019/11/24 17:40:32(Kind:Local)
DateTime dtNow = DateTime.Now;
//dtUtcNow:2019/11/24 9:40:32(Kind:Utc)
DateTime dtUtcNow = DateTime.UtcNow;
//dtParse:2019/11/24 17:40:13(Kind:Unspecified)
DateTime dtParse = DateTime.Parse("2019-11-24 17:40:13");
//dtoNow:2019/11/24 17:40:32 +08:00
DateTimeOffset dtoNow = dtNow;
//dtoUtcNow:2019/11/24 9:40:32 +00:00
DateTimeOffset dtoUtcNow = dtUtcNow;
//dtoParse:2019/11/24 17:40:13 +08:00
DateTimeOffset dtoParse = dtParse;
Console.WriteLine("DateTime:");
Console.WriteLine("dtNow:{0}(Kind:{1})", dtNow, dtNow.Kind);
Console.WriteLine("dtUtcNow:{0}(Kind:{1})", dtUtcNow, dtUtcNow.Kind);
Console.WriteLine("dtParse:{0}(Kind:{1})", dtParse, dtParse.Kind);
Console.WriteLine();
Console.WriteLine("DateTimeOffset:");
Console.WriteLine("dtoNow:{0}", dtoNow);
Console.WriteLine("dtoUtcNow:{0}", dtoUtcNow);
Console.WriteLine("dtoParse:{0}", dtoParse);
輸出結(jié)果如下:
DateTime:
dtNow:2019/11/24 17:40:32(Kind:Local)
dtUtcNow:2019/11/24 9:40:32(Kind:Utc)
dtParse:2019/11/24 17:40:13(Kind:Unspecified)
DateTimeOffset:
dtoNow:2019/11/24 17:40:32 +08:00
dtoUtcNow:2019/11/24 9:40:32 +00:00
dtoParse:2019/11/24 17:40:13 +08:00
DateTimeOffset.Parse的默認(rèn)時(shí)區(qū)
DateTimeOffset.Parse
的默認(rèn)時(shí)區(qū)是當(dāng)前時(shí)區(qū)宠互。
//parse:2019/6/14 15:38:49 +08:00
Console.WriteLine("parse:{0}", DateTimeOffset.Parse("2019-6-14 15:38:49"));
參考
- C# DateTime與時(shí)間戳轉(zhuǎn)換:https://www.cnblogs.com/polk6/p/6024892.html
- 如何將Unix時(shí)間戳轉(zhuǎn)換為DateTime,反之亦然券册?:https://stackoverflow.com/questions/249760/how-can-i-convert-a-unix-timestamp-to-datetime-and-vice-versa
- DateTimeOffset源碼:https://source.dot.net/#System.Private.CoreLib/DateTimeOffset.cs