此代码:
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
我应该如何修改我的代码,使其在testDateAndTime
中将时区偏移从-4:00
更改为+00:00
?
我也试过:
public Task<DateTimeOffset> SetTimeZoneOffsetToZero(DateTimeOffset dateTimeOffSetObj)
{
TimeSpan zeroOffsetTimeSpan = new TimeSpan(0, 0, 0, 0, 0);
return dateTimeOffSetObj.ToOffset(zeroOffsetTimeSpan);
}
但那个代码没有任何作用。
我的最终目标只是有一个没有时间或时区偏移的日期。我不想将时间转换为另一个时区。(也就是说,我不想从00:00:00.0000000
时间中减去4小时,并将设置的时间偏移量删除为+00:00
。我只想将偏移量设置为+00:00
。)
这是我在其他地方遇到的另一种方法:
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
。也就是说,同时更改时间和时区偏移量。但是,我的测试表明,这段代码只是更改了时区偏移量,这正是我想要的。这样做有问题吗?
这个问题实际上与数据库无关。如果您设置了一个断点或将输出记录在某个地方,那么您应该能够在以下代码之后不久看到被附加的偏移:
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
-的隐式转换,该转换应用本地时区。在您的情况下,本地时区中该值的偏移量似乎是-04:00
,因此生成的值是2008-05-01T00:00:00-04:00
的DateTimeOffset
,如您所述
你说:
最终目标只是有一个没有时间或时区偏移的日期。
嗯,目前没有本机C#数据类型,它只是一个没有时间的日期。corefxlab中的System.Time包中有一个纯Date
类型,但它还没有完全准备好用于典型的生产应用程序。Noda Time库中有LocalDate
,您现在可以使用,但在保存到数据库之前,您仍然必须转换回本机类型。因此,在此期间,你能做的最好的事情就是:
- 将SQL Server更改为在字段中使用
date
类型 - 在.NET代码中,使用时间为
00:00:00
和DateTimeKind.Unspecified
的DateTime
。你必须记住忽略时间部分(因为在某些时区确实有没有当地午夜的日期) - 将
test
道具更改为DateTime
,而不是DateTimeOffset
一般来说,虽然DateTimeOffset
适用于大量场景(如时间戳事件),但它不太适合仅限日期的值。
我想要当前日期,零偏移。
如果您真的想要将其作为DateTimeOffset
,您可以这样做:
testDateAndTime = new DateTimeOffset(testDateAndTime.Date, TimeSpan.Zero);
然而,我建议不要这样做。通过这样做,您获得了原始值的本地日期,并断言它是UTC。如果原始偏移量不是零,那将是一个错误的断言。这势必会导致以后出现其他错误,因为你实际上谈论的是与你创建的时间点不同的时间点(可能有不同的日期)。
关于编辑中提出的附加问题-指定DateTimeKind.Utc
会更改隐式强制转换的行为。它不使用本地时区,而是使用UTC时间,该时间的偏移量始终为零。结果与我上面给出的更明确的形式相同。出于同样的原因,我仍然建议不要这样做。
考虑一个从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
。请注意转换中日期的更改。这可能不是您希望悄悄进入应用程序的行为。