【问题标题】:Business/Holiday date handling [closed]商务/假日日期处理[关闭]
【发布时间】:2021-08-24 03:27:22
【问题描述】:

我正在寻找与 Perl 模块 Date::Manip 类似的 C# 类/库,就商务/假日日期而言。在 Perl 中使用该模块,我可以给它传递一个日期,并确定它是工作日(即周一至周五)还是假期。假期很容易在配置文件中定义(参见Date::Manip::Holidays)。您可以输入适用于每一年的“固定”日期,例如:

12/25                           = Christmas

或每年的“动态”日期,例如:

last Monday in May              = Memorial Day

或给定年份的“固定”日期,例如:

5/22/2010                       = Bob's Wedding

您还可以输入一个日期并在下一个/上一个工作日取回。

在 C# 世界中有人知道类似的事情吗?我发现了一些实现我需要的部分的东西(http://www.codeproject.com/KB/cs/busdatescalculation.aspxhttp://www.codeproject.com/KB/dotnet/HolidayCalculator.aspx),我可以将它们分开并制作我需要的东西。但是,如果其他人已经这样做了,为什么还要这样做呢?

【问题讨论】:

  • Date::Manip 知道 Bob 的婚礼是什么时候!?
  • 如果你在配置文件中定义它就可以了! :)

标签: c#


【解决方案1】:

Nager.Date 支持 110 多个国家/地区(美国、德国、法国、俄罗斯、英国……),该库可用于 .net45 和 .netstandard 2.0。支持的国家列表可以在here找到。

Nuget

PM> install-package Nager.Date

示例:

获取一年中的所有公共假期

var publicHolidays = DateSystem.GetPublicHoliday(2018, CountryCode.DE);

检查日期是否为公共假期

var date = new DateTime(2018, 01, 01);
if (DateSystem.IsPublicHoliday(date, CountryCode.DE))
{
    //Yes - New Year's Day
}

【讨论】:

  • 酷,工作得很好!只是注意到这些年来国家代码参数似乎已经从"DE"更改为CountryCode.DE
  • 非常酷,但请注意它需要 .Net 4.5。
【解决方案2】:

聚会有点晚了,但它会帮助其他人在谷歌上搜索它。在http://web.archive.org/web/20210128001521/http://geekswithblogs.net/wpeck/archive/2011/12/27/us-holiday-list-in-c.aspx 找到了一个很好的答案。它甚至考虑到了周末的假期。

private static HashSet<DateTime> GetHolidays(int year) 
{ 
    HashSet<DateTime> holidays = new HashSet<DateTime>();

    // New Years
    DateTime newYearsDate = AdjustForWeekendHoliday(new DateTime(year, 1, 1)); 
    holidays.Add(newYearsDate); 

    // Memorial Day -- last monday in May 
    DateTime memorialDay = new DateTime(year, 5, 31); 
    DayOfWeek dayOfWeek = memorialDay.DayOfWeek; 
    while (dayOfWeek != DayOfWeek.Monday) 
    { 
        memorialDay = memorialDay.AddDays(-1); 
        dayOfWeek = memorialDay.DayOfWeek; 
    } 
    holidays.Add(memorialDay); 
    
    // Independence Day
    DateTime independenceDay = AdjustForWeekendHoliday(new DateTime(year, 7, 4)); 
    holidays.Add(independenceDay); 
 
    // Labor Day -- 1st Monday in September 
    DateTime laborDay = new DateTime(year, 9, 1); 
    dayOfWeek = laborDay.DayOfWeek; 
    while(dayOfWeek != DayOfWeek.Monday) 
    { 
        laborDay = laborDay.AddDays(1); 
        dayOfWeek = laborDay.DayOfWeek; 
    } 
    holidays.Add(laborDay);

    // Thanksgiving Day -- 4th Thursday in November 
    var thanksgiving = (from day in Enumerable.Range(1, 30) 
                   where new DateTime(year, 11, day).DayOfWeek == DayOfWeek.Thursday 
                   select day).ElementAt(3); 
    DateTime thanksgivingDay = new DateTime(year, 11, thanksgiving); 
    holidays.Add(thanksgivingDay);

    // Christmas Day 
    DateTime christmasDay = AdjustForWeekendHoliday(new DateTime(year, 12, 25)); 
    holidays.Add(christmasDay); 

    // Next year's new years check
    DateTime nextYearNewYearsDate = AdjustForWeekendHoliday(new DateTime(year + 1, 1, 1));
    if (nextYearNewYearsDate.Year == year)
    holidays.Add(nextYearNewYearsDate);

    return holidays; 
}

