如何根据c#中传递的时间计算价格?

时间:2013-01-19 16:19:54

标签: c# windows-phone-7.1 windows-phone-7.1.1

我目前正在开发一款应用,根据用户使用该服务所花费的时间,计算用户必须支付的价格。第一个小时的费用为3.30美元,之后每半个小时的费用为1.15美元。我的计时器看起来像这样:

    private void timer()
    {
        DispatcherTimer timer = new DispatcherTimer();

        timer.Tick +=
            delegate(object s, EventArgs args)
            {
                TimeSpan time = (DateTime.Now - StartTime);

                this.Time.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", time.Hours, time.Minutes, time.Seconds);
            };
        timer.Interval = new TimeSpan(0, 0, 1); // one second
        timer.Start();
    }

关键是计时器和支付的价格应该显示在屏幕上并随着时间的推移自动更新(计时器已经这样做了。)

至于价格本身,我想过使用if / else和foreach的组合,但到目前为止,我什么也没做到......

3 个答案:

答案 0 :(得分:2)

像这样的东西。 (你忽略了如何处理部分小时,所以我忽略了它们。)

double span = (DateTime.Now - StartTime).TotalHours;
decimal cost = 0.0;
if (span > 0)
    cost = 3.30 + ((span - 1) * 1.15);

答案 1 :(得分:1)

如果方案是在段开始后立即添加成本,那么您可以计算在最初的小时后开始的半小时数,如下:

Math.Round((hours - 1) / 0.5 + 0.5)

然后计算成本:

double hours = (DateTime.UtcNow - StartTime).TotalHours;
double cost;
if (hours < 1)
    cost = 3.30;
else
    cost = 3.30 + Math.Round((hours - 1) / 0.5 + 0.5) * 1.15;

答案 2 :(得分:1)

一些注意事项:

  1. 使用UTC时间,而不是当地时间(参见Eric Lippert的评论)
  2. 使用decimal而非double代表资金
  3. 要计算开始时间间隔,Math.Ceiling很棒。无需跳过箍来让Math.Round做你想做的事。
  4. 将定价逻辑封装成一个简单的无副作用的方法,该方法不与外部服务交互,例如时钟。

    这使得单独测试该方法变得容易。

  5. 对所有定期UI更新使用单个计时器(除非它们需要不同的间隔)
  6. 我会这样写:

    public decimal CostByTime(TimeSpan t)
    {
      if(t < TimeSpan.Zero)
          throw new ArgumentOutOfRangeExeception("t", "Requires t>=0");
      if(t ==  TimeSpan.Zero)
          return 0;
      double hours = t.TotalHours;
      if(hours <= 1)
          return 3.30m;
      else
          return 3.30m + (int)Math.Ceiling((hours-1)*2) * 1.15m
    }
    

    然后在您的视图中,您可以使用:

    TimeSpan billableTime = DateTime.UtcNow - StartTime;
    decimal cost = CostByTime(billableTime);
    
    Time.Text = billableTime.ToString(...);
    Cost.Text = cost.ToString();