【问题标题】:Convert difference between start time and end time to hours. minutes and seconds将开始时间和结束时间之间的差异转换为小时。分和秒
【发布时间】:2017-01-17 07:01:17
【问题描述】:

我正在尝试查找时间范围之间的持续时间并将其转换为小时、分钟和秒。应添加的小时数不应转换为 24 小时。如果有 50 小时 30 分 30 秒,则应显示为 50:30:30,如果分钟持续时间超过 59,则应添加小时,以秒为单位。

请查看完整代码。两种方法都没有给出正确答案。方法 GetSumOfDuration 将 0.30 视为 0.3,因此它没有给出正确的答案。当相差超过 24 小时时,GetSumOfDurationFromSecond 方法失​​败。

using System;
using System.Collections.Generic;
using System.Linq;

namespace TimeCalculationApp
{
public class ProcessDetail
{
    public DateTime? StartTime { get; set; }
    public DateTime? EndTime { get; set; }

    public double? DurationInSeconds
    {
        get
        {
            if (StartTime != null && EndTime != null)
                return (EndTime.Value - StartTime.Value).TotalSeconds;
            return null;
        }
    }

    public double? Duration
    {
        get
        {
            if (StartTime != null && EndTime != null)
                return double.Parse(DateTimeHelper.GetTimeDuration(StartTime, EndTime));
            return null;
        }
    }
}

class DateTimeHelper
{
    public static string GetTimeDuration(DateTime? sDateTime, DateTime? eDateTime)
    {
        if (sDateTime != null && eDateTime != null)
        {
            if (sDateTime.Value <= eDateTime.Value)
            {
                var tsdiff = eDateTime.Value - sDateTime.Value;
                var ts = TimeSpan.FromSeconds(tsdiff.TotalSeconds);

                return string.Format("{0}.{1}", ts.Hours.ToString("0"), ts.Minutes.ToString("D2"));
            }
            return "0.00";
        }
        return "0.00";
    }

    public static string GetSumOfDuration(List<ProcessDetail> processDetails)
    {
        TimeSpan? sumDuration = null;

        var totalhours = 0;
        var totalminutes = 0;

        foreach (var processDetail in processDetails)
        {
            if (processDetail.Duration != null)
            {
                var splitString = processDetail.Duration.ToString().Split('.');

                var hour = splitString.Length > 0 ? splitString[0] : "0";
                var minutes = splitString.Length > 1 ? splitString[1] : "0";

                totalhours += int.Parse(hour);
                totalminutes += int.Parse(minutes);

                sumDuration = new TimeSpan(totalhours, totalminutes, 0);
            }
        }
        return sumDuration == null
            ? null
            : Math.Floor(sumDuration.Value.TotalHours).ToString("0") + ":" +
              sumDuration.Value.Minutes.ToString("D2");
    }

    public static string GetSumOfDurationFromSecond(List<ProcessDetail> processDetails, bool includeSeconds = false)
    {
        var seconds = processDetails.Where(x => x.DurationInSeconds != null).Sum(x => x.DurationInSeconds);
        if (seconds == null) return null;

        var ts = TimeSpan.FromSeconds(seconds.Value);

        return includeSeconds ? string.Format("{0}:{1}:{2}", ts.Hours.ToString("0"), ts.Minutes.ToString("D2"), ts.Seconds.ToString("D2")) :
            string.Format("{0}:{1}", ts.Hours.ToString("0"), ts.Minutes.ToString("D2"));
    }
}
class Program
{
    static void Main(string[] args)
    {
        var processDetails = GetProcessDetails();

        var duration = DateTimeHelper.GetSumOfDuration(processDetails);
        var durationFromSeconds = DateTimeHelper.GetSumOfDurationFromSecond(processDetails);

        Console.WriteLine(duration);
        Console.WriteLine(durationFromSeconds);

        processDetails = GetProcessDetailsTestData();

        duration = DateTimeHelper.GetSumOfDuration(processDetails);
        durationFromSeconds = DateTimeHelper.GetSumOfDurationFromSecond(processDetails);

        Console.WriteLine(duration);
        Console.WriteLine(durationFromSeconds);

        Console.ReadKey();

    }

