Remove Time Zone Offset from DateTimeOffset?(从 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 的 - 然后您调用了
.DateTime,这导致2008-05-01T08:06:32的DateTime值与DateTimeKind.Unspecified. - 然后您调用了
.Date,这导致2008-05-01T00:00:00的DateTime值与DateTimeKind.Unspecified. - 您将结果分配回
testDateAndTime,它的类型为DateTimeOffset.这会调用从DateTime到DateTimeOffset的隐式转换 - 应用 本地 时区.在您的情况下,您当地时区的此值的偏移量似乎是-04:00,因此结果值是2008- 的,如你所述.DateTimeOffset05-01T00:00:00-04:00
DateTimeOffset 值开始- You started with a
DateTimeOffsetvalue of2008-05-01T08:06:32+01:00 - You then called
.DateTime, which resulted in aDateTimevalue of2008-05-01T08:06:32withDateTimeKind.Unspecified. - You then called
.Date, which resulted in aDateTimevalue of2008-05-01T00:00:00withDateTimeKind.Unspecified. - You assign the result back to
testDateAndTime, which is of typeDateTimeOffset. This invokes an implicit cast fromDateTimetoDateTimeOffset- 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 aDateTimeOffsetof2008-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:00和DateTimeKind.Unspecified的DateTime.您必须记住忽略时间部分(因为在某些时区确实存在没有当地午夜的日期). - 将您的
test属性更改为DateTime,而不是DateTimeOffset.
- Change your SQL Server to use a
datetype in the field. - In your .NET code, use a
DateTimewith a time of00:00:00andDateTimeKind.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
testprop to be aDateTime, not aDateTimeOffset.
一般来说,虽然 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 中删除时区偏移量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从 DateTimeOffset 中删除时区偏移量?
基础教程推荐
- 从 VS 2017 .NET Core 项目的发布目录中排除文件 2022-01-01
- JSON.NET 中基于属性的类型解析 2022-01-01
- 在 VS2010 中的 Post Build 事件中将 bin 文件复制到物 2022-01-01
- 首先创建代码,多对多,关联表中的附加字段 2022-01-01
- 如何动态获取文本框中datagridview列的总和 2022-01-01
- 经典 Asp 中的 ResolveUrl/Url.Content 等效项 2022-01-01
- 错误“此流不支持搜索操作"在 C# 中 2022-01-01
- 将事件 TextChanged 分配给表单中的所有文本框 2022-01-01
- 全局 ASAX - 获取服务器名称 2022-01-01
- 是否可以在 asp classic 和 asp.net 之间共享会话状态 2022-01-01
