我目前正在开发一款应用,根据用户使用该服务所花费的时间,计算用户必须支付的价格。第一个小时的费用为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的组合,但到目前为止,我什么也没做到......
答案 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)
一些注意事项:
decimal
而非double
代表资金Math.Ceiling
很棒。无需跳过箍来让Math.Round
做你想做的事。将定价逻辑封装成一个简单的无副作用的方法,该方法不与外部服务交互,例如时钟。
这使得单独测试该方法变得容易。
我会这样写:
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();