我正在从数据库中获取日期,对于每个日期,我想更改从数据库获取的DateTime开始的时间,直到到达给定的固定时间(Y)。但是,(Y)可能在第二天。
例如,如果数据库中的日期为[7/6/2017 5:00:00 AM],并且给定的“固定时间”为10:00 PM,那么我想获取[7/6/2017 10:00: 00 PM]。
但是,如果固定时间为02:00 AM,那么我想得到[7/7/2017 02:00:00 AM](请注意,日期增加了一个)
注意:代码正在运行,但是我修改了代码以使其更短,更有意义。因此,可能存在语法或拼写错误。
我的第一个解决方案是这样的:
private DateTime setTimeForeward(DateTime date) {
DateTime today = DateTime.ParseExact(FixedTime, "hh:mm tt", CultureInfo.InvariantCulture);
TimeSpan difference = today.TimeOfDay - date.TimeOfDay;
return date + difference;
}
当固定时间为02:00 AM时,此操作未按预期工作。差异变为负数(不全天候),日期将为[7/6/2017 02:00:00 AM]。
我最终得到了以下代码
private DateTime setTimeForeward(DateTime date) {
DateTime today = DateTime.ParseExact(FixedTime "hh:mm tt", CultureInfo.InvariantCulture);
TimeSpan difference = today.TimeOfDay - date.TimeOfDay;
if (difference.Hours < 0) {
difference += new TimeSpan(24, 0, 0);
}
return date + difference;
}
我不确定我的功能在逻辑上是否正确,我觉得自己想得太多了。另外,我不确定是否有更好的方法或内置函数可以满足我的需求。基本上,我正在寻找正确且优雅的解决方案。
非常感谢您。
答案 0 :(得分:2)
在这种方法中,我使用DateTime fixedTime
来表示时间。我不太在意它的Day, Month, and Year
值。
static DateTime GetClosingTime(DateTime fixedTime, DateTime dbTime)
{
var cutoff = new DateTime(dbTime.Year, dbTime.Month, dbTime.Day, fixedTime.Hour, fixedTime.Minute, fixedTime.Second);
if (dbTime < cutoff)
return cutoff;
else
{
cutoff = cutoff.AddDays(1);
return cutoff;
}
}
在此使用您提供的示例输入进行调用。
var FixedTime10PM = new DateTime(1, 1, 1, 22, 0, 0);
var FixedTime02AM = new DateTime(1, 1, 1, 2, 0, 0);
var dbTime = new DateTime(2018, 6, 20, 5, 0, 0);
var dt1 = GetClosingTime(FixedTime10PM, dbTime);
var dt2 = GetClosingTime(FixedTime02AM, dbTime);
Console.WriteLine(dt1.ToLongDateString() + " " + dt1.ToLongTimeString());
Console.WriteLine(dt2.ToLongDateString() + " " + dt2.ToLongTimeString());
这是我的输出:
基于注释建议的简化方法:
static DateTime GetClosingTime(DateTime fixedTime, DateTime dbTime)
{
var cutoff = new DateTime(dbTime.Year, dbTime.Month, dbTime.Day, fixedTime.Hour, fixedTime.Minute, fixedTime.Second);
return dbTime < cutoff ? cutoff : cutoff.AddDays(1);
}
答案 1 :(得分:1)
您的逻辑几乎是正确的,但是您不应该检查difference.Hours
,因为可能会在几分钟(甚至是几秒钟,如果您稍后更改格式)之间有所不同。>
我调整了您的函数并更改了一些变量名称,以使它们更易于使用:
private DateTime SetTimeForward(DateTime originalDate)
{
TimeSpan newTime = DateTime.ParseExact(FixedTime,
"hh:mm tt",
CultureInfo.InvariantCulture).TimeOfDay;
TimeSpan diff = newTime - originalDate.TimeOfDay;
if (diff.Ticks < 0)
diff = diff.Add(new TimeSpan(24, 0, 0));
return originalDate.Add(diff);
}
一些评论:
如果您的FixedTime
确实是 固定的,则您可能希望将其直接存储为TimeSpan
,因此不必每次都进行解析。
如果因为FixedTime
可变而解析了它,则可以将其作为第二个参数传递:
private DateTime SetTimeForward(DateTime originalDate, string fixedTime)
或者:
private DateTime SetTimeForward(DateTime originalDate, TimeSpan newTime)
如果newTime
等于originalDate.TimeOfDay
,则当前实现不会 不 更改日期值。即,如果originalDate
为7/6/2017 2:00 AM
,而FixedTime
/ newTime
为02:00 AM
,则返回的日期将等于originalDate
。如果这不是您想要的行为,则可以将diff.Ticks < 0
更改为diff.Ticks <= 0
。
答案 2 :(得分:1)
稍有不同的方法:
private DateTime setTimeForeward(DateTime date)
{
var targetTimeOfDay = TimeSpan.ParseExact(FixedTime, "hh:mm tt", CultureInfo.InvariantCulture);
if (targetTimeOfDay < date.TimeOfDay)
{
date = date.AddDays(1);
}
return date.Date + targetTimeOfDay;
}
我从一开始就将目标时间作为TimeSpan,而不是创建DateTime并获取TimeOfDay(即TimeSpan)。
然后,我检查目标一天中的时间是否低于要修改的时间,如果是,则增加一天。
我使用date.Date + targetTimeOfDay
作为返回值,因为date.Date
将返回日期,时间设置为00:00,并且向其添加目标时间将已经设置目标小时,而无需计算差额。