【问题标题】:change DateTime based on specifyKind change [duplicate]根据指定类型更改日期时间 [重复]
【发布时间】:2019-11-12 16:35:09
【问题描述】:

DateTime 类型有一个名为“DateTimeKind”的枚举属性,可以设置为以下之一:“Local”、“Unspecified”和“Utc”。

当从数据库中以 'datetime' 格式查询值时,如果使用 Dapper 进行查询,则此 DateTimeKind 为 'Unspecified',然后在 'DateTimeOffset' 对象中实例化时自动计算到本地时间的时间。

当前的后端标准是 Utc,我想创建一个属性来处理这个“DateTimeKind”值,默认为“Utc”,因为这是预期的。

不仅如此,我还想创建一些辅助函数自动转换日期时间值以及将指定类型设置为“Utc”,如果它是作为不同类型提供的。

一个简单的想法是在 setter 中处理类似的东西:

    private DateTime? _someValue;
    [DataMember]
    public DateTime? SomeValue
    {
        get
        {
            return _someValue;
        }
        set
        {
            if (value.HasValue)
            {
                 //Todo: do something more such as converting datetime value as well if DateTimeKind was not Utc as coming in..
                _someValue = DateTime.SpecifyKind(value.Value, DateTimeKind.Utc);
            }
        }
    }

如果有已知的方法可以不重新发明轮子,请告诉我。

【问题讨论】:

  • 您能否澄清您所说的“然后自动计算本地时间的时间作为在 DateTimeOffset 对象中实例化的时间”?目前尚不清楚您要实现什么 - 包括“创建一些辅助函数自动转换日期时间值”的意思。如果您想保留当前日期/时间值,但只是将 Kind 更改为 UTC,那么您已经在做正确的事情了……如果您的数据库正在存储 UTC,听起来就像这样你想做的。
  • @swcraft - 关于 Dapper,我将作为重复关闭。请参阅 that answer 了解如何告诉 Dapper 您希望所有 DateTime 值都设置为 DateTimeKind.Utc。如果您的问题比这更笼统,请告诉我。
  • @JonSkeet - 如果日期时间值以 DateTime.Kind = 'Local' 的形式出现,那么我想使用 DateTime.Kind = 'Utc' 将其转换为 Utc 时间。我编辑了下面的答案,以便更精确地处理不同的场景。谢谢。
  • @swcraft:所以您想在 那种 的情况下执行时区转换,但不是在它有一种未指定的情况下,大概?我怀疑你会想为此编写一个方法。
  • @JonSkeet - 你是对的,我最终写了一个 DateTime 的扩展方法。

标签: c# datetime


【解决方案1】:

你可以在 setter 中使用DateTime.ToUniversalTime()

    private DateTime? _someValue;
    [DataMember]
    public DateTime? SomeValue
    {
        get
        {
            return _someValue;
        }
        set
        {
            if (value.HasValue)
            {
                if(value.Kind == DateTimeKind.Local)
                {
                   _someValue = value.Value.ToUniversalTime();
                }
                else if(value.Kind == DateTimeKind.Unspecified)
                {
                   _someValue = DateTime.SpecifyKind(value, DateTimeKind.Utc)
                }
            }
        }
    }

【讨论】:

  • 这会自动将 Kind 设置为 Utc 吗?
  • 它将强制在返回的 DateTime 中使用 DateTImeKind.Utc。
  • 注意,如果 value 的 DateTimeKind 是 Unspecified,它将被认为是通用时间,不改变时区。
  • @hal:不,会被视为local,进行时区转换。从您链接到的文档中的注释中:“未指定当前的 DateTime 对象被假定为本地时间,并且转换的执行就像 Kind 是 Local 一样。”如果我正确理解它们,那不是 OP 想要做的(虽然不是很清楚)
  • @swcraft:您目前已经接受了这个答案 - 我强烈建议您检查您是否确实想要执行本地 -> UTC 转换。跨度>
【解决方案2】:

DateTime 是不可变结构,你不能修改任何东西。

您必须在创建结构时设置 DateTimeKind,许多构造函数中的一些包括 DateTimeKind。

默认是 DateTimeKind.unspecified,这是决定性的,因为你没有指定它。

如果你想明确的话,你可以这样做。

  DateTime time2 = new DateTime(time1.Ticks, DateTimeKind.Utc) 

这是一个廉价的操作,因为它是一个结构。这里并不是真正在堆上分配内存。

【讨论】:

  • 我认为使用 DateTime.SpecifyKind 是一种更清晰的方法。
  • 是的,就口味而言,一个和另一个一样好。想指出是怎么回事,而且这个设置与转化无关,更多的是附加信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多