代码之家  ›  专栏  ›  技术社区  ›  Slavo

datetime.now与datetime.utcnow

  •  186
  • Slavo  · 技术社区  · 18 年前

    我一直在想,这两种性质的工作原理究竟是什么。我知道第二个是通用的,基本上不涉及时区,但是有人能详细解释它们是如何工作的,在什么情况下应该使用哪个时区吗?

    12 回复  |  直到 8 年前
        1
  •  297
  •   Leniel Maccaferri    12 年前

    DateTime.UtcNow 告诉你日期和时间,因为它将在协调世界时,也被称为格林威治标准时区-基本上就像你在伦敦,英国,但不是在夏天。 DateTime.Now 为当前区域设置中的某个人提供显示的日期和时间。

    我建议使用 DateTime.Now 每当你向一个人展示一个约会的时候——这样他们就会对他们看到的价值感到满意——这是他们可以很容易地与他们在手表或时钟上看到的相比的东西。使用 DateTime.UtcNow 当您想以这种方式(在客户机-服务器模型中)存储日期或将其用于以后的计算时,您的计算不会被来自您的服务器或彼此的不同时区的客户机混淆。

        2
  •  77
  •   Jeff Atwood    18 年前

    这真的很简单,所以我认为这取决于你的观众是什么,他们住在哪里。

    如果不使用UTC,则 必须 知道要向其显示日期和时间的人的时区——否则,您将告诉他们系统或服务器时间下午3点发生了什么事情,而实际发生的时间是下午5点,他们正好住在那里。

    我们使用 DateTime.UtcNow 因为我们有一个全球性的网络受众,而且我不想让每个用户都填写一个表格来说明他们居住的时区。

    我们还显示相对时间(2小时前,1天前等),直到岗位年龄足够大,时间是“相同的”,无论你住在地球上的什么地方。

        3
  •  25
  •   Magnus Krisell    17 年前

    还要注意性能差异:datetime.utcnow比datetime快30倍左右。现在,因为在内部datetime.now正在进行很多时区调整(您可以用reflector轻松地验证这一点)。

    所以不要使用日期时间。现在用相对时间测量。

        4
  •  25
  •   Carl Camera    9 年前

    在.NET中要理解的一个主要概念是 现在 是 现在 不管你在哪个时区,全世界都是如此。因此,如果您加载一个带有datetime.now或datetime.utcnow的变量——赋值是相同的。*您的datetime对象知道您所在的时区,并将其考虑在内,而不管赋值是什么。

    在计算跨越夏令时边界的日期时,datetime.utcnow的实用性非常有用。也就是说,在参加夏令时的地方,有时从中午到次日中午有25小时,有时从中午到次日中午有23小时。如果要正确确定时间A和时间B的小时数,在计算时间跨度之前,需要先将每个小时转换为其UTC等效值。

    这是由一个 blog post i wrote 这进一步解释了时间跨度,并包含一个链接,指向关于这个主题的更广泛的MS文章。

    *说明:任何一项任务都将存储当前时间。如果要加载两个变量,一个通过datetime.now()加载,另一个通过datetime.utcnow()加载,那么这两个变量之间的时间跨度差异将是毫秒,而不是小时(假设您在距gmt数小时的时区内)。如下面所述,打印出它们的字符串值将显示不同的字符串。

        5
  •  13
  •   Ted Bigham    11 年前

    这是个好问题。我正在重新激活它,以提供更多关于.NET如何使用不同的“种类”值的详细信息。正如@jan zich所指出的,它实际上是一个非常重要的属性,根据您现在使用还是使用utcnow设置不同。

    在内部,日期存储为“ticks”,这与@carl camera的答案相反,取决于您现在使用还是utcnow。

    datetime.utcnow的行为与其他语言类似。它将计时设置为基于GMT的值。它还将“kind”设置为“utc”。

    datetime.now将ticks值更改为 如果你在格林尼治标准时间区是一天中的某个时间,那会是什么? . 它还将“kind”设置为“local”。

    如果你落后6小时(格林尼治标准时间6),你将得到6小时前的格林尼治时间。.NET实际上忽略了“善良”,这次就像6小时前一样对待它,即使它应该是“现在”。如果您创建一个日期时间实例,然后更改您的时区并尝试使用它,则会破坏更多。

    具有不同“kind”值的日期时间实例不兼容。

    让我们看一些代码…

        DateTime utc = DateTime.UtcNow;
        DateTime now = DateTime.Now;
        Debug.Log (utc + " " + utc.Kind);  // 05/20/2015 17:19:27 Utc
        Debug.Log (now + " " + now.Kind);  // 05/20/2015 10:19:27 Local
    
        Debug.Log (utc.Ticks);  // 635677391678617830
        Debug.Log (now.Ticks);  // 635677139678617840
    
        now = now.AddHours(1);
        TimeSpan diff = utc - now;
        Debug.Log (diff);  // 05:59:59.9999990
    
        Debug.Log (utc <  now);  // false
        Debug.Log (utc == now);  // false
        Debug.Log (utc >  now);  // true
    
        Debug.Log (utc.ToUniversalTime() <  now.ToUniversalTime());  // true
        Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime());  // false
        Debug.Log (utc.ToUniversalTime() >  now.ToUniversalTime());  // false
        Debug.Log (utc.ToUniversalTime() -  now.ToUniversalTime());  // -01:00:00.0000010
    

    正如您在这里看到的,比较和数学函数不会自动转换为兼容时间。时间跨度应该是一个小时,但实际上是6个小时。”“UTC<now”应该是正确的(我甚至增加了一个小时来确定),但仍然是错误的。

    你也可以看到“周而复始”的意思,即只要“种类”不相同,就可以简单地转换成宇宙时间。

    我对这个问题的直接回答与公认的关于何时使用每个答案的建议一致。你应该永远 尝试 使用kind=utc的日期时间对象,但在I/O(显示和分析)期间除外。这意味着您几乎应该总是使用datetime.utcnow,除非您创建对象只是为了显示它,并立即丢弃它。

        6
  •  6
  •   Omer van Kloeten    18 年前

    日期时间不知道时区是什么。它总是假设你在当地时间。 UTCNW 只表示“从时间中减去我的时区”。

    如果要使用时区感知日期,请使用 数据偏移 ,表示具有时区的日期/时间。我不得不用一种艰苦的方式来学习。

        7
  •  4
  •   Jan Zich    17 年前

    只需在上面的点上添加一点:datetime结构还包含一个鲜为人知的字段,名为 Kind (至少,我已经很久不知道了)。它基本上只是一个标志,指示时间是本地时间还是UTC;它没有为本地时间指定与UTC的实际偏移量。除了说明了stuct的构建意图之外,它还影响了方法的构建方式 ToUniversalTime() 和 ToLocalTime() 工作。

        8
  •  4
  •   PapillonUK    14 年前

    这个问题的“简单”答案是:

    日期时间 返回A 日期时间 表示当前系统时间的值(在系统运行的任何时区中)。这个 日期时间 属性将为 日期时间类型.本地

    数据处理程序 返回A 日期时间 表示当前通用协调时间(即UTC)的值,不管系统的时区是什么,该值都是相同的。这个 日期时间 属性将为 日期时间类型.utc

        9
  •  2
  •   Sorin Comanescu    15 年前
        10
  •  1
  •   user1315023    12 年前

    datetime.utcnow是一个连续的单值时间刻度,而datetime.now不是连续的或单值的。主要原因是夏令时,这不适用于UTC。所以UTC从不向前或向后跳一个小时,而本地时间(datetime.now)是这样。当它向后跳时,相同的时间值会出现两次。

        11
  •  1
  •   ChaiVan    8 年前

    datetime.utcnow是一个省略夏令时的通用时间刻度。因此,UTC从不因DST而改变。

    但是,datetime.now不是连续的或单值的,因为它根据dst变化。这意味着日期时间。现在,相同的时间值可能会出现两次,使客户处于混乱状态。

        12
  •  0
  •   kender    18 年前

    如果您的应用程序运行的计算机需要本地时间(如欧洲的CEST),请立即使用。如果你想要一个世界性的时间-联合技术合作。这只取决于你的喜好-可能是制作一个本地网站/独立的应用程序,你想使用用户的时间-所以受他/她的时区设置-datetime的影响。

    记住,对于一个网站来说,它是服务器的时区设置。因此,如果您要为用户显示时间,请获取他喜欢的时区并切换时间(只需将UTC时间保存到数据库中,然后进行修改),或者指定该时间为UTC。如果忘记了这样做,用户可以看到如下内容: 3分钟前发布 然后在未来的某个时候靠近它:)

    推荐文章