这是一个场景,我需要知道当前的DateTime是否在08:00 PM(20:00)和08:00 AM(08:00)之间。如果是,我需要将总时数留到08:00 AM(08:00)。
我的尝试:
TimeSpan start = TimeSpan.Parse("20:00");
TimeSpan end = TimeSpan.Parse("08:00");
TimeSpan now = DateTime.Now.TimeOfDay;
bool flag = false;
if (start <= end)
{
if (now >= start && now <= end)
{
flag = true;
}
}
else
{
if (now >= start || now <= end)
{
flag = true;
}
}
if (flag)
{
/// calculate hours?
}
答案 0 :(得分:8)
这是一种简单的方法:
var date = DateTime.Now;
if(date.Hour >= 20 || date.Hour < 8)
{
var DateTime8 = date.Date.AddHours((date.Hour > 8) ? 24 + 8 : 8);
TimeSpan diff = DateTime8 - date;
}
答案 1 :(得分:2)
这就是我想出的。首先检查当前时间是否在开始和结束时间之间。如果是这样,那么做一些TimeSpan
数学来确定到早上8点还剩多少时间。如果它当前在午夜之前,我们会从24:00:00
中减去当前时间并添加8
;否则,我们从8:00:00
:
Console.WriteLine($"The current time is {DateTime.Now.ToString("hh\\:mm\\:ss")}.");
var currentTime = DateTime.Now.TimeOfDay;
var start = new TimeSpan(20, 0, 0);
var end = new TimeSpan(8, 0, 0);
var midnight = new TimeSpan(24, 0, 0);
if (currentTime >= start || currentTime <= end)
{
var hoursLeftUntil8 = currentTime.Hours >= 20
? midnight.Subtract(currentTime).Add(end)
: end.Subtract(currentTime);
Console.WriteLine("There are {0} hours, {1} minutes, and {2} seconds left until 8AM",
hoursLeftUntil8.Hours, hoursLeftUntil8.Minutes, hoursLeftUntil8.Seconds);
}
else
{
Console.WriteLine("It is not between 8PM and 8AM.");
}
Console.WriteLine("\nDone!\n\nPress any key to exit...");
Console.ReadKey();
<强>输出强>
答案 2 :(得分:1)
据我所知,到目前为止,所提供的答案都没有考虑到夏令时。至少在我住的地方有一个春天的夜晚,墙上的时钟将从凌晨2点到凌晨3点跳过,而在秋天的另一个夜晚,时钟将从凌晨3点跳回到凌晨2点一次。不同的国家将有不同的规则(或根本没有夏令时)。
春夜在当地时区少了一个小时,所以如果时间戳在凌晨2点之前,当地时间早上8点之间的时差比通过简单计算得到的时间<1> 。
同样地,秋夜在当地时区还有一个小时,所以如果时间戳在凌晨2点之前,那么到当地时间早上8点的时差是1小时更多比你得到的做简单的计算。更糟糕的是:如果本地时间戳在凌晨2点到凌晨3点之间,那就不明确了。是第一个上午2:30还是第二个?
要解决模糊问题,您需要从使用本地DateTime
切换到DateTimeOffset
。当你使用后者时,在夜间第一次上午2:30和第二次之间没有歧义,因为它们具有不同的UTC偏移,并且UTC偏移是DateTimeOffset
结构的一部分。 / p>
所以这里有一些代码可以考虑夏令时:
var now = DateTimeOffset.Now;
if (now.Hour >= 20 || now.Hour < 8)
{
var midnightDateTime = now.Date.AddDays(now.Hour >= 20 ? 1 : 0);
var offsetMidnight = TimeZoneInfo.Local.GetUtcOffset(midnightDateTime);
var midnight = new DateTimeOffset(midnightDateTime, offsetMidnight);
var eightAmDateTime = new DateTime(midnight.Year, midnight.Month, midnight.Day, 8, 0, 0);
var offsetEightAm = TimeZoneInfo.Local.GetUtcOffset(eightAmDateTime);
var eightAm = new DateTimeOffset(eightAmDateTime, offsetEightAm);
var timeLeftUntilEightAm = eightAm - now;
}
使用DateTimeOffset
时,与DateTime
混合使用时必须非常小心。存在从DateTime
到DateTimeOffset
的隐式转换。如果DateTime
的类型为Local
或Unspecified
,则生成的DateTimeOffset
的偏移量将是本地时区的偏移量。在上面的代码now.Date
中有Unspecified
种类,如果您使用此DateTime
和另一个DateTimeOffset
进行一些算术运算,则转换会启动并且结果可能会偏移您当地的时区。这可能不是你想要的,至少我被这个不太明显的转换所困扰。
答案 3 :(得分:0)
你可以使用类似的东西。如果时间在20:00到00:00之间,那么现在和00:00之间的差异应该增加8小时。
TimeSpan timeLeft = new TimeSpan(0);
if (now >= start)
{
timeLeft = end + (TimeSpan.Parse("23:59:59.9999") - now);
}
else if (now <= end)
{
timeLeft = end - now;
}
Console.WriteLine(timeLeft);
另一种方法可以是:
DateTime now = DateTime.Now;
TimeSpan t = new TimeSpan(0);
if (now.Hour >= 20)
{
DateTime nextDay = now.AddDays(1);
t = new DateTime(nextDay.Year, nextDay.Month, nextDay.Day, 8, 0, 0).Subtract(now);
}
else if (now.Hour < 8)
{
t = new DateTime(now.Year, now.Month, now.Day, 8, 0, 0).Subtract(now);
}
Console.WriteLine(t);
答案 4 :(得分:0)
以下代码应该可以满足您的需求。此解决方案适用于开始,结束和现在的任何值。 关键是如果它变为负数则增加24小时。
var remainingTime = end - now;
if (remainingTime < TimeSpan.Zero)
remainingTime = remainingTime + new TimeSpan(24, 0, 0);
完整样本:
using System;
namespace Test
{
public class Program
{
public static void Main()
{
var start = TimeSpan.Parse("20:00");
var end = TimeSpan.Parse("08:00");
var now = DateTime.Now.TimeOfDay;
var flag = InTheTimeWindow(start, end, now);
if (flag)
{
var remainingTime = end - now;
if (remainingTime < TimeSpan.Zero)
remainingTime = remainingTime + new TimeSpan(24, 0, 0);
Console.WriteLine(remainingTime);
}
Console.ReadLine();
}
private static bool InTheTimeWindow(TimeSpan start, TimeSpan end, TimeSpan now)
{
var flag = false;
if (start <= end)
{
if (now >= start && now <= end)
{
flag = true;
}
}
else
{
if (now >= start || now <= end)
{
flag = true;
}
}
return flag;
}
}
}
答案 5 :(得分:0)
基于this SO,您可以尝试以下代码:
private ICommand wordGridClickedCommand;
pubilc ICommand WordGridClickedCommand
{
get
{
return wordGridClickedCommand ??
(wordGridClickedCommand = new Command(() =>
{
if (App.Timer1Running)
ResetTimer1();
else
ResetTimer2();
}));
}
}
答案 6 :(得分:-3)
if if的第一个条件永远不会被满足。无论如何只是垃圾代码,它不会影响结果,只是因为额外的比较而影响性能。
因此,为了进行差距测量&#39;看看TimeSpan.Subtract method