0

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

问题是从 12:00 PM 到 12:05 AM 的计算是计算 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");
4

6 回答 6

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);
于 2013-10-10T19:01:57.627 回答
2

问题是您忽略了12:05 AM之后12: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");
于 2013-10-10T18:54:57.173 回答
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));
于 2013-10-10T19:09:34.670 回答
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 是否大于一天,而是检查它是否变为负数。我仍然认为将字符串数组转换为总计不涉及日期的时间跨度会很有趣。

于 2013-10-10T18:44:57.207 回答
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();

现在电脑知道你在新的一天

于 2013-10-10T18:46:52.770 回答
0

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

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

我想你预计它会是 2013 年 1 月 2 日 00:05 - 提前一天。12小时5分钟。

于 2013-10-10T18:37:30.673 回答