我遇到了以下需求的有趣问题: 测试过程是否在同一天运行,如果不运行该过程。日期存储为DataTimeOffset。DateTimeOffset当天比较
我最初的做法是:
- 都转换值UTC,因为可能在不同的时区中创建这些日期,并有不同的偏移。
- 查看每个值的日期值。这是在转换为UTC后完成的,因为Date方法会忽略偏移量。
大多数情况下,这工作,但我遇到了一种情况下,逻辑会失败。如果其中一个值的时间接近前一天/第二天,以便转换为UTC时它将更改日期。如果其他值没有时间也转换为前一天/下一天,则日期比较失败。
所以我结束了以下逻辑包括情景:
public static bool SameDate(DateTimeOffset first, DateTimeOffset second)
{
bool returnValue = false;
DateTime firstAdjusted = first.ToUniversalTime().Date;
DateTime secondAdjusted = second.ToUniversalTime().Date;
// If date is now a day ahead after conversion, than add/deduct a day to other date if that date hasn't advanced
if (first.Date < firstAdjusted.Date && second.Date == secondAdjusted.Date)
secondAdjusted = secondAdjusted.Date.AddDays(1);
if (first.Date > firstAdjusted.Date && second.Date == secondAdjusted.Date)
secondAdjusted = secondAdjusted.Date.AddDays(-1);
if (second.Date < secondAdjusted.Date && first.Date == firstAdjusted.Date)
firstAdjusted = firstAdjusted.Date.AddDays(1);
if (second.Date > secondAdjusted.Date && first.Date == firstAdjusted.Date)
firstAdjusted = firstAdjusted.Date.AddDays(-1);
if (DateTime.Compare(firstAdjusted, secondAdjusted) == 0)
returnValue = true;
return returnValue;
}
这里是被失败的,现在通过单元测试:
[TestMethod()]
public void SameDateTest()
{
DateTimeOffset current = DateTimeOffset.Now;
DateTimeOffset first = current;
DateTimeOffset second = current;
// 23 hours later, next day, with negative offset (EST) -- First rolls over
first = new DateTimeOffset(2014, 1, 1, 19, 0, 0, new TimeSpan(-5, 0, 0));
second = new DateTimeOffset(2014, 1, 2, 18, 0, 0, new TimeSpan(-5, 0, 0));
Assert.IsFalse(Common.SameDate(first, second));
// 23 hours earlier, next day, with postive offset -- First rollovers
first = new DateTimeOffset(2014, 1, 1, 4, 0, 0, new TimeSpan(5, 0, 0));
second = new DateTimeOffset(2014, 1, 2, 5, 0, 0, new TimeSpan(5, 0, 0));
Assert.IsFalse(Common.SameDate(first, second));
// 23 hours later, next day, with negative offset (EST) -- Second rolls over
first = new DateTimeOffset(2014, 1, 2, 18, 0, 0, new TimeSpan(-5, 0, 0));
second = new DateTimeOffset(2014, 1, 1, 19, 0, 0, new TimeSpan(-5, 0, 0));
Assert.IsFalse(Common.SameDate(first, second));
// 23 hours earlier, next day, with postive offset -- Second rolls over
first = new DateTimeOffset(2014, 1, 2, 5, 0, 0, new TimeSpan(5, 0, 0));
second = new DateTimeOffset(2014, 1, 1, 4, 0, 0, new TimeSpan(5, 0, 0));
Assert.IsFalse(Common.SameDate(first, second));
}
我的直觉是,有比基于其他值的递增/递减更清洁的方法。有更好的方法吗?
的主要标准:
- 调整两个日期为具有相同的偏移量。
- 只有在第一个和第二个日期都在同一日历日内发生,而不是在24小时内才返回true。
你所做的是一个肯定的迹象,表明方法很差。根据我的经验,处理日期/时间的最佳方法是将它们存储为UTC或具有特定偏移量。任何“数学”工作都会消失,现在您可以使用标准日期时间API转换为UI显示等。 – 2014-11-23 19:18:27
它们与偏移量一起存储,但偏移量不总是相同。例如,我们通常存储东部时区的偏移量,但取决于夏令时,它可以是-4或-5。 – Josh 2014-11-23 19:30:46
在您的示例中,使用带有和不带夏令时的东部时区,实际上应该表示为两个不同的时区:冬季的EST(UTC-0500)和夏季的EDT(UTC-0400)。 – 2014-11-23 19:42:33