public static DateTime AdjustForWeekendHoliday(DateTime holiday) 
{ 
    if (holiday.DayOfWeek == DayOfWeek.Saturday) 
    { 
        return holiday.AddDays(-1); 
    } 
    else if (holiday.DayOfWeek == DayOfWeek.Sunday) 
    { 
        return holiday.AddDays(1); 
    } 
    else 
    { 
        return holiday; 
    } 
}

【讨论】:

  • 请注意,根据您的使用案例,您可能需要考虑元旦何时落在星期六。例如,2010 年 12 月 31 日将是 2011 年 1 月 1 日的观察日。
  • @FacioRatio 查看底部的 AdjustForWeekendHoliday 方法。它取假期的日期,如果是星期六,则减去一天,如果是星期日,则增加一天。
  • 对,但在我的情况下,由于观察日有时在不同的年份,我需要考虑这一点。不过,只要告诉您某一年的假期是什么,它对我来说非常有用,谢谢!
  • @FacioRatio 除非我误解了你,否则 AdjustForWeekendHoliday 方法也应该能处理你的问题。 DateTime.AddDays() 返回初始值加上传入的天数的新 DateTime。它知道何时有闰日、新月或新年。所以... New DateTime(2017,1,1).AddDays(-1) 将返回 (2016,12,31)。 New DateTime(2016,02,28).AddDays(1) 将返回 (2016,02,29)。 New DateTime(2017,02,28).AddDays(1) 将返回 (2017,03,01)。
  • @Todes3ngel 它不会返回错误的日期。它工作正常。但是,对于 2010 年,2010 年 12 月 31 日有一个假期。如果您针对 2010 运行此代码,它将不会显示。为什么?因为那个假期是因为 2011 年新年是在星期六,这会将它推回一天到 2010 年。如果您针对该方法运行 2011,您将看到 12/31/2010,但如果您运行,您将看不到它2010 年反对它。我希望这能很好地解释它。
【解决方案3】:

drules project 是一个可用于生成此类规则的库。

5 月的最后一个星期一是:

roll(*/5/last, -1, mon)

【讨论】:

    【解决方案4】:

    我找不到完全符合我要求的东西,所以我使用了来自http://www.codeproject.com/KB/dotnet/HolidayCalculator.aspx 的代码并对其进行了修改以满足我的需要。它完成了我需要的大部分工作,因此不需要太多调整。

    【讨论】:

    • 很旧的一个现在这个
    【解决方案5】:

    如果您对广泛的国家/地区参考感兴趣。我正在考虑最初专注于银行或交易所假期的 QuantLib。如有必要,您可以在 C# 中构建库,尽管这样做可能很繁重。

    无论如何,这是迄今为止我能找到的最佳参考。

    QuantLib: Calendars

    【讨论】:

    • 请提供问题的答案(带有示例),而不仅仅是链接。
    • 请在您的答案中发布链接的主要部分。如果将来该链接断开,则此答案将毫无用处
    【解决方案6】:

    这是一个营业时间计算器,它还处理金融机构使用的市场假期。它会检查所有 9 个市场假期,您可以调整工作日或周末的营业时间。

    Business Hours Calculator

    【讨论】:

      【解决方案7】:

      Date::Manip 可以处理复杂的规则,例如耶稣受难日。这是我使用的 Date::Manip holidays.cnf 文件中耶稣受难日的定义:

      1*0:0:0:0:0:0*EASTER,PD5    = Good Friday
      

      在内部,它具有根据月相确定复活节时间的逻辑。

      【讨论】:

      • 是的,但问题是要找到一个可以做 Date::Manip 所做的 C# 库。
      猜你喜欢
      • 2011-04-18
      • 2012-01-21
      • 2011-08-15
      • 2023-04-02
      • 1970-01-01
      • 2010-09-27
      • 2011-11-13
      • 2019-04-13
      相关资源
      最近更新 更多