C# 平到下个月,因为这对我来说似乎更有用
我还加入了一个LINQPad可运行的示例程序C# 平到下个月,因为这对我来说似乎更有用,c#,.net,datetime,C#,.net,Datetime,我还加入了一个LINQPad可运行的示例程序 void Main() { DayOfWeek dow = DayOfWeek.Friday; int y = 2014; int m = 2; String.Format("First {0}: {1}", new object[] { dow, DateHelper.FirstDayOfWeekInMonth(y, m, dow) }).Dump(); "".Dump(); String.Fo
void Main()
{
DayOfWeek dow = DayOfWeek.Friday;
int y = 2014;
int m = 2;
String.Format("First {0}: {1}", new object[] { dow, DateHelper.FirstDayOfWeekInMonth(y, m, dow) }).Dump();
"".Dump();
String.Format("Last {0}: {1}", new object[] { dow, DateHelper.LastDayOfWeekInMonth(y, m, dow) }).Dump();
"".Dump();
for(int i = 1; i <= 6; i++)
String.Format("{0} #{1}: {2}", new object[] { dow, i, DateHelper.XthDayOfWeekInMonth(y, m, dow, i) }).Dump();
}
public class DateHelper
{
public static DateTime FirstDayOfWeekInMonth(int year, int month, DayOfWeek day)
{
DateTime res = new DateTime(year, month, 1);
int offset = -(res.DayOfWeek - day);
if (offset < 0)
offset += 7;
res = res.AddDays(offset);
return res;
}
public static DateTime LastDayOfWeekInMonth(int year, int month, DayOfWeek day)
{
DateTime dt = new DateTime(year, month, 1).AddMonths(1);
DateTime res = FirstDayOfWeekInMonth(dt.Year, dt.Month, day);
res = res.AddDays(-7);
return res;
}
public static DateTime XthDayOfWeekInMonth(int year, int month, DayOfWeek day, int x)
{
DateTime res = DateTime.MinValue;
if (x > 0)
{
res = FirstDayOfWeekInMonth(year, month, day);
if (x > 1)
res = res.AddDays((x - 1) * 7);
res = res.Year == year && res.Month == month ? res : DateTime.MinValue;
}
return res;
}
}
这是我的算法:
柜台将为您提供该日期当月的第n个星期五(或即将到来的星期五)。我将此日期时间传递给您,作为我所查看的月初的日期时间
private DateTime thirdSunday(DateTime timeFrom)
{
List<DateTime> days = new List<DateTime>();
DateTime testDate = timeFrom;
while (testDate < timeFrom.AddMonths(1))
{
if (testDate.DayOfWeek == DayOfWeek.Friday)
{
days.Add(testDate);
}
testDate = testDate.AddDays(1);
}
return days[2];
}
private DateTime thirdSunday(DateTime timeFrom)
{
列表天数=新列表();
DateTime testDate=timeFrom;
而(测试日期
以下方法效果很好,未提供事件验证。您可以找到给定日期月份的任何第n天,从开始或最后。如果要查找上一个事件,请提供负发生值
public static DateTime GetDayOfMonth(DateTime dateValue, DayOfWeek dayOfWeek, int occurance)
{
List<DateTime> dayOfWeekRanges = new List<DateTime>();
//move to the first of th month
DateTime startOfMonth = new DateTime(dateValue.Year, dateValue.Month, 1);
//move startOfMonth to the dayOfWeek requested
while (startOfMonth.DayOfWeek != dayOfWeek)
startOfMonth = startOfMonth.AddDays(1);
do
{
dayOfWeekRanges.Add(startOfMonth);
startOfMonth = startOfMonth.AddDays(7);
} while (startOfMonth.Month == dateValue.Month);
bool fromLast = occurance < 0;
if (fromLast)
occurance = occurance * -1;
if (fromLast)
return dayOfWeekRanges[dayOfWeekRanges.Count - occurance];
else
return dayOfWeekRanges[occurance - 1];
}
public static DateTime GetDayOfMonth(DateTime dateValue、DayOfWeek-DayOfWeek、int-occurrence)
{
List dayOfWeekRanges=新列表();
//移到第个月的第一天
DateTime startOfMonth=新的日期时间(dateValue.Year,dateValue.Month,1);
//将startOfMonth移动到请求的星期几
while(startOfMonth.DayOfWeek!=DayOfWeek)
startOfMonth=startOfMonth.AddDays(1);
做
{
dayOfWeekRanges.Add(startOfMonth);
startOfMonth=startOfMonth.AddDays(7);
}while(startOfMonth.Month==dateValue.Month);
bool fromLast=发生率<0;
if(fromLast)
发生率=发生率*-1;
if(fromLast)
返回Weekranges日[dayOfWeekRanges.Count-发生];
其他的
周末回归日[发生-1];
}
这是我的两分钱。。。
没有不必要的循环或测试的优化解决方案:
public static DateTime ThirdFridayOfMonth(DateTime dateTime)
{
int day = dateTime.Day;
return dateTime.AddDays(21 - day - ((int)dateTime.DayOfWeek + 37 - day) % 7);
}
我编写了@justcoding121代码的扩展版本,可以从每月的最后一天获得。我不知道这个算法是对的,但到目前为止它仍然有效
public static int? GetNthDayOfWeekInMonth(int year, int month, DayOfWeek dow, int weekNumOfMonth)
{
if (weekNumOfMonth < -5 || weekNumOfMonth == 0 || weekNumOfMonth > 5)
throw new ArgumentOutOfRangeException("weekNumOfMonth", $"must be between 1~5 or -1~-5. ({weekNumOfMonth})");
int daysOfMonth = DateTime.DaysInMonth(year, month);
if (weekNumOfMonth > 0)
{
var firstDay = new DateTime(year, month, 1);
var firstDayOfTargetDOW = (int)dow - (int)firstDay.DayOfWeek;
if (firstDayOfTargetDOW < 0)
firstDayOfTargetDOW += 7;
var resultedDay = (firstDayOfTargetDOW + 1) + (7 * (weekNumOfMonth - 1));
if (resultedDay > daysOfMonth)
return null;
return resultedDay;
}
else
{
var lastDay = new DateTime(year, month, daysOfMonth);
var firstDayOfTargetDOW = (int)lastDay.DayOfWeek - (int)dow;
if (firstDayOfTargetDOW < 0)
firstDayOfTargetDOW += 7;
var resultedDay = firstDayOfTargetDOW + (7 * (Math.Abs(weekNumOfMonth) - 1));
if (resultedDay > daysOfMonth)
return null;
return (daysOfMonth - resultedDay);
}
}
我知道这个帖子很旧。我有这个解决方案,试图找到一个更干净的代码#伯伯叔叔
publicstaticboolshirdwednesday(DateTime-inputDate)
{
DateTime firstDayOfMonth=新的日期时间(inputDate.Year,inputDate.Month,1);
DateTime firstDayOfNextMonth=firstDayOfMonth.AddMonths(1);
int周三计数=0;
while(每月第一天<下个月第一天)
{
如果(每月的第一天。星期三的第二天==星期三的第二天)
星期三计数++;
如果(星期三计数=3)
{
如果(inputDate==每月的第一天)
返回true;
其他的
返回false;
}
firstDayOfMonth=每月第一天添加天数(1);
}
返回false;
}
+1解释而不是给出代码,因为这是一个算法问题,而不是技术问题。这应该是答案,因为它很清楚,普遍适用,并且实际有效。我已经在它的基础上创建了一个C#类,并添加了它作为任何想要快速解决问题的人的答案。你有一个bug。它应该如下所示。否则我认为这是最干净的解决方案更改为每月第一天DateTime dayOfMonth=instance.AddDays(1-instance.day);此测试:if(occurrence<0 | | occurrence>5)将允许出现值为#0,我认为这是一个错误。这是可行的,但TryGet方法是否应该引发异常?我认为您是根据Int32.TryParseMost等方法建模的,如果不是所有以Try开头的Microsoft.Net framework方法都不会对正常错误引发异常。相反,如果尝试以布尔值形式成功,它们将返回,并在out参数中返回有效结果(如不抛出异常)。现在考虑到我添加了额外的参数,验证参数并在这些参数无效时抛出异常仍然是最佳做法(我可能不应该检查实例,因为DateTime不能为null)。例如,可以在反射时同时抛出ArgumentException
和NotSupportedException
,将XthDayOfWeekInMonth更改为接受负数“x”表示“最后一个”、“倒数第二个”等是非常好的。但是我没有个人的使用案例,所以我没有这样做:o)LastDayOfWeekInMonth在12月失败,因为DateTime不能用第13个月来计算出您需要下一年的1月。该死的,我怎么从来没有注意到这一点?我会编辑一个补丁谢谢你的功能!效果很好,补充了马克的答案。谢谢。。。这真的很有帮助。:)欢迎来到SO。回答这个问题可能有助于解释您演示的代码背后的逻辑/基本原理。
public static DateTime GetThirdFriday(int year, int month)
{
DateTime baseDay = new DateTime(year, month, 15);
int thirdfriday = 15 + ((12 - (int)baseDay.DayOfWeek) % 7);
return new DateTime(year, month, thirdfriday);
}
private readonly static int[] thirdfridays =
new int[] { 20, 19, 18, 17, 16, 15, 21 };
public static int GetThirdFriday(int year, int month)
{
DateTime baseDay = new DateTime(year, month, 15);
return thirdfridays[(int)baseDay.DayOfWeek];
}
public DateTime GetThirdThursday(DateTime now)
{
DateTime ThirdThursday;
now = DateTime.Now;
string wkday;
DateTime firstday = new DateTime(now.Year, now.Month, 1);
ThirdThursday = firstday.AddDays(15);
// ThirdThursday = now.AddDays((now.Day - 1) * -1).AddDays(14);
wkday = ThirdThursday.DayOfWeek.ToString();
while (wkday.CompareTo("Thursday") < 0)
{
ThirdThursday.AddDays(1);
}
return ThirdThursday;
}
public static bool TryGetDayOfMonth(this DateTime instance,
DayOfWeek dayOfWeek,
int occurance,
out DateTime dateOfMonth)
{
if (instance == null)
{
throw new ArgumentNullException("instance");
}
if (occurance <= 0 || occurance > 5)
{
throw new ArgumentOutOfRangeException("occurance", "Occurance must be greater than zero and less than 6.");
}
bool result;
dateOfMonth = new DateTime();
// Change to first day of the month
DateTime dayOfMonth = instance.AddDays(1 - instance.Day);
// Find first dayOfWeek of this month;
if (dayOfMonth.DayOfWeek > dayOfWeek)
{
dayOfMonth = dayOfMonth.AddDays(7 - (int)dayOfMonth.DayOfWeek + (int)dayOfWeek);
}
else
{
dayOfMonth = dayOfMonth.AddDays((int)dayOfWeek - (int)dayOfMonth.DayOfWeek);
}
// add 7 days per occurance
dayOfMonth = dayOfMonth.AddDays(7 * (occurance - 1));
// make sure this occurance is within the original month
result = dayOfMonth.Month == instance.Month;
if (result)
{
dateOfMonth = dayOfMonth;
}
return result;
}
DateTime myDate = new DateTime(2013, 1, 1)
DateTime dateOfMonth;
myDate.TryGetDayOfMonth(DayOfWeek.Sunday, 1, out dateOfMonth)
// returns: true; dateOfMonth = Sunday, 1/6/2013
myDate.TryGetDayOfMonth(DayOfWeek.Sunday, 4, out dateOfMonth)
// returns: true; dateOfMonth = Sunday, 1/27/2013
myDate.TryGetDayOfMonth(DayOfWeek.Sunday, 5, out dateOfMonth)
// returns: false;
myDate.TryGetDayOfMonth(DayOfWeek.Wednesday, 1, out dateOfMonth)
// returns: true; dateOfMonth = Wednesday, 1/2/2013
myDate.TryGetDayOfMonth(DayOfWeek.Wednesday, 4, out dateOfMonth)
// returns: true; dateOfMonth = Wednesday, 1/23/2013
myDate.TryGetDayOfMonth(DayOfWeek.Wednesday, 5, out dateOfMonth)
// returns: true; dateOfMonth = Wednesday, 1/30/2013
// etc
int thirdFriday = DayFinder.FindDay(2013, 12, DayOfWeek.Friday, 3);
public class DayFinder
{
//For example to find the day for 2nd Friday, February, 2016
//=>call FindDay(2016, 2, DayOfWeek.Friday, 2)
public static int FindDay(int year, int month, DayOfWeek Day, int occurance)
{
if (occurance <= 0 || occurance > 5)
throw new Exception("Occurance is invalid");
DateTime firstDayOfMonth = new DateTime(year, month, 1);
//Substract first day of the month with the required day of the week
var daysneeded = (int)Day - (int)firstDayOfMonth.DayOfWeek;
//if it is less than zero we need to get the next week day (add 7 days)
if (daysneeded < 0) daysneeded = daysneeded + 7;
//DayOfWeek is zero index based; multiply by the Occurance to get the day
var resultedDay = (daysneeded + 1) + (7 * (occurance - 1));
if (resultedDay > (firstDayOfMonth.AddMonths(1) - firstDayOfMonth).Days)
throw new Exception(String.Format("No {0} occurance(s) of {1} in the required month", occurance, Day.ToString()));
return resultedDay;
}
}
public DateTime DateOfWeekOfMonth(int year, int month, DayOfWeek dayOfWeek, byte weekNumber)
{
DateTime tempDate = new DateTime(year, month, 1);
tempDate = tempDate.AddDays(-(tempDate.DayOfWeek - dayOfWeek));
return
tempDate.Day > (byte)DayOfWeek.Saturday
? tempDate.AddDays(7 * weekNumber)
: tempDate.AddDays(7 * (weekNumber - 1));
}
public DateTime DateOfWeekOfMonth(DateTime sender, DayOfWeek dayOfWeek, byte weekNumber)
{
return DateOfWeekOfMonth(sender.Year, sender.Month, dayOfWeek, weekNumber);
}
DateTime thirdFridayOfMonth = DateOfWeekOfMonth(DateTime.Now, DayOfWeek.Friday, 3);
void Main()
{
DayOfWeek dow = DayOfWeek.Friday;
int y = 2014;
int m = 2;
String.Format("First {0}: {1}", new object[] { dow, DateHelper.FirstDayOfWeekInMonth(y, m, dow) }).Dump();
"".Dump();
String.Format("Last {0}: {1}", new object[] { dow, DateHelper.LastDayOfWeekInMonth(y, m, dow) }).Dump();
"".Dump();
for(int i = 1; i <= 6; i++)
String.Format("{0} #{1}: {2}", new object[] { dow, i, DateHelper.XthDayOfWeekInMonth(y, m, dow, i) }).Dump();
}
public class DateHelper
{
public static DateTime FirstDayOfWeekInMonth(int year, int month, DayOfWeek day)
{
DateTime res = new DateTime(year, month, 1);
int offset = -(res.DayOfWeek - day);
if (offset < 0)
offset += 7;
res = res.AddDays(offset);
return res;
}
public static DateTime LastDayOfWeekInMonth(int year, int month, DayOfWeek day)
{
DateTime dt = new DateTime(year, month, 1).AddMonths(1);
DateTime res = FirstDayOfWeekInMonth(dt.Year, dt.Month, day);
res = res.AddDays(-7);
return res;
}
public static DateTime XthDayOfWeekInMonth(int year, int month, DayOfWeek day, int x)
{
DateTime res = DateTime.MinValue;
if (x > 0)
{
res = FirstDayOfWeekInMonth(year, month, day);
if (x > 1)
res = res.AddDays((x - 1) * 7);
res = res.Year == year && res.Month == month ? res : DateTime.MinValue;
}
return res;
}
}
First Friday: 07/02/2014 00:00:00
Last Friday: 28/02/2014 00:00:00
Friday #1: 07/02/2014 00:00:00
Friday #2: 14/02/2014 00:00:00
Friday #3: 21/02/2014 00:00:00
Friday #4: 28/02/2014 00:00:00
Friday #5: 01/01/0001 00:00:00
Friday #6: 01/01/0001 00:00:00
private DateTime thirdSunday(DateTime timeFrom)
{
List<DateTime> days = new List<DateTime>();
DateTime testDate = timeFrom;
while (testDate < timeFrom.AddMonths(1))
{
if (testDate.DayOfWeek == DayOfWeek.Friday)
{
days.Add(testDate);
}
testDate = testDate.AddDays(1);
}
return days[2];
}
public static DateTime GetDayOfMonth(DateTime dateValue, DayOfWeek dayOfWeek, int occurance)
{
List<DateTime> dayOfWeekRanges = new List<DateTime>();
//move to the first of th month
DateTime startOfMonth = new DateTime(dateValue.Year, dateValue.Month, 1);
//move startOfMonth to the dayOfWeek requested
while (startOfMonth.DayOfWeek != dayOfWeek)
startOfMonth = startOfMonth.AddDays(1);
do
{
dayOfWeekRanges.Add(startOfMonth);
startOfMonth = startOfMonth.AddDays(7);
} while (startOfMonth.Month == dateValue.Month);
bool fromLast = occurance < 0;
if (fromLast)
occurance = occurance * -1;
if (fromLast)
return dayOfWeekRanges[dayOfWeekRanges.Count - occurance];
else
return dayOfWeekRanges[occurance - 1];
}
public static DateTime ThirdFridayOfMonth(DateTime dateTime)
{
int day = dateTime.Day;
return dateTime.AddDays(21 - day - ((int)dateTime.DayOfWeek + 37 - day) % 7);
}
public static int? GetNthDayOfWeekInMonth(int year, int month, DayOfWeek dow, int weekNumOfMonth)
{
if (weekNumOfMonth < -5 || weekNumOfMonth == 0 || weekNumOfMonth > 5)
throw new ArgumentOutOfRangeException("weekNumOfMonth", $"must be between 1~5 or -1~-5. ({weekNumOfMonth})");
int daysOfMonth = DateTime.DaysInMonth(year, month);
if (weekNumOfMonth > 0)
{
var firstDay = new DateTime(year, month, 1);
var firstDayOfTargetDOW = (int)dow - (int)firstDay.DayOfWeek;
if (firstDayOfTargetDOW < 0)
firstDayOfTargetDOW += 7;
var resultedDay = (firstDayOfTargetDOW + 1) + (7 * (weekNumOfMonth - 1));
if (resultedDay > daysOfMonth)
return null;
return resultedDay;
}
else
{
var lastDay = new DateTime(year, month, daysOfMonth);
var firstDayOfTargetDOW = (int)lastDay.DayOfWeek - (int)dow;
if (firstDayOfTargetDOW < 0)
firstDayOfTargetDOW += 7;
var resultedDay = firstDayOfTargetDOW + (7 * (Math.Abs(weekNumOfMonth) - 1));
if (resultedDay > daysOfMonth)
return null;
return (daysOfMonth - resultedDay);
}
}
Assert.AreEqual(02, DateTimeHelper.GetNthDayOfWeekInMonth(2019, 11, DayOfWeek.Saturday, 1));
Assert.AreEqual(30, DateTimeHelper.GetNthDayOfWeekInMonth(2019, 11, DayOfWeek.Saturday, -1));
public static DateTime FindTheNthDay(
int year, int month, DayOfWeek day, int occurrence)
{
var startDate = new DateTime(year, month, 1);
while(startDate.DayOfWeek != day)
{
startDate = startDate.AddDays(1);
}
var nDays = 7 * (occurrence - 1);
var result = startDate.AddDays(nDays);
return result;
}
> FindTheNthDay(2006, 11, DayOfWeek.Friday, 4)
[11/24/2006 12:00:00 AM]
> FindTheNthDay(2005, 11, DayOfWeek.Friday, 4)
[11/25/2005 12:00:00 AM]
> FindTheNthDay(2004, 11, DayOfWeek.Friday, 4)
[11/26/2004 12:00:00 AM]
> FindTheNthDay(2003, 11, DayOfWeek.Friday, 4)
[11/28/2003 12:00:00 AM]
> FindTheNthDay(1983, 11, DayOfWeek.Friday, 4)
[11/25/1983 12:00:00 AM]
> FindTheNthDay(1978, 11, DayOfWeek.Friday, 4)
[11/24/1978 12:00:00 AM]
> FindTheNthDay(1972, 11, DayOfWeek.Friday, 4)
[11/24/1972 12:00:00 AM]
public static bool IsThirdWednesday(DateTime inputDate)
{
DateTime firstDayOfMonth = new DateTime(inputDate.Year, inputDate.Month, 1);
DateTime firstDayOfNextMonth = firstDayOfMonth.AddMonths(1);
int wednesdayCount = 0;
while(firstDayOfMonth < firstDayOfNextMonth)
{
if (firstDayOfMonth.DayOfWeek == DayOfWeek.Wednesday)
wednesdayCount++;
if (wednesdayCount == 3)
{
if (inputDate == firstDayOfMonth)
return true;
else
return false;
}
firstDayOfMonth = firstDayOfMonth.AddDays(1);
}
return false;
}