为不同的日历获取一年中某一天的更好方法
Posted
技术标签:
【中文标题】为不同的日历获取一年中某一天的更好方法【英文标题】:Better way of getting day of year for a different calendar 【发布时间】:2021-02-07 12:07:42 【问题描述】:我正在尝试获取以下日历的月份日期:
我写了两个不同的函数来完成这个:
public int DayOfYear(int year, int month, int day)
var months = new[] 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 31;
var dayOfYear = day;
if (month == 1) return dayOfYear;
for (var i = 0; i < month-1; i++)
dayOfYear += months[i];
return dayOfYear;
并且要在没有循环的情况下执行此操作:
public int DayOfYear(int year, int month, int day)
var dayOfYear = day;
if (month <= 5)
dayOfYear += 31 * (month-1);
else
dayOfYear += 31 * 5 + 30 * ((month - 5) - 2);
if (month == 12)
dayOfYear += 31;
return dayOfYear;
假设第 12 个月总是有 31 天。我觉得有更好的数学方法可以做到这一点,但我真的想不出。
例如:(522, 12, 14) 根据我的日历,是一年中的第 349 天。使用这两个函数都是正确的。 (522, 1, 1) 将是一年的第一天。
对于一些可视化,(522, 5, 18) 将按以下方式完成:
31 + 31 + 31 + 31 + 18
而 (522, 9, 18) 为:
31 + 31 + 31 + 31 + 31 + 30 + 30 + 30 + 18
【问题讨论】:
@Charlieface 这对我想要一年中的某一天的问题有何帮助?此外,我在几个月中的日子显然与公历不同。 【参考方案1】:单线解决方案:
public int DayOfYear(int year, int month, int day) =>
31 * (month - 1) - Math.Max(0, month - 6) + day;
它只是假设每个月有 31 天。所以 31*(month-1),但由于第 6 个月是 30 天,所以我们减去 Math.Max(0, month-6),然后简单地加上天。
它也适用于闰年,但仅适用于有效日期。
【讨论】:
【参考方案2】:创建一个包含月份的字典 => 到那时为止的总天数。
private static readonly Dictionary<int, int> TotalDays = new Dictionary<int, int>
[1] = 0,
[2] = 31,
[3] = 62,
[4] = 93,
// etc
;
// for day of month validation
private static readonly Dictionary<int, int> DaysPerMonth = new Dictionary<int, int>
[1] = 31,
[2] = 31,
[3] = 31,
[4] = 31,
// etc
;
然后根据截至该点的天数加上本月的某天计算一年中的哪一天:
public int DayOfYear(int year, int month, int day)
// validate your parameters
if (!TotalDays.TryGetValue(month, out var total))
throw new Exception("invalid month");
if (day <= 0 || day > DaysPerMonth[month])
throw new Exception("day too big or small");
return total + day;
【讨论】:
这个好办法,我也想过这样做。但是,由于这个日历与公历不同,它重复了几个月的同一天。我认为我们可以在没有字典的情况下在数学上做到这一点。 @OS 虽然可能是这样,但上面的内容可能更清晰。对于阅读您的代码的其他人(甚至是您未来的自己)来说,数学解决方案可能并不明显,因此难以推理和阅读。记住你写了一次代码,但读了很多次。如果我看到这样的解决方案,包括您在 PR/代码审查中的第二个示例,我绝对会拒绝它 这不是我们可以使用 cmets 的吗?帮助我们更好地理解代码?日历计算本质上往往是数学计算。以上是关于为不同的日历获取一年中某一天的更好方法的主要内容,如果未能解决你的问题,请参考以下文章