    private static List<ProcessDetail> GetProcessDetails()
    {
        return new List<ProcessDetail>
        {
            new ProcessDetail
            {
                StartTime = new DateTime(2017, 01, 01, 1, 0, 0),
                EndTime =   new DateTime(2017, 01, 01, 7, 59, 0)
            },
            new ProcessDetail
            {
                StartTime = new DateTime(2017, 01, 01, 1, 0, 0),
                EndTime =   new DateTime(2017, 01, 01, 17, 3, 45)
            },
            new ProcessDetail
            {
                StartTime = new DateTime(2017, 01, 01, 1, 0, 0),
                EndTime =   new DateTime(2017, 01, 01, 10, 0, 20)
            },
            new ProcessDetail
            {
                StartTime = new DateTime(2017, 01, 01, 1, 0, 0),
                EndTime =   new DateTime(2017, 01, 01, 15, 1, 12)
            }
        };
    }

    private static List<ProcessDetail> GetProcessDetailsTestData()
    {
        return new List<ProcessDetail>
        {
            new ProcessDetail
            {
                StartTime =  DateTime.Parse("11/01/2017 06:36:28"),
                EndTime =  DateTime.Parse("11/01/2017 06:53:51")
            },
            new ProcessDetail
            {
                StartTime = DateTime.Parse("11/01/2017 09:12:46"),
                EndTime =  DateTime.Parse("11/01/2017 09:43:00")
            },
            new ProcessDetail
            {
                StartTime =DateTime.Parse("11/01/2017 15:29:25"),
                EndTime =   DateTime.Parse("11/01/2017 15:37:26")
            },
            new ProcessDetail
            {
                StartTime = DateTime.Parse("11/01/2017 15:19:19"),
                EndTime =  DateTime.Parse("11/01/2017 15:27:52")
            },
            new ProcessDetail
            {
                StartTime = DateTime.Parse("12/01/2017 01:05:43"),
                EndTime =  DateTime.Parse("12/01/2017 01:08:37")
            }
        };
    }
}
}

【问题讨论】:

  • 为什么不将Duration 存储为TimeSpan

标签: c# datetime


【解决方案1】:

这应该给出日期之间的总小时数。

  DateTime dt1 = new DateTime(2016, 1, 1);
  DateTime dt2 = new DateTime(2016, 1, 5);
  TimeSpan difference = dt2 - dt1;
  int totalDaysToHours = difference.Days * 24; 
  Console.WriteLine((difference.Hours + totalDaysToHours) + " hours " + difference.Minutes + " Minutes " + difference.Seconds + " seconds" );
  Console.ReadKey();

【讨论】:

    【解决方案2】:

    您可以通过减法操作修复差异的时间跨度。

    TimeSpan time1 = TimeSpan.Parse(date1);
    TimeSpan time2 = TimeSpan.Parse(date2);
    
    TimeSpan difference = time1 - time2;
    
    int hours = difference.Hours;
    int minutes = difference.Minutes;
    

    【讨论】:

    • 文本框从何而来?
    • 请替换date1和date2。它会工作
    【解决方案3】:

    您可以从结束时间中减去开始时间。 结果将是一个 Timespan 对象。

    // Set startime example to one hour ten minutes and 30 seconds ago
    DateTime startTime = DateTime.Now.AddSeconds(-4230);
    DateTime endTime = DateTime.Now;
    TimeSpan elapsedTime = endTime-startTime;
    // Print out the elapsed time in hour:minutes:seconds to string
    string result = elapsedTime.TotalHours + ":" + elapsedTime.Minutes + ":" + elapsedTime.Seconds
    

    请注意,TimeSpan 提供了诸如 Hours 和 TotalHours 的属性。 Hours 的值可以在 0-23 之间(当值超过 23 时,属性 Days 会增加)而 TotalHours 提供完整小时数

    【讨论】:

      【解决方案4】:

      我同意 Thomas Voß 的观点,即您应该使用 Timespan。然而 TotalHours 应该被强制转换为 int 以获得正确的小时数。

      string result = (int)elapsedTime.TotalHours + ":" + elapsedTime.Minutes + ":" + elapsedTime.Seconds
      

      如果您可以考虑以天格式显示结果,您可以使用 TimeSpan 格式:

      elapsedTime.ToString("dd\.hh\:mm\:ss") 
      

      您可以阅读有关自定义 TimeSpan 格式的更多信息here

      【讨论】:

        猜你喜欢
        • 2012-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-04
        相关资源
        最近更新 更多