Roundoff Timespan到15分钟的间隔

时间:2014-06-03 02:33:33

标签: c#

我的代码中有一个属性,用户可以在HH中输入一个时间跨度:mm,如

10:32
10:44
15:45

我想在我的房产中尽量到最近的15分钟,但我没有约会时间。我只需要使用Timespan

10:32 to 10:30
10:44 to 10:45
15:45 to 15:45
01:02 to 01:00
02:11 to 02:15
03:22 to 03:15
23:52 to 00:00

尝试了所有这些解决方案,但它们涉及日期时间

How can I round up the time to the nearest X minutes?
Is there a simple function for rounding a DateTime down to the nearest 30 minutes, in C#?
DotNet Roundoff datetime to last 15 minutes

5 个答案:

答案 0 :(得分:15)

我想你想要这样的东西:

public static class TimeSpanExtensions
{
    public static TimeSpan RoundToNearestMinutes(this TimeSpan input, int minutes)
    {
        var totalMinutes = (int)(input + new TimeSpan(0, minutes/2, 0)).TotalMinutes;

        return new TimeSpan(0, totalMinutes - totalMinutes % minutes, 0);
    }
}

如果您传入15作为所选的舍入间隔,则该函数将首先添加7分钟,然后向下舍入到最接近的15分钟。这应该给你你想要的东西。

因为上面写的是一个扩展方法,你可以像这样使用它:

var span1 = new TimeSpan(0, 10, 37, 00).RoundToNearestMinutes(15);
var span2 = new TimeSpan(0, 10, 38, 00).RoundToNearestMinutes(15);

第一个变为10:30,第二个变为10:45(根据需要)。

答案 1 :(得分:4)

我喜欢Baldrick的答案,但我发现使用负时间值(如时区偏移)时它不起作用。

我将其原始代码修改如下,这似乎适用于正和负TimeSpan值。

public static class TimeSpanExtensions
{
    public static TimeSpan RoundToNearestMinutes(this TimeSpan input, int minutes)
    {
        var halfRange = new TimeSpan(0, minutes/2, 0);
        if (input.Ticks < 0)
            halfRange = halfRange.Negate();
        var totalMinutes = (int)(input + halfRange).TotalMinutes;
        return new TimeSpan(0, totalMinutes - totalMinutes % minutes, 0);
    }
}

答案 2 :(得分:2)

我知道这已经很晚了,但我认为对于那些寻找答案的人来说这可能是有用的,就像我在找到这个问题时那样。请注意,这可用于向上舍入到任何时间长度的单位,并且可以轻松修改为向下舍入或舍入到最近的时间段(通过将Math.Ceiling更改为Math.Floor或Math.Round)

UIImageView

可以像这样使用:

public TimeSpan RoundTimeSpanUp(TimeSpan span, TimeSpan roundingTimeSpan) { long originalTicks = roundingTimeSpan.Ticks; long roundedTicks = (long)(Math.Ceiling((double)span.Ticks / originalTicks) * originalTicks); TimeSpan result = new TimeSpan(roundedTicks); return result; }

或以任何时间单位进行整理,如下:

TimeSpan roundedMinutes = RoundTimeSpanUp(span, TimeSpan.FromMinutes(15));

答案 3 :(得分:0)

我意识到这已经很晚了,但是@Baldrick提供的答案启发了我自己的解决方案:

public static class TimeSpanExtensions
{
    /// <summary>
    /// Rounds a TimeSpan based on the provided values.
    /// </summary>
    /// <param name="ts">The extension target.</param>
    /// <param name="Direction">The direction in which to round.</param>
    /// <param name="MinutePrecision">The precision to round to.</param>
    /// <returns>A new TimeSpan based on the provided values.</returns>
    public static System.TimeSpan Round(this System.TimeSpan ts, 
        RoundingDirection Direction, 
        int MinutePrecision)
    {
        if(Direction == RoundingDirection.Up)
        {
            return System.TimeSpan.FromMinutes(
                MinutePrecision * Math.Ceiling(ts.TotalMinutes / MinutePrecision)); 
        }

        if(Direction == RoundingDirection.Down)
        {
            return System.TimeSpan.FromMinutes(
                MinutePrecision * Math.Floor(ts.TotalMinutes / MinutePrecision)); 
        }

        // Really shouldn't be able to get here...
        return ts; 
    }
}

/// <summary>
/// Rounding direction used in rounding operations. 
/// </summary>
public enum RoundingDirection
{
    /// <summary>
    /// Round up.
    /// </summary>
    Up, 
    /// <summary>
    /// Round down.
    /// </summary>
    Down
}

答案 4 :(得分:0)

我在代码隐藏中将以下逻辑放在一起,用于旧的asp表单应用程序从UI中的隐藏字段中获取dateTime字符串,并计算客户端和服务器之间的差异。

 private TimeSpan calculateVariance(string dateString)
        {
            DateTime clientHour = Convert.ToDateTime(dateString);
            DateTime serverHour = DateTime.Now.ToLocalTime();
            TimeSpan timeVariance = clientHour - serverHour;

            TimeSpan roundedTimeVariance;

            //ROUND VARIANCE TO THE NEAREST 15 minutes AND RETURN AS EITHER A POSITIVE OR NEGATIVE TimeSpan Object
            if (timeVariance.Minutes > 52)
            {
                roundedTimeVariance = new TimeSpan(timeVariance.Hours + 1, 0, 0);
            }
            else if (timeVariance.Minutes > 37)
            {
                roundedTimeVariance = new TimeSpan(timeVariance.Hours, 45, 0);
            }
            else if (timeVariance.Minutes > 22)
            {
                roundedTimeVariance = new TimeSpan(timeVariance.Hours, 30, 0 );
            }
            else if (timeVariance.Minutes > 7)
            {
                roundedTimeVariance = new TimeSpan(timeVariance.Hours, 15, 0);
            }
            else
            {
                roundedTimeVariance = new TimeSpan(timeVariance.Hours, 0, 0);
            }

            return roundedTimeVariance;
        }