检查当前日期时间是否在08 PM到08 AM之间,并计算剩余时间到08 AM

时间:2017-09-08 05:26:40

标签: c# datetime

这是一个场景,我需要知道当前的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?
}

7 个答案:

答案 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();

<强>输出

enter image description here

答案 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混合使用时必须非常小心。存在从DateTimeDateTimeOffset的隐式转换。如果DateTime的类型为LocalUnspecified,则生成的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