如何在c#中从字符串中累积TimeOfDay

时间:2013-10-10 18:21:02

标签: c# datetime timespan

我想累积时间值的字符串数组,并检查总时间是否大于一天。在这个测试用例中,我从凌晨12:00开始,增加12小时。然后我加12小时5分钟。总时间应为24小时5分钟。

问题是,从中午12:00到上午12:05的计算是计算11小时55分钟而不是12小时5分钟。

如何为我的用例正确累积这些时间?

string[] times = {"12:00 AM", "12:00 PM", "12:05 AM"};
const string timePattern = "h:mm tt";

double totalMillis = 0;
var prevTimeSpan = new TimeSpan(0);

foreach (var time in times)
{
    var parsedDate = DateTime.ParseExact(time, timePattern, null, DateTimeStyles.None);
    var currTimeSpan = parsedDate.TimeOfDay;
    var millis = Math.Abs((prevTimeSpan - currTimeSpan).TotalMilliseconds);
    prevTimeSpan = currTimeSpan;
    totalMillis += millis;
}

// 24 hours = 86400000
Console.WriteLine("Result is more than 24 hours? {0}", totalMillis >= 86400000 ? "Yes" : "No");

6 个答案:

答案 0 :(得分:2)

问题是你忽略了12:05 AM12:00 PM次日之后的事实。

试试这个

string[] times = { "12:00 AM", "12:00 PM", "12:05 AM" };
const string timePattern = "h:mm tt";
TimeSpan prev = TimeSpan.Zero;
var spans = times.Select(x =>
{
    var span = DateTime.ParseExact(x, timePattern, null, DateTimeStyles.None).TimeOfDay;
    if (span < prev)
    {
        span = span.Add(TimeSpan.FromDays(1.0) - prev);
    }
    prev = span;
    return span;
});
var totalMillis = spans.Sum(x => x.TotalMilliseconds);

// 24 hours = 86400000
Console.WriteLine("Result is more than 24 hours? {0}", totalMillis >= 86400000 ? "Yes" : "No");

答案 1 :(得分:2)

有一点需要注意的是,您正在假设您的时间。您假设每次都比上一次晚,因此如果是的早些时候必须在第二天。

基于这个假设,您可以从一天中的时间计算出TimeSpan总数:

string[] times = { "12:00 AM", "12:00 PM", "12:05 AM" };
const string timePattern = "h:mm tt";

DateTime[] dates = times.Select(x => DateTime.ParseExact(x, timePattern, null)).ToArray();

TimeSpan totalTimeSpan = new TimeSpan();

for (int i = 1; i < dates.Length; i++)
{
    // Assume that each time is at least the same date as the previous time
    dates[i] = dates[i - 1].Date + dates[i].TimeOfDay;

    // If this time is earlier than the previous time then assume it must be on the next day
    if (dates[i - 1].TimeOfDay > dates[i].TimeOfDay)
        dates[i] = dates[i].AddDays(1);

    totalTimeSpan += dates[i] - dates[i - 1];
}

Console.WriteLine("Result is more than 24 hours? {0}", totalTimeSpan.TotalHours > 24);

答案 2 :(得分:1)

您可以使用LINQ轻松完成此操作:

string[] times = { "12:00 AM", "12:00 PM", "12:05 AM" };
const string timePattern = "h:mm tt";

var timesOfDay = times.Select(x => DateTime.ParseExact(x, timePattern, CultureInfo.InvariantCulture).TimeOfDay).ToList();
var elapsedTimes = timesOfDay.Zip(timesOfDay.Skip(1), (a, b) => b - a + TimeSpan.FromDays(a > b ? 1 : 0));
TimeSpan totalElapsedTime = elapsedTimes.Aggregate((s, t) => s.Add(t));

答案 3 :(得分:0)

如果您添加日期部分,它会正确计算。

2013年1月1日12:00 - 2013年1月1日00:05 = 11小时55分钟。

我认为你期待它是1/2/2013 00:05 - 提前一天。 12小时5分钟。

答案 4 :(得分:0)

针对此特定用例的解决方案是:

string[] times = {"12:00 AM", "12:00 PM", "12:00 AM"};
const string timePattern = "h:mm tt";

double totalMillis = 0;
var prevTimeSpan = new TimeSpan(0);

foreach (var time in times)
{
    var parsedDate = DateTime.ParseExact(time, timePattern, null, DateTimeStyles.None);
    var currTimeSpan = parsedDate.TimeOfDay;
    var millis = (prevTimeSpan - currTimeSpan).TotalMilliseconds;
    prevTimeSpan = currTimeSpan;
    totalMillis += millis;
}

// 24 hours = 86400000
Console.WriteLine("Result is more than 24 hours? {0}", totalMillis >= 0 ? "No" : "Yes");

请注意,我只是检查它是否变为负数,而不是检查totalMillis是否超过一天。我仍然认为将字符串数组转换为总计没有涉及日期的时间跨度会很有趣。

答案 5 :(得分:0)

所以也许在DateTime上运行:

string[] times = { "12:00 AM", "12:00 PM", "12:05 AM" };
         const string timePattern = "h:mm tt";

         var dateTime = new DateTime(2010,1,1,0,0,0,0);
         foreach (var time in times)
         {
            var parsedDate = DateTime.ParseExact(time, timePattern, null, DateTimeStyles.None);
            dateTime = dateTime.AddHours(parsedDate.Hour);
            dateTime = dateTime.AddMinutes(parsedDate.Minute);
         }
         Console.WriteLine(a.ToShortTimeString());
         Console.ReadKey();

现在计算机知道你正处于新的一天