我有两个decimal
值
3.10m = 3 years 10 months
2.8m = 2 years 8 months.
我正在尝试sum
这些值,结果是5.9
,这是不正确。
预期结果应为
6.6m = 6 years 6 months
任何人都可以建议我们如何使用TimeSpan
或C#中的任何其他方法来实现此目标吗?在此先感谢
答案 0 :(得分:5)
首先,我避免使用类似这样的小数来表示年/月值。如评论中所述,您将无法轻松区分1个月和10个月...而decimal
可以代表3.1和3.10,这将是一个非常奇怪的用法。只需将两个值保存在单独的整数中即可。
接下来,您无法使用TimeSpan
进行这样的算术运算。 TimeSpan
仅存储“一定数量的滴答声”-它不能处理“ 1个月”或“ 1年”之类的想法,因为它们不代表固定的滴答声数量。
我建议改为使用我的Noda Time库。您可以将这些值表示为Period
对象。您仍然无法直接将年和月加在一起-Period
并没有采用格里高利历系统,并且这样的算术不适用于某些非格里高利历,尤其是那些基于年份的月数。但是,您可以轻松编写自己的Period
规范化方法:
using System;
using NodaTime;
class Test
{
static void Main()
{
Period p1 = new PeriodBuilder { Years = 3, Months = 10 }.Build();
Period p2 = new PeriodBuilder { Years = 5, Months = -12 }.Build();
Period sum = p1 + p2;
Period normalized = NormalizeYearsAndMonths(sum);
Console.WriteLine($"{normalized.Years} years; {normalized.Months} months");
}
static Period NormalizeYearsAndMonths(Period period)
{
// TODO: Handle negative years and months however you want.
int years = period.Years;
int months = period.Months;
years += months / 12;
months = months % 12;
var builder = period.ToBuilder();
builder.Years = years;
builder.Months = months;
return builder.Build();
}
}
现在您当然可以将所有内容保留为两个整数了-使用Period
的好处是您可以轻松地将其添加到LocalDate
或{ {1}}等。如果需要,您甚至可以不进行标准化就可以这样做。
答案 1 :(得分:2)
请勿执行此操作! app.get("/issues", function(req, res) {
Issue.find({})
.exec(function (err, issues) {
if (err)
console.log(err);
else
console.log("successfully requested");
res.json(issues);
});
});
不适用于decimal
。从技术上讲,您可以解决问题并区分 year.month
和3.1m
(3.10m
可以解决);这是仅用于学术用途的代码:
decimal.GetBits
演示:
private static decimal EerieArithmetics(decimal d1, decimal d2) {
int y1 = (int)d1;
int m1 = (int)((d1 % 1m) * ((((decimal.GetBits(d1)[3] >> 16) & 31) == 2) ? 100m : 10m));
int y2 = (int)d2;
int m2 = (int)((d2 % 1m) * ((((decimal.GetBits(d2)[3] >> 16) & 31) == 2) ? 100m : 10m));
int y = y1 + y2 + (m1 + m2) / 12;
int m = (m1 + m2) % 12;
return y + (m == 10 ? 0.10m : m > 10 ? m / 100.00m : m / 10.0m);
}
结果:
Tuple<decimal, decimal>[] tests = new Tuple<decimal, decimal>[] {
Tuple.Create(3.10m, 2.8m),
Tuple.Create( 3.1m, 2.8m),
Tuple.Create( 3.0m, 2.8m),
Tuple.Create( 3.0m, 2.0m),
Tuple.Create( 3m, 2m),
Tuple.Create( 3.8m, 2.4m),
Tuple.Create(3.10m, 3.10m),
Tuple.Create( 2.8m, 2.2m),
Tuple.Create(2.11m, 2.2m),
};
string report = string.Join(Environment.NewLine, tests
.Select(test =>
$"{test.Item1,5} + {test.Item2,5} == {EerieArithmetics(test.Item1, test.Item2),5}"));
Console.Write(report);
我希望,我吓倒了你使用 3.10 + 2.8 == 6.6
3.1 + 2.8 == 5.9
3.0 + 2.8 == 5.8
3.0 + 2.0 == 5
3 + 2 == 5
3.8 + 2.4 == 6
3.10 + 3.10 == 7.8
2.8 + 2.2 == 4.10
2.11 + 2.2 == 5.1
。作为一个快速又肮脏补丁(如果您只能使用标准库,则不能使用任何库),可以尝试decimal
类:
DateTime