vb.net 如何计算美国的假期
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18326446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to calculate holidays for the USA
提问by D_Bester
I need to know how to calculate USA holidays. I need a solution that works for any year. I didn't want to simply store the dates in a database that would need to be maintained.
我需要知道如何计算美国假期。我需要一个适用于任何一年的解决方案。我不想简单地将日期存储在需要维护的数据库中。
For holidays on the weekend it needs to follow policy of the US government to adjust to a weekday. If it falls on a Saturday it is adjusted to Friday. If it falls on a Sunday it needs to be adjusted to Monday. I understand many (most?) banks in the US do it the same way.
周末假期需要按照美国政府的政策调整为工作日。如果是星期六,则调整为星期五。如果它落在星期日,则需要调整到星期一。我知道美国的许多(大多数?)银行都是这样做的。
How do I calculate a list of USA holidays?
如何计算美国假期列表?
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
回答by D_Bester
This is one way to do it. A weakness of this method is that since the rules are hard coded I would need to change the code in the rare event that congress changed the rules. For my in-house software that is not a problem but it might be for others.
这是一种方法。这种方法的一个弱点是,由于规则是硬编码的,我需要在国会更改规则的极少数情况下更改代码。对于我的内部软件来说,这不是问题,但对其他人来说可能是问题。
Also I don't calculate Easter since that is not a US federal holiday. See Nature (1876) Algorithm for Calculating the Date of Easter
另外我不计算复活节,因为那不是美国联邦假期。参见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
回答by Redbaran
Converted to C# as a console program... I needed the dates in a text file quickly:
转换为 C# 作为控制台程序......我需要快速文本文件中的日期:
class Program
{
public class Holiday
{
public string HolidayName { get; set; }
public DateTime Date { get; set; }
public Holiday(string holidayName, DateTime date)
{
HolidayName = holidayName;
Date = date;
}
}
public static List<Holiday> getHolidayList(int vYear)
{
int FirstWeek = 1;
int SecondWeek = 2;
int ThirdWeek = 3;
int FourthWeek = 4;
int LastWeek = 5;
List<Holiday> HolidayList = new List<Holiday>();
// 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(new Holiday("NewYears", new DateTime(vYear, 1, 1)));
// Martin Luther King, Jr. third Mon in Jan
HolidayList.Add(new Holiday("MLK", GetNthDayOfNthWeek(new DateTime(vYear, 1, 1), DayOfWeek.Monday, ThirdWeek)));
// Washington's Birthday third Mon in Feb
HolidayList.Add(new Holiday("WashingtonsBDay", GetNthDayOfNthWeek(new DateTime(vYear, 2, 1), DayOfWeek.Monday, ThirdWeek)));
// Memorial Day last Mon in May
HolidayList.Add(new Holiday("MemorialDay", GetNthDayOfNthWeek(new DateTime(vYear, 5, 1), DayOfWeek.Monday, LastWeek)));
// Independence Day July 4
HolidayList.Add(new Holiday("IndependenceDay", new DateTime(vYear, 7, 4)));
// Labor Day first Mon in Sept
HolidayList.Add(new Holiday("LaborDay", GetNthDayOfNthWeek(new DateTime(vYear, 9, 1), DayOfWeek.Monday, FirstWeek)));
// Columbus Day second Mon in Oct
HolidayList.Add(new Holiday("Columbus", GetNthDayOfNthWeek(new DateTime(vYear, 10, 1), DayOfWeek.Monday, SecondWeek)));
// Veterans Day Nov 11
HolidayList.Add(new Holiday("Veterans", new DateTime(vYear, 11, 11)));
// Thanksgiving Day fourth Thur in Nov
HolidayList.Add(new Holiday("Thanksgiving", GetNthDayOfNthWeek(new DateTime(vYear, 11, 1), DayOfWeek.Thursday, FourthWeek)));
// Christmas Day Dec 25
HolidayList.Add(new Holiday("Christmas", new DateTime(vYear, 12, 25)));
//saturday holidays are moved to Fri; Sun to Mon
foreach (var holiday in HolidayList)
{
if (holiday.Date.DayOfWeek == DayOfWeek.Saturday)
{
holiday.Date = holiday.Date.AddDays(-1);
}
if (holiday.Date.DayOfWeek == DayOfWeek.Sunday)
{
holiday.Date = holiday.Date.AddDays(1);
}
}
//return
return HolidayList;
}
private static System.DateTime GetNthDayOfNthWeek(DateTime dt, DayOfWeek dayofWeek, int WhichWeek)
{
//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
System.DateTime dtFirst = new DateTime(dt.Year, dt.Month, 1);
//get first DayOfWeek of the month
System.DateTime dtRet = dtFirst.AddDays(6 - (int)dtFirst.AddDays(-1 * ((int)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))
{
dtRet = dtRet.AddDays(-7);
}
//return
return dtRet;
}
static void Main(string[] args)
{
for(int ii = 2013; ii < 2100; ii++)
{
var holidays = getHolidayList(ii);
foreach (var holiday in holidays)
{
Console.WriteLine(holiday.HolidayName + ": " + holiday.Date.ToShortDateString());
}
}
}
}
回答by Rich Moss
For reference, the list of Federal Holidays is defined in 5 U.S. Code §?6103. Holidays:
作为参考,联邦假日列表在5 美国法典 §6103 中定义。假期:
- New Year's Day, January 1.
- Birthday of Martin Luther King, Jr., the third Monday in January.
- Washington's Birthday, the third Monday in February.
- Memorial Day, the last Monday in May.
- Independence Day, July 4.
- Labor Day, the first Monday in September.
- Columbus Day, the second Monday in October.
- Veterans Day, November 11.
- Thanksgiving Day, the fourth Thursday in November.
- Christmas Day, December 25.
- 元旦,1 月 1 日。
- 小马丁路德金的生日,一月的第三个星期一。
- 华盛顿诞辰日,二月的第三个星期一。
- 阵亡将士纪念日,五月的最后一个星期一。
- 独立日,7 月 4 日。
- 劳动节,九月的第一个星期一。
- 哥伦布日,十月的第二个星期一。
- 退伍军人节,11 月 11 日。
- 感恩节,十一月的第四个星期四。
- 圣诞节,12 月 25 日。
For regular Monday through Friday workers, holidays that land on a Saturday will be observed on the Friday before. I've read in other places that holidays landing on a Sunday will be observed the following Monday.
对于周一至周五的普通员工,周六的假期将在前周五进行。我在其他地方读到过周日的假期将在下周一进行。
回答by D_Bester
Jay Muntz on CodeProject has an excellent implementation of holidays using an XML file to store the rules. That code doesn't adjust for weekends though.
CodeProject 上的 Jay Muntz 使用 XML 文件存储规则对假期进行了出色的实现。不过,该代码不会针对周末进行调整。
Also his version of tax day (April 15) doesn't correct for Emancipation Day in Washington DC although that may be irrelevant for this question.
此外,他的纳税日(4 月 15 日)版本并不适用于华盛顿特区的解放日,尽管这可能与这个问题无关。
回答by moonman239
Here's some code I whipped up in C#. Each holiday is represented as an instance of Holiday. To get the date of observance by the federal government, simply call the object's FederalObservance method. Notice, however, that only one of the holidays is an actual holiday; I just created two holidays as examples.
这是我用 C# 编写的一些代码。每个假期都表示为 Holiday 的一个实例。要获得联邦政府的遵守日期,只需调用对象的 FederalObservance 方法即可。但是请注意,只有一个假期是实际假期;我刚刚创建了两个假期作为示例。
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;
}
}
}
回答by Joe
Thanks so much for your answer D_Bester. I was trying to do this in VBA for Excel.
非常感谢您的回答 D_Bester。我试图在 VBA for Excel 中执行此操作。
I got your VB code translated into VBA for Excel. I thought I would post my code here, for anyone else who may be trying that language.
我把你的 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
回答by live2
Nager.Date supports the public holiday for USA the full source code is available on githuba lot of other coutries are supported.
Nager.Date 支持美国的公共假期,完整的源代码可在github 上获得,还支持许多其他国家。
Nuget
纽吉特
PM> install-package Nager.Date
Example:
例子:
Get all publicHolidays of a year
获取一年中的所有 publicHolidays
var publicHolidays = DateSystem.GetPublicHoliday("US", 2017);
Check if a date a public holiday
检查日期是否为公共假期
if (DateSystem.IsPublicHoliday(date, "US"))
{
//logic
}
回答by TxRegex
Here is a C# solution using Lync. I didn't see any other answers using this approach. I'm putting all the days of the month into a List of type DateTime and then using Lync to select exactly what I want. Yes this takes up more time/memory, but if that's not the most critical priority, look how easily it reads...
这是使用 Lync 的 C# 解决方案。我没有看到使用这种方法的任何其他答案。我将一个月中的所有天数放入 DateTime 类型的列表中,然后使用 Lync 来准确选择我想要的内容。是的,这会占用更多的时间/内存,但如果这不是最关键的优先级,那么看看它读取起来有多容易......
/// <summary>
/// Find the Nth day of the month that matches the given dayOfWeek
/// </summary>
/// <param name="year">The year</param>
/// <param name="month">The month number 1 - 12</param>
/// <param name="dayOfWeek">The day of the week</param>
/// <param name="occurance">Take the Nth day found</param>
/// <returns></returns>
public static DateTime GetNthDayOfMonth(int year, int month, DayOfWeek dayOfWeek, int occurance)
{
return GetDaysInMonth(year, month).Where(d => d.DayOfWeek == dayOfWeek).Skip(occurance - 1).FirstOrDefault();
}
/// <summary>
/// Find the Nth last day of the month that matches the given dayOfWeek
/// </summary>
/// <param name="year">The year</param>
/// <param name="month">The month number 1 - 12</param>
/// <param name="dayOfWeek">The day of the week</param>
/// <param name="occurance">Take the Nth day found</param>
/// <returns></returns>
public static DateTime GetNthLastDayOfMonth(int year, int month, DayOfWeek dayOfWeek, int occurance)
{
return GetDaysInMonth(year, month).Where(d => d.DayOfWeek == dayOfWeek).Reverse().Skip(occurance - 1).FirstOrDefault();
}
/// <summary>
/// Put all dates of the month into a list that lync can work with
/// </summary>
/// <param name="year">The year</param>
/// <param name="month">The month number 1 - 12</param>
/// <returns></returns>
public static List<DateTime> GetDaysInMonth(int year, int month)
{
List<DateTime> days = new List<DateTime>();
var d = new DateTime(year, month, 1);
while(d.Month == month)
{
days.Add(d);
d = d.AddDays(1);
}
return days;
}

