16

アメリカの祝日の計算方法を知りたいです。どの年でも機能するソリューションが必要です。メンテナンスが必要なデータベースに日付を単純に保存したくありませんでした。

週末の祝日については、米国政府の方針に従って平日に調整する必要があります。土曜日の場合は金曜日に調整されます。日曜日になる場合は、月曜日に調整する必要があります。私は、米国の多くの (ほとんどの?) 銀行が同じ方法でそれを行っていることを理解しています。

アメリカの祝日のリストを計算するにはどうすればよいですか?

Public Function getHolidayList(ByVal vYear As Integer) As List(Of Date)

    Dim HolidayList As New List(Of Date)

    '...fill the list with holidays 
    ' New Year's Day            Jan 1
    ' Martin Luther King, Jr. third Mon in Jan
    ' Washington's Birthday third Mon in Feb
    ' Memorial Day          last Mon in May
    ' Independence Day      July 4
    ' Labor Day             first Mon in Sept
    ' Columbus Day          second Mon in Oct
    ' Veterans Day          Nov 11
    ' Thanksgiving Day      fourth Thur in Nov
    ' Christmas Day         Dec 25

    'adjust for weekends

End Function

www.archives.gov

www.usa.gov

www.opm.gov

4

9 に答える 9

18

これは 1 つの方法です。この方法の弱点は、ルールがハードコードされているため、まれに議会がルールを変更した場合にコードを変更する必要があることです。私の社内ソフトウェアでは問題ありませんが、他のソフトウェアでは問題になる可能性があります。

また、イースターは米国連邦の祝日ではないため、計算しません。Nature (1876) 復活祭の日付を計算するためのアルゴリズムを参照

Public Function getHolidayList(ByVal vYear As Integer) As List(Of Date)

    Dim FirstWeek As Integer = 1
    Dim SecondWeek As Integer = 2
    Dim ThirdWeek As Integer = 3
    Dim FourthWeek As Integer = 4
    Dim LastWeek As Integer = 5

    Dim HolidayList As New List(Of Date)

    '   http://www.usa.gov/citizens/holidays.shtml      
    '   http://archive.opm.gov/operating_status_schedules/fedhol/2013.asp

    ' New Year's Day            Jan 1
    HolidayList.Add(DateSerial(vYear, 1, 1))

    ' Martin Luther King, Jr. third Mon in Jan
    HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 1, 1), DayOfWeek.Monday, ThirdWeek))

    ' Washington's Birthday third Mon in Feb
    HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 2, 1), DayOfWeek.Monday, ThirdWeek))

    ' Memorial Day          last Mon in May
    HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 5, 1), DayOfWeek.Monday, LastWeek))

    ' Independence Day      July 4
    HolidayList.Add(DateSerial(vYear, 7, 4))

    ' Labor Day             first Mon in Sept
    HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 9, 1), DayOfWeek.Monday, FirstWeek))

    ' Columbus Day          second Mon in Oct
    HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 10, 1), DayOfWeek.Monday, SecondWeek))

    ' Veterans Day          Nov 11
    HolidayList.Add(DateSerial(vYear, 11, 11))

    ' Thanksgiving Day      fourth Thur in Nov
    HolidayList.Add(GetNthDayOfNthWeek(DateSerial(vYear, 11, 1), DayOfWeek.Thursday, FourthWeek))

    ' Christmas Day         Dec 25
    HolidayList.Add(DateSerial(vYear, 12, 25))

    'saturday holidays are moved to Fri; Sun to Mon
    For i As Integer = 0 To HolidayList.Count - 1
        Dim dt As Date = HolidayList(i)
        If dt.DayOfWeek = DayOfWeek.Saturday Then
            HolidayList(i) = dt.AddDays(-1)
        End If
        If dt.DayOfWeek = DayOfWeek.Sunday Then
            HolidayList(i) = dt.AddDays(1)
        End If
    Next

    'return
    Return HolidayList

End Function

