我的代码中有一个属性,用户可以在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
答案 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;
}