从 DateTimeOffset 中删除时区偏移量? [英] Remove Time Zone Offset from DateTimeOffset?

查看:46
本文介绍了从 DateTimeOffset 中删除时区偏移量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这段代码:

DateTimeOffset testDateAndTime =
    new DateTimeOffset(2008, 5, 1, 8, 6, 32, new TimeSpan(1, 0, 0));

//CLEAN TIME AND DATE 
testDateAndTime = testDateAndTime.DateTime.Date; 

var datesTableEntry = db.DatesTable.First(dt => dt.Id == someTestId);
datesTableEntry.test= testDateAndTime;

db.SaveChangesAsync(); 

...在我的数据库中产生这个结果:2008-05-01 00:00:00.0000000 -04:00

...produces this result in my database: 2008-05-01 00:00:00.0000000 -04:00

我应该如何修改我的代码,以便在 testDateAndTime 中将时区偏移量从 -4:00 更改为 +00:00?

How should I revise my code so that it changes the time zone offset from -4:00 to +00:00 in testDateAndTime?

我也试过了:

public Task<DateTimeOffset> SetTimeZoneOffsetToZero(DateTimeOffset dateTimeOffSetObj)
{
    TimeSpan zeroOffsetTimeSpan = new TimeSpan(0, 0, 0, 0, 0);
    return dateTimeOffSetObj.ToOffset(zeroOffsetTimeSpan);
}

...但是那段代码什么也没做.

...but that code doesn't do anything.

我的最终目标只是有一个没有时间或时区偏移的日期.我确实想将时间转换为另一个时区.(也就是说,我不想从 00:00:00.0000000 时间中减去 4 小时,并将设置的时间偏移量删除为 +00:00.我 只是想将偏移量设置为+00:00.)

