为不同的日历获取一年中某一天的更好方法

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 的吗?帮助我们更好地理解代码?日历计算本质上往往是数学计算。

以上是关于为不同的日历获取一年中某一天的更好方法的主要内容,如果未能解决你的问题,请参考以下文章

r 从日期字符串中获取一年中的某一天(可能需要调整格式)

推断一年中某一天是这一年的第几天的函数接口

JavaScript怎么获得某一天的前一天日期

java如何获取某一天的日期?

MySQL中, 如何查询某一天, 某一月, 某一年的数据.

获取某一天的前多少天多少月多少年的时间