从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

我应该如何修改我的代码,使其在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;

让我们来分解一下:

  • 您从DateTimeOffset2008-05-01T08:06:32+01:00开始
  • 然后调用.DateTime,结果DateTime值为2008-05-01T08:06:32DateTimeKind.Unspecified
  • 然后调用.Date,结果DateTime值为2008-05-01T00:00:00DateTimeKind.Unspecified
  • 将结果分配回类型为DateTimeOffsettestDateAndTime。这将调用从DateTimeDateTimeOffset-的隐式转换,该转换应用本地时区。在您的情况下,本地时区中该值的偏移量似乎是-04:00,因此生成的值是2008-05-01T00:00:00-04:00DateTimeOffset,如您所述

你说:

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

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

  • 将SQL Server更改为在字段中使用date类型
  • 在.NET代码中,使用时间为00:00:00DateTimeKind.UnspecifiedDateTime。你必须记住忽略时间部分(因为在某些时区确实有没有当地午夜的日期)
  • 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。请注意转换中日期的更改。这可能不是您希望悄悄进入应用程序的行为。

相关内容

  • 没有找到相关文章

最新更新