Private Function GetNthDayOfNthWeek(ByVal dt As Date, ByVal DayofWeek As Integer, ByVal WhichWeek As Integer) As Date
    'specify which day of which week of a month and this function will get the date
    'this function uses the month and year of the date provided

    'get first day of the given date
    Dim dtFirst As Date = DateSerial(dt.Year, dt.Month, 1)

    'get first DayOfWeek of the month
    Dim dtRet As Date = dtFirst.AddDays(6 - dtFirst.AddDays(-(DayofWeek + 1)).DayOfWeek)

    'get which week
    dtRet = dtRet.AddDays((WhichWeek - 1) * 7)

    'if day is past end of month then adjust backwards a week
    If dtRet >= dtFirst.AddMonths(1) Then
        dtRet = dtRet.AddDays(-7)
    End If

    'return
    Return dtRet

End Function
于 2013-08-20T03:21:14.577 に答える
2

C# で作成したコードを次に示します。各休日は、Holiday のインスタンスとして表されます。連邦政府による遵守日を取得するには、オブジェクトの FederalObservance メソッドを呼び出すだけです。ただし、実際の休日は 1 つだけであることに注意してください。例として 2 つの休日を作成しました。

        public static void Main (string[] args)
    {
        Holiday SatHoliday = new Holiday ("Satman", 2015, 11, 20);
        Holiday Thanksgiving = new Holiday ("Thanksgiving", 2015, 11, 3, DayOfWeek.Thursday);
        Holiday[] holidays = new Holiday[] { SatHoliday, Thanksgiving };

    }
}
class Holiday
{
    public DateTime hDate;
    public String name;
    public Holiday(String name, int year, int month, int day)
    {
        this.name = name;
        this.hDate = new DateTime (year, month, day);
    }
        public Holiday(String name, int year, int month, int weekNum/* Weeks are numbered starting with 0. So, the first week would be 0, the second week 1, etc.*/, DayOfWeek dayOfWeek)
    {
        this.name = name;
        DateTime firstOfMonth = new DateTime (year, month, 1);
        this.hDate = firstOfMonth.AddDays (7 * weekNum + (int)dayOfWeek - (int)firstOfMonth.DayOfWeek);
    }
    public DateTime FederalObservance()
    {

                    if (hDate.DayOfWeek == DayOfWeek.Saturday) {
                        return hDate.AddDays (-1);
                    } else if (hDate.DayOfWeek == DayOfWeek.Sunday) {
                        return hDate.AddDays (1);
        } else {
            return hDate;
        }
    }
}
于 2015-11-20T00:07:40.937 に答える
2

CodeProject の Jay Muntz は、XML ファイルを使用してルールを保存することで、休日をうまく実装しています。ただし、そのコードは週末には調整されません。

また、彼のバージョンの税日 (4 月 15 日) は、この質問には関係ないかもしれませんが、ワシントン DC の Emancipation Day に対応していません。

2006 年 1 月 5 日、Jay Muntz による動的休日計算ツール

于 2013-08-20T03:33:15.050 に答える
1

D_Bester さん、ご回答ありがとうございます。VBA for Excelでこれをやろうとしていました。

あなたの VB コードを VBA for Excel に翻訳しました。その言語を試している可能性のある他の人のために、ここにコードを投稿すると思いました。

Sub displayHolidays()
    Dim myHolidayList As New Collection
    Set myHolidayList = GetHolidayList(2005)

    For x = 1 To (myHolidayList.Count)
        Debug.Print myHolidayList(x)
    Next
End Sub

