C#中的时间戳

来源:https://blog.guoqianfan.com/2019/11/24/timestamp-in-csharp/

什么是时间戳

时间戳默认是Unix时间戳

首先要清楚JavaScript与Unix的时间戳的区别:

JavaScript时间戳:是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总毫秒数

Unix时间戳:是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数

可以看出JavaScript时间戳是总毫秒数,Unix时间戳是总秒数

比如同样是的 2016/11/03 12:30:00 ,转换为JavaScript时间戳为 1478147400000;转换为Unix时间戳为 1478147400。

从上面也可以看出时间戳与时区无关

Unix时间戳相互转换

C# DateTime转换为Unix时间戳

.NET 4.6新方法

只能在 .NET 4.6及更高版本里才能使用。

long timeStamp = DateTimeOffset.Now.ToUnixTimeSeconds(); // 相差秒数
Console.WriteLine(timeStamp);

通用的老方法

System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
long timeStamp = (long)(DateTime.Now - startTime).TotalSeconds; // 相差秒数
System.Console.WriteLine(timeStamp);

Unix时间戳转换为C# DateTime

.NET 4.6新方法

由时间戳转换的DateTimeOffset的时区默认是+00:00,此时我们需要转为本地时区,否则后续使用可能会有问题。

转为本地时区:DateTimeOffset.LocalDateTime

示例代码如下:

//默认为UTC时间:{2019/11/14 1:53:26 +00:00}
DateTimeOffset dto = DateTimeOffset.FromUnixTimeMilliseconds(1573696406184);
//默认为UTC时间:{2019/11/14 1:53:26}
DateTime dt01 = dto.DateTime;
//转为本地时区:{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)); // 当地时区
DateTime dt = startTime.AddSeconds(unixTimeStamp);
System.Console.WriteLine(dt.ToString("yyyy/MM/dd HH:mm:ss:ffff"));

备注

DateTimeOffset使用Now还是UtcNow

对于DateTimeOffset,发现有2个获取当前时间的属性:DateTimeOffset.NowDateTimeOffset.UtcNow

如果只是获取时间戳,这2个使用哪个都可以,得到的值是一样的。

因为DateTimeOffset里面有时区信息,获取时间戳时会使用时区进行转换的,所以获得的时间戳一样。

而也是因为时区的原因,DateTimeOffset的其他操作可能会不一样。例如DateTimeOffset.DateTime就不一样,此时推荐使用DateTimeOffset.LocalDateTime来获得本地时区的时间。

测试代码如下:

//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转换为DateTimeOffset

可以直接把DateTime赋值给DateTimeOffset,内部会自动进行隐式转换。这里涉及到时区,请往下看。

DateTime的时区信息(Kind属性)

DateTime时区信息存放在Kind属性里。Kind属性的数据类型是DateTimeKind枚举,只有3个值:

  • Unspecified:未指定/未规定
  • UtcUTC时间
  • Local:本地时区

不同情况下得到的DateTimeKind是不同的,具体如下:

  • DateTime.NowDateTime.KindLocal(本地时区)

  • DateTime.UtcNowDateTime.KindUtc

  • DateTime.Parse()

    • 默认】在未指定时区时,DateTime.KindUnspecified

    • 指定时区:指定时区后DateTime.Kind就是相对应的值。

      指定时区有2种方式:

      • 默认+优先待转换的字符串里有时区信息。例如:2019/11/24 17:40:32 +08:00
      • 使用DateTimeStyles参数来指定时区。DateTimeStyles是枚举类型,更多信息自己查看定义,这里不再多说。

LocalUtc都会把相应的时区传递过去。对于 Unspecified(未指定),会被当做本地时区来处理(结果已验证,源码没看懂)。

测试代码

//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);

输出结果如下:

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的默认时区

DateTimeOffset.Parse的默认时区是当前时区

//parse:2019/6/14 15:38:49 +08:00
Console.WriteLine("parse:{0}", DateTimeOffset.Parse("2019-6-14 15:38:49"));

参考

  1. C# DateTime与时间戳转换:https://www.cnblogs.com/polk6/p/6024892.html
  2. 如何将Unix时间戳转换为DateTime,反之亦然?:https://stackoverflow.com/questions/249760/how-can-i-convert-a-unix-timestamp-to-datetime-and-vice-versa
  3. DateTimeOffset源码:https://source.dot.net/#System.Private.CoreLib/DateTimeOffset.cs
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • MySql取得日期(前一天、某一天) 取得当天: SELECT curdate(); mysql> SELECT ...
    laravel阅读 1,589评论 0 4
  • 在Python中,日期和时间的应用非常普遍。在实际应用中,大部分数据的记录和日志的处理都需要使用时间。这里将介绍P...
    泷汰泱阅读 814评论 0 0
  • 时间(date time)应该是一个精确的点,以便能够进行比较。但是如何能让他成为一个精确的点呢?一般的,如果需要...
    远程板砖阅读 1,826评论 1 8
  • 【姓名】 程小平【日期:2018.10.12】第5天 【目标】我想要还清稠州银行债务,财务富足。 【计划】1.慷慨...
    lindacheng2017阅读 46评论 0 0
  • 今天来开封旅游,抽了三张卡代表带着怎么的自己,儿子,老公来旅游。 这一张是我:靓靓,28岁,迷惑。 愿望:高兴的玩...
    李娟AINI阅读 132评论 0 0