【问题标题】:Dividing time with timespan [duplicate]将时间除以时间跨度[重复]
【发布时间】:2021-05-22 14:22:06
【问题描述】:

大家好,我已经用这篇文章上传了一张图片。图中有四个时间戳。第一个和最后一个是动态的,因为它们不断变化。我希望中间两个也随着第一个和四个的不同而改变。比如Timer 1 = 2,Timer 4 = 5,那么Timer 2和Timer 3应该分别是3和4。4行应该是均匀分布的。

现在我使用 TimeSpan 以 {HH:MM} 格式显示,我不能用整数除时间戳,因为它不允许我这样做。那么我在这里有什么选择呢?

public TimeSpan HoursMinutes_01;
public double totalMinutes_01;
private string result_01;

public TimeSpan HoursMinutes_02;
public double totalMinutes_02;
private string result_02;

void Start()
{
      //For First Timer
            HoursMinutes_01 = new TimeSpan (1, 0, 0);
            totalMinutes = HoursMinutes_01 .TotalMinutes;
            result = string.Format ("{0:D2}:{1:D2}", HoursMinutes_01.Hours, HoursMinutes_01.Minutes);

     //For Second Timer
            HoursMinutes_02 = new TimeSpan (4, 0, 0);
            totalMinutes = HoursMinutes_02 .TotalMinutes;
            result = string.Format ("{0:D2}:{1:D2}", HoursMinutes_02.Hours, HoursMinutes_02.Minutes);
}

TimeDifference

【问题讨论】:

    标签: c# unity3d timespan


    【解决方案1】:

    this answer那样按分钟计算实际上是相当昂贵的。

    您可以/应该使用Ticks 来降低最基本的价值:

    var firstTime = new TimeSpan(1, 30, 0);
    var fourthTime = new TimeSpan(3, 0, 0);
    
    var difference = fourthTime.Ticks - firstTime.Ticks;
    var step = difference / 3;
    
    var secondTime = new TimeSpan(firstTime.Ticks + step);
    var thirdTime = new TimeSpan (secondTime.Ticks + step);
    

    由于多种原因,这更有效:

    • .Ticks 只返回存储的报价,无需任何额外计算
    • 获取刻度的构造函数只存储这些刻度,无需任何额外计算
    • 我们使用 int 除法,它也比双除法更快
    • 我们不会创建不需要的 TimeSpan 实例,而是直接使用刻度 (long) 进行计算

    并概括它

    /// <summary>
    /// Returns an array of all time steps between from and to (including from and to)
    /// </summary>
    /// <param name="from">the first time</param>
    /// <param name="to">the last time</param>
    /// <param name="stepCount">How many steps to insert between first and last time</param>
    public TimeSpan[] GetInBetweenTimes(TimeSpan from, TimeSpan to, int stepCount)
    {
        if(stepCount <= 0)
        {
            return new[]{from, to};
        }
    
        var times = new List<TimeSpan>{from};
    
        var difference = to.Ticks - from.Ticks;
        var ticksStepDelta = difference / (stepCount+1);
        if(ticksStepDelta == 0)
        {
            Debug.LogError("Difference between from and to is too small for the given stepCount!");
            return return new[]{from, to};
        }
    
        var currentStep = from.Ticks;
        for(i = 0; i < stepCount; i++)
        {
            currentStep += ticksStepDelta;
            times.Add(currentStep);
        }
    
        times.Add(to);
      
        return times.ToArray();
    }
    

    而对于string,则只需使用

    var timeSpan = new TimeSpan(1,30,0);
    var stringValue = someTimeSpan.ToString("hh\:mm");
    

    01:30

    【讨论】:

    • 感谢您提出更优化的解决方案。但我能问为什么它更贵吗?是的,您的解决方案会运行得更快一点,但从 source code 开始,它看起来并没有太大的不同。
    • @SeLeCtRa 刻度是存储的基础值。其他所有内容都是每次访问它们时都必须重新计算的属性 => 访问刻度更有效。而在另一个方向上,构造函数获取刻度也更有效,因为它只是再次获取并存储给定的刻度。使用任何其他构造函数基本上需要给定的小时、分钟、秒,例如并将其重新计算为刻度以存储它=>再次按刻度进行效率更高
    • 我同意你的观点,但我只是说,性能方面,几乎不引人注意。我们在这里只处理小的双精度值,如果它是数组/列表/字典,你的代码会好得多。但在这种情况下,性能并不明显。但是谢谢你的另一个观点
    • @SeLeCtRa 性能明智,这更有效 ;) 现在它是否会显着 / 重要当然总是取决于你多久做一次;)
    【解决方案2】:

    要以 {HH:MM} 格式显示时间,请使用:

    TimeSpan oneAndHalfHour = new TimeSpan(1, 30, 0);
    Debug.Log(string.Format("You were out of game for: {00} hours and {1:00} minutes", oneAndHalfHour.Hours, oneAndHalfHour.Minutes));
    

    对于动态发现的第二次和第三次使用这个。

    TimeSpan firstTime = new TimeSpan(1, 30, 0); // 1.5 hour
    TimeSpan secondTime = new TimeSpan(); // Should be 2 hour 
    TimeSpan thirdTime = new TimeSpan(); // Should be 2.5 hour
    TimeSpan fourthTime = new TimeSpan(3, 0, 0); // 3 Hour
    
    TimeSpan difference = fourthTime - firstTime;
    // There are 3 element between 1st and 4th time, should include 1st one too
    // This variable will give us interval between every time
    int differenceInMinutes = (int)(difference.TotalMinutes / 3);
    
    secondTime = firstTime.Add(new TimeSpan(0, differenceInMinutes, 0));
    thirdTime = secondTime.Add(new TimeSpan(0, differenceInMinutes, 0));
    

    【讨论】:

      猜你喜欢
      • 2012-05-27
      • 2010-10-24
      • 2015-03-18
      • 2014-01-09
      • 1970-01-01
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      • 2013-03-20
      相关资源
      最近更新 更多