Function GetHolidayList(ByVal vYear As Integer) As Collection
    Const FirstWeek As Integer = 1
    Const SecondWeek As Integer = 2
    Const ThirdWeek As Integer = 3
    Const FourthWeek As Integer = 4
    Const LastWeek As Integer = 5
    Const DayofWeek_Monday As Integer = 2
    Const DayofWeek_Thursday As Integer = 5
    Const DayofWeek_Saturday As Integer = 7
    Const DayofWeek_Sunday As Integer = 1

    Dim holidayList As New Collection
    Dim finalHolidayList As New Collection

    '   http://www.usa.gov/citizens/holidays.shtml
    '   http://archive.opm.gov/operating_status_schedules/fedhol/2013.asp

    ' New Year's Day            Jan 1
    holidayList.Add (DateSerial(vYear, 1, 1))

    ' Martin Luther King, Jr. third Mon in Jan
    holidayList.Add (GetNthDayOfNthWeek(DateSerial(vYear, 1, 1), DayofWeek_Monday, ThirdWeek))

    ' Washington's Birthday third Mon in Feb
    holidayList.Add (GetNthDayOfNthWeek(DateSerial(vYear, 2, 1), DayofWeek_Monday, ThirdWeek))

    ' Memorial Day          last Mon in May
    holidayList.Add (GetNthDayOfNthWeek(DateSerial(vYear, 5, 1), DayofWeek_Monday, LastWeek))

    ' Independence Day      July 4
    holidayList.Add (DateSerial(vYear, 7, 4))

    ' Labor Day             first Mon in Sept
    holidayList.Add (GetNthDayOfNthWeek(DateSerial(vYear, 9, 1), DayofWeek_Monday, FirstWeek))

    ' Columbus Day          second Mon in Oct
    holidayList.Add (GetNthDayOfNthWeek(DateSerial(vYear, 10, 1), DayofWeek_Monday, SecondWeek))

    ' Veterans Day          Nov 11
    holidayList.Add (DateSerial(vYear, 11, 11))

    ' Thanksgiving Day      fourth Thur in Nov
    holidayList.Add (GetNthDayOfNthWeek(DateSerial(vYear, 11, 1), DayofWeek_Thursday, FourthWeek))

    ' Christmas Day         Dec 25
    holidayList.Add (DateSerial(vYear, 12, 25))

    'saturday holidays are moved to Fri; Sun to Mon
    For Each dt In holidayList
        If Weekday(dt) = DayofWeek_Saturday Then
            dt = DateAdd("d", -1, dt)
        End If
        If Weekday(dt) = DayofWeek_Sunday Then
            dt = DateAdd("d", 1, dt)
        End If
        finalHolidayList.Add dt
    Next dt

    'return
    Set GetHolidayList = finalHolidayList
End Function

Function GetNthDayOfNthWeek(ByVal dt As Date, ByVal DayofWeek As Integer, ByVal WhichWeek As Integer) As Date
    'specify which day of which week of a month and this function will get the date
    'this function uses the month and year of the date provided
    Dim dtFirst As Date
    Dim innerDate As Date
    Dim monthAdd As Date

    'get first day of the given date
    dtFirst = DateSerial(Year(dt), Month(dt), 1)

    'get first DayOfWeek of the month
    innerDate = DateAdd("d", -DayofWeek, dtFirst)
    GetNthDayOfNthWeek = DateAdd("d", (7 - Weekday(innerDate)), dtFirst)

    'get which week
    GetNthDayOfNthWeek = DateAdd("d", ((WhichWeek - 1) * 7), GetNthDayOfNthWeek)

    'if day is past end of month then adjust backwards a week
    monthAdd = DateAdd("m", 1, dtFirst)
    If GetNthDayOfNthWeek >= monthAdd Then
        GetNthDayOfNthWeek = DateAdd("d", (-7), GetNthDayOfNthWeek)
    End If
End Function
于 2020-05-01T17:57:10.117 に答える
0

土>>金と日>>月の週末ルールには特殊なケースがあります。2022 年の元旦は土曜日ですが、私の雇用主は 12 月 31 日までそれを守りたくありません。代わりに 2022 年の変動休日を作成しています。)
私は、月末日を含む月の特定の日に継続的な資金移動をサポートするアプリケーションを担当していました。週末のルールは月曜日にプッシュされ、休日のルールは翌日でした。8 月 31 日が土曜日の場合、両方のルールが適用され、一部のユーザーは 9 月 3 日の火曜日にプッシュすることに反対しました。 3 日間の週末に着陸する月の最終日は金曜日まで。イースターに関して - ニューヨーク証券取引所は聖金曜日に閉まるため、イースターの計算は有効なビジネス ケースです。
場合によっては、毎年恒例の休日を登録するだけで、より良いユーザー ソリューションになることもあります。

于 2021-12-15T01:07:12.397 に答える