改变时间向前
Change the time forward
我正在从数据库中获取日期,对于每个日期,我都想从从数据库中获取的 DateTime 开始向前更改时间,直到到达给定的固定时间 (Y)。但是,(Y) 可能会在第二天。
例如,如果数据库中的日期是 [7/6/2017 5:00:00 AM] 并且给定的固定时间是 10:00 PM 那么我想得到 [7/6/2017 10:00:00 点。
但是如果固定时间是 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 上午时,这没有按预期工作。差异变为负数(它不会全天候运行)并且日期将是 [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;
}
我不确定我的函数在逻辑上是否正确,我觉得我想多了。另外,我不确定是否有更好的方法或内置函数可以满足我的需求。基本上,我正在寻找一个正确而优雅的解决方案。
非常感谢你。
您的逻辑 几乎 是正确的,但您不应该检查 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
。
在这个方法中,我使用 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);
}
方法略有不同:
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
作为 return 值,因为 date.Date
将 return 日期设置为 00:00 并向其添加目标时间将已经设置目标小时而不计算区别。
我正在从数据库中获取日期,对于每个日期,我都想从从数据库中获取的 DateTime 开始向前更改时间,直到到达给定的固定时间 (Y)。但是,(Y) 可能会在第二天。
例如,如果数据库中的日期是 [7/6/2017 5:00:00 AM] 并且给定的固定时间是 10:00 PM 那么我想得到 [7/6/2017 10:00:00 点。
但是如果固定时间是 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 上午时,这没有按预期工作。差异变为负数(它不会全天候运行)并且日期将是 [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;
}
我不确定我的函数在逻辑上是否正确,我觉得我想多了。另外,我不确定是否有更好的方法或内置函数可以满足我的需求。基本上,我正在寻找一个正确而优雅的解决方案。
非常感谢你。
您的逻辑 几乎 是正确的,但您不应该检查 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
。
在这个方法中,我使用 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);
}
方法略有不同:
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
作为 return 值,因为 date.Date
将 return 日期设置为 00:00 并向其添加目标时间将已经设置目标小时而不计算区别。