(此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注。)

题记:新年第一篇文章,就来谈谈关于时间的简单技术问题:该用DateTime还是DateTimeOffset?该用Now还是UtcNow?

首先需要说明的是.NET中出现两个保存时间的数据结构是由于历史的原因。DateTime一开始就出现在.NET的基础类型中;为了解决DateTime中的一些缺陷,又保证代码能够兼容,就多出了一个DateTimeOffset。

DateTime只保存两部分信息:Ticks和Kind。一个Tick是100纳秒(1万Tick等于1毫秒),Ticks记录了从1/1/0001 12:00 AM到现在经过了多少100纳秒。Kind保存的是DateTimeKind枚举值,有Utc、Local和Unspecified 。Utc意味着Tick计数表示协调世界时间的数量,其不会受到夏令时或者时区的影响。Local表示本地时间的数量,会受到夏令时的影响。由于DateTime并不保存时区偏移,所以要获得真正的UTC时间,就会检查计算机当前的市区设置,那么ToUniversalTime和ToLocalTime方法都会进行这样的转换。Kind的第三种值Unspecified,意味着我们不知道到底是本地时间还是UTC时间。所以这种情况只能表示年月日,时间无法精确表示。

DateTime除了存在这个问题,还会在进行比较的时候,其不会考虑Kind是UTC还是Local,从而导致错误。DateTime在进行字符串化的时候,对于某些标准格式也会出现问题(根源还是时区的问题),比如ToString("u")的时候,会直接把Local当作UTC来处理。

为了解决上述时区和转换的问题,DateTimeOffset应运而生。它只保存Ticks,不保存Kind,且Ticks总是相对于UTC的值。

从官方文档给出的建议来看,我们总是应该使用DateTimeOffset,只有仅仅表示日期和不需要关心时区的时候才使用DateTime。https://msdn.microsoft.com/en-us/library/bb384267.aspx

另外,在Stackoverflow上的这个回答http://stackoverflow.com/a/14268167,也很形象的描述了DateTimeOffset和DateTime的区别和优势。简而言之,DateTimeOffset是一种瞬时时间(即绝对时间),DateTime是一种历法时间(即钟表时间)。

最后,这两个数据类型都有Now和UtcNow两个方法。Now用于获取现在的时间,UtcNow获取Utc的现在时间。而实际上,Now内部是先调用UtcNow,然后进行转换得到。所以,在一般情况下,都应该使用UtcNow。

在文章结束的时候,给大家留个小问题,协调世界时间(Coordinated Universal Time)的简写为什么是UTC,而不是CUT?下次文章公布答案。

DateTime还是DateTimeOffset?Now还是UtcNow?的更多相关文章

  1. 重学c#系列——datetime 和 datetimeoffset[二十一]

    前言 简单介绍一下datetime和 datetimeoffset. 正文 了解一个国家的文化,就要了解一个国家的历史. 要了解datetimeoffset,那么很有必要了解一下datetime. 表 ...

  2. DateTime , DateTime2 ,DateTimeOffset 之间的小区别

    闲来无事列了个表比对一下这3兄弟之间还是有一点差距的╮(╯_╰)╭   DateTime DateTime2 DateTimeOffset 日期范围 1753-01-01到 9999-12-31 00 ...

  3. 第二节:比较DateTime和DateTimeOffset两种时间类型并介绍Quartz.Net中用到的几类时间形式(定点、四舍五入、倍数、递增)

    一. 时间的类型 1. 背景 这里为什么要介绍时间类型呢,明明是定时调度篇,原因是在定时任务中,任务什么时间开始执行,什么时间结束执行,要用到各种各样的时间模式,虽然这不能算是一个复杂的问题,但在正式 ...

  4. C#中 DateTime , DateTime2 ,DateTimeOffset 之间的小区别 (转载)

    闲来无事列了个表比对一下这3兄弟之间还是有一点差距的╮(╯_╰)╭   DateTime DateTime2 DateTimeOffset 日期范围 1753-01-01到 9999-12-31 00 ...

  5. DateTime和DateTimeOffset的区别

    1,DateTime 表示时间上的一刻,通常以日期和当天时间来表示. 2, DateTimeOffset 表示一个时间点,通常以相对于协调世界时(UTC)的日期和时间来表示. 3,下面是微软官方给出的 ...

  6. .NETFramework:DateTimeOffset

    ylbtech-.NETFramework:DateTimeOffset 表示一个时间点,通常相对于协调世界时(UTC)的日期和时间来表示. 1.程序集 mscorlib, Version=4.0.0 ...

  7. .NET: C#: Datetime

    比较简单的类,一般用到它的属性.经常会用到的是DateTime.Now和DateTime.Now.TimeOfDay; using System; using System.Collections.G ...

  8. datetime & time

    python有两个和时间相关的模块,datetime和time datetime datetime模块下有四个类 date     日期相关的 time          时间相关的 datetime ...

  9. 08 datetime与logging模块(进阶)

    datetime与logging模块 阶段一:日期与时间 1.datetime 模块中 主要类: 类名 功能说明 date 日期对象,常用的属性有year, month, day time 时间对象h ...

随机推荐

  1. 如何解决phpcms后台验证码不显示的问题

    方法一: 主要在于是否开启gd库 查看办法 找到php.ini文件 搜索extension=php_gd2.dll这段代码(windows) 然后把前面的;符号去掉即可. centOS6.5中可能需要 ...

  2. fstream的使用方法介绍

    转载自:  fstream的使用方法介绍 - saga's blog - C++博客 http://www.cppblog.com/saga/archive/2007/06/19/26652.html ...

  3. Unity3d 制作物品平滑运动

    直接贴代码了 using UnityEngine; using System; using System.Collections; using System; using DataTable; pub ...

  4. iOS 在类别里添加成员变量的方法:objc_setAssociatedObject

    今天在github上查看MJPopupViewController这个项目,发现里面用到了objc_setAssociatedObject,用来为类别添加成员变量. 我百度之后,发现有人是这样说明的: ...

  5. echo 单引号和双引号

    echo输出 $key=value echo "$key" echo 后面带双引号的话,双引号里面的内容会翻译,输出value echo '$key' echo后面带单引号的话,双 ...

  6. google 语音api

    mdeia.Source = new Uri("http://translate.google.cn/translate_tts?ie=UTF-8&q=你好&tl=zh-CN ...

  7. 利用冒泡对List排序

    SysMenu是List集合中的类型,在这是一个菜单实体. public List<SysMenu> selfMenuSort(List<SysMenu> list) { fo ...

  8. Luncence .Net 使用

    public partial class Form1 : Form { public Form1() { InitializeComponent(); } //标准分词 private void bu ...

  9. 【python】多进程学习

    来源:廖雪峰 讲解看来源吧 把例子记一下 1.用fork创建进程 import os print "Process (%s) start..." % os.getpid() pid ...

  10. POJ 1222 EXTENDED LIGHTS OUT (高斯消元)

    题目链接 题意:5*6矩阵中有30个灯,操作一个灯,周围的上下左右四个灯会发生相应变化 即由灭变亮,由亮变灭,如何操作使灯全灭? 题解:这个问题是很经典的高斯消元问题.同一个按钮最多只能被按一次,因为 ...