My end goal is just to have a date without a time or a time zone offset. I do not want to convert the time to another time zone. (That is, I don't want to subtract 4 hours from the 00:00:00.0000000 time and remove set time offset to +00:00. I just want to set the offset to +00:00.)

这是我在其他地方遇到的另一种方法:

Here is another approach that I came across elsewhere:

DateTimeOffset testDateAndTime =
    new DateTimeOffset(2008, 5, 1, 8, 6, 32, new TimeSpan(1, 0, 0));

testDateAndTime = testDateAndTime.DateTime.Date; //Zero out time portion

testDateAndTime = DateTime.SpecifyKind(
    testDateAndTime.Date, DateTimeKind.Utc); //"Zero out" offset portion

我确信 SpecifyKind转换我的 DateTimeOffset.也就是说,改变both时间时区偏移.但是,我的测试表明此代码 just 更改了时区偏移量,这正是我想要的.这样做有问题吗?

I was sure that SpecifyKind would convert my DateTimeOffset. That is, change both the time and the time zone offset. But, my test indicates that this code just changes the time zone offset, which is what I want. Is there a problem with doing it this way?

推荐答案

这个问题实际上和数据库没有任何关系.如果您在某处设置断点或记录输出,您应该能够看到在此代码之后不久添加的偏移量:

The issue doesn't have anything to do with the database actually. If you set a breakpoint or log the output somewhere, you should be able to see the offset being tacked on shortly after this code:

testDateAndTime = testDateAndTime.DateTime.Date;

让我们分解一下:

  • 您从 2008-05-01T08:06:32+01:00
  • DateTimeOffset 值开始
  • 然后您调用了 .DateTime,这导致 2008-05-01T08:06:32DateTime 值与 DateTimeKind.Unspecified.
  • 然后您调用了 .Date,这导致 2008-05-01T00:00:00DateTime 值与 DateTimeKind.Unspecified.
  • 您将结果分配回 testDateAndTime,它的类型为 DateTimeOffset.这会调用从 DateTimeDateTimeOffset 的隐式转换 - 应用 本地 时区.在您的情况下,您当地时区的此值的偏移量似乎是 -04:00,因此结果值是 2008- 的 DateTimeOffset05-01T00:00:00-04:00,如你所述.
  • You started with a DateTimeOffset value of 2008-05-01T08:06:32+01:00
  • You then called .DateTime, which resulted in a DateTime value of 2008-05-01T08:06:32 with DateTimeKind.Unspecified.
  • You then called .Date, which resulted in a DateTime value of 2008-05-01T00:00:00 with DateTimeKind.Unspecified.
  • You assign the result back to testDateAndTime, which is of type DateTimeOffset. This invokes an implicit cast from DateTime to DateTimeOffset - which applies the local time zone. In your case, it would appear the offset for this value in your local time zone is -04:00, so the resulting value is a DateTimeOffset of 2008-05-01T00:00:00-04:00, as you described.

你说:

最终目标只是有一个没有时间或时区偏移的日期.

End goal is just to have a date without time or time zone offset.

嗯,目前没有原生 C# 数据类型,它只是一个没有时间的日期.System.Time 包中有一个纯 Date 类型corefxlab,但这还没有为典型的生产应用程序做好准备.Noda Time 库中有 LocalDate,您现在可以使用,但您仍然必须使用在保存到数据库之前转换回本机类型.因此,与此同时,您能做的最好的事情是:

Well, there is currently no native C# data type that is just a date without a time. There is a pure Date type in the System.Time package in corefxlab, but that's not quite ready for the typical production application. There's LocalDate in the Noda Time library that you can use today, but you'd still have to convert back to a native type before saving to the database. So in the meantime, the best you can do is:

  • 将您的 SQL Server 更改为在字段中使用 date 类型.
  • 在您的 .NET 代码中,使用时间为 00:00:00DateTimeKind.UnspecifiedDateTime.您必须记住忽略时间部分(因为在某些时区确实存在没有当地午夜的日期).
  • 将您的 test 属性更改为 DateTime,而不是 DateTimeOffset.
  • Change your SQL Server to use a date type in the field.
  • In your .NET code, use a DateTime with a time of 00:00:00 and DateTimeKind.Unspecified. You'll have to remember to ignore the time portion (as there are indeed dates without a local midnight in certain time zones).
  • Change your test prop to be a DateTime, not a DateTimeOffset.

一般来说,虽然 DateTimeOffset 适合大量场景(例如 timestamping 事件),但它不太适合仅日期值.

In general, while DateTimeOffset fits a large number of scenarios (such as timestamping events), it doesn't fit well for date-only values.

我想要当前日期,偏移量为零.

I want the current date, with zero offset.

如果你真的想要这个作为 DateTimeOffset,你会这样做:

If you really want this as a DateTimeOffset, you'd do:

testDateAndTime = new DateTimeOffset(testDateAndTime.Date, TimeSpan.Zero);

但是,我建议不要这样做.通过这样做,您将获取原始值的 local 日期并断言它是 UTC.如果原始偏移量不是零,那将是错误的断言.以后肯定会导致其他错误,因为您实际上是在谈论与您创建的时间点不同的时间点(可能是不同的日期).

However, I advise against this. By doing so, you're taking the local date of the original value and asserting that it is in UTC. If the original offset is anything other than zero, that would be a false assertion. It is bound to lead to other errors later, as you're actually talking about a different point in time (with potentially a different date) than the one you created.

关于您在编辑中提出的附加问题 - 指定 DateTimeKind.Utc 会更改隐式转换的行为.它不使用本地时区,而是使用 UTC 时间,其偏移量始终为零.结果与我上面给出的更明确的形式相同.出于同样的原因,我仍然建议不要这样做.

Regarding the additional question asked in your edit - Specifying DateTimeKind.Utc changes the behavior of the implicit cast. Instead of using the local time zone, it uses UTC time, which always has an offset of zero. The result is the same as the more explicit form I gave above. I still recommend against this, for the same reasons.

考虑以 2016-12-31T22:00:00-04:00 开头的示例.通过您的方法,您可以将 2016-12-31T00:00:00+00:00 保存到数据库中.然而,这是两个非常不同的时间点.标准化为 UTC 的第一个将是 2017-01-01T02:00:00+00:00,而转换为另一个时区的第二个将是 2016-12-30T20:00:00-04:00.注意转换中日期的变化.这可能不是您希望潜入应用程序的行为.

Consider an example of starting with 2016-12-31T22:00:00-04:00. By your approach, you'd save into the database 2016-12-31T00:00:00+00:00. However these are two very different points in time. The first one normalized to UTC would be 2017-01-01T02:00:00+00:00, and the second one converted to the other time zone would be 2016-12-30T20:00:00-04:00. Notice the change of dates in the conversion. This is probably not the behavior you'd want creeping into your application.

这篇关于从 DateTimeOffset 中删除时区偏移量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