2

我试图模仿谷歌日历和 Outlook 处理时间选择的方式,其中所有时间条目相隔 30 分钟。除了一件事,我几乎所有的东西都与功能测试一起工作。我的问题是我不知道如何确保我总是将当前日期四舍五入到 30 分钟。

我正在使用以下代码:

protected DateTime GetStartTime()
{
    var spanTicks = TimeSpan.FromMinutes(30).Ticks;
    var ticks = (Time.Now.Ticks + spanTicks - 1) / spanTicks;

    return new DateTime(ticks * spanTicks);
}

这适用于大多数情况,除了上午 12:00(我希望它会在上午 12:30 返回)和上午 8:56(我希望它会在上午 9:00 返回)。

我怎样才能解决这个问题?

4

5 回答 5

2

为什么要打扰蜱虫?您可以将时间强制为:30:00,如下所示:

protected DateTime GetStartTime() {
    var now = DateTime.Now;
    int addHours;
    int minute;
    if (now.Minute >= 30) {
        addHour = 1;
        minute = 0;
    } else {
        addHour = 0;
        minute = 30;
    }
    return new DateTime(now.Year, now.Month, now.Day, hour, minute, 0).AddHours(addHours);
}
于 2012-01-18T14:05:00.947 回答
2

编辑:原始版本不起作用!来自旧 Mono 中的虚假实现!

新版本:

protected DateTime GetStartTime()
{
    DateTime dt=DateTime.Now;
    if (dt.Minute<30) 
    {
        dt=dt.AddMinutes(30-dt.Minute);
    }
    else 
    {
        dt=dt.AddMinutes(60-dt.Minute);
    }

    //dt now has the upcoming half-hour border

    //...

}
于 2012-01-18T14:05:50.977 回答
1

您是否尝试过类似以下的方法?我已经成功地使用了类似的方法来四舍五入到下一个小时、分钟、天等......

private static readonly long _ticksIn30Mins = TimeSpan.FromMinutes(30).Ticks;

protected DateTime GetRoundedTime(DateTime inputTime) 
{     
    long currentTicks = inputTime.Ticks;
    return new DateTime(currentTicks.RoundUp(_ticksIn30Mins)); 
} 

public static class ExtensionMethods 
{     
    public static long RoundUp(this long i, long toTicks)     
    {         
        return (long)(Math.Round(i / (double)toTicks, 
                  MidpointRounding.AwayFromZero)) * toTicks; 
    } 
} 

这采用上一个问题中的 RoundOff 方法。您只需使用 MidpointRoundingMode.AwayFromZero 将其修改为始终向上取整。

最后,为了应对上午 12:00 变为上午 12:30 的具体情况,然后检查您的舍入前后值是否相同,如果是,则增加刻度的汇总量(例如 30 分钟)

var currentTime = DateTime.Now;
var rounded = GetRoundedTime(currentTime); 
if (rounded == currentTime) 
{ 
    rounded = new DateTime(rounded.Ticks + _ticksIn30Mins); 
} 

对于演示此原理的经过测试的控制台应用程序,请参见以下内容:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        private static readonly long _ticksIn30Mins = TimeSpan.FromMinutes(30).Ticks; 

        static void Main(string[] args)
        {
            WriteDateString(new DateTime(2012, 01, 18, 09, 45, 11, 152));
            WriteDateString(new DateTime(2012, 01, 18, 12, 15, 11, 999));
            WriteDateString(new DateTime(2012, 01, 18, 12, 00, 00, 000));

            Console.ReadLine();
        }

        private static void WriteDateString(DateTime dateTime)
        {
            Console.WriteLine("Before: {0}, After: {1}", dateTime, GetRoundedTime(dateTime));
        }

        private static DateTime GetRoundedTime(DateTime inputTime)
        {
            long currentTicks = inputTime.Ticks; 
            var rounded = new DateTime(currentTicks.RoundUp(_ticksIn30Mins));
            if (rounded == inputTime)
            {
                rounded = new DateTime(rounded.Ticks + _ticksIn30Mins);
            }
            return rounded;
        } 
    }

    public static class ExtensionMethods
    {
        public static long RoundUp(this long i, long toTicks)
        {
            return (long)(Math.Round(i / (double)toTicks, MidpointRounding.AwayFromZero)) * toTicks;
        }
    }  
}

输出:

日期汇总示例的控制台输出

最好的祝福,

于 2012-01-18T14:07:06.577 回答
1

让 .NET 为您处理所有特殊情况:

var now = DateTime.Now;
DateTime result = now.AddMinutes(now.Minute >= 30 ? (60-now.Minute) : (30-now.Minute));
result = result.AddSeconds(-1* result.Second); // To reset seconds to 0
result = result.AddMilliseconds(-1* result.Millisecond); // To reset milliseconds to 0
于 2012-01-18T14:12:59.007 回答
0
                        String today = DateTime.Now.ToString("dd.MM.yyyy");
                        String hourMinute = DateTime.Now.ToString("HH:mm");

                        string[] sep = hourMinute.Split(":");
                        string hour = sep[0];
                        string minutes = sep[1];

                        int min = Int32.Parse(minutes);

                        if(min >= 30)
                        {
                            minutes = "30";
                        }
                        else
                        {
                            minutes = "00";
                        }

                        hourMinute = hour + ":" + minutes;
于 2020-06-18T08:47:19.933 回答