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

本文关键字:TimeOfDay 字符串 | 更新日期: 2023-09-27 18:34:52

我想累积一个时间值的字符串数组,并检查总时间是否大于一天。 在此测试用例中,我从上午 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");

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

需要注意的一件事是,你正在对你的时代做出假设。 您假设每次都晚于上次,因此,如果是一天中较早的时间,则必须在第二天。

基于该假设,您可以如何从一天中的一组时间计算总时间跨度:

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);

问题是你忽略了12:00 PM之后12:05 AM是第二天的事实。

试试这个

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");

您可以使用 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));

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

1

/1/2013 12:00 - 1/1/2013 00:05 = 11 小时 55 分钟。

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

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

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");

请注意,我不是检查总米利斯是否大于一天,而是检查它是否变为负数。 我仍然认为将字符串数组转换为不涉及日期的总和的时间跨度会很有趣。

所以也许在日期时间上操作:

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();

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