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

查看:64
本文介绍了从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 convert 我的 DateTimeOffset .也就是说,同时更改时间和时间区域偏移量.但是,我的测试表明此代码 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;

让我们分解一下:

  • 您以 DateTimeOffset 值为 2008-05-01T08:06:32 + 01:00
  • 开始
  • 然后您调用了 .DateTime ,这导致 DateTime 的值为 2008-05-01T08:06:32 DateTimeKind.Unspecified .
  • 然后您调用了 .Date ,这导致 DateTime 的值为 2008-05-01T00:00:00 DateTimeKind.Unspecified .
  • 您将结果分配回 DateTimeOffset 类型的 testDateAndTime .这会调用从 DateTime DateTimeOffset -的隐式强制转换,这将应用 local 时区.在您的情况下,该值在您当地的时区中显示为 -04:00 ,因此结果值为 2008-如您所描述的05-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#数据类型只是一个没有时间的日期.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:00 DateTimeKind.Unspecified DateTime .您必须记住要忽略时间部分(因为在某些时区中确实存在没有本地午夜的日期).
  • 将您的 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天全站免登陆