C# - 给定起始工作日,获取一个月中的周列表的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/505175/
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
C# - What is the best way to get a list of the weeks in a month, given a starting weekday?
提问by Daniel Schaffer
I need to get a list of weeks for a given month, with Monday as the start day.
我需要获取给定月份的周列表,以星期一为开始日。
So for example, for the month of February 2009, this method would return:
例如,对于 2009 年 2 月,此方法将返回:
2/2/2009
2/9/2009
2/16/2009
2/23/2009
采纳答案by Tim
// Get the weeks in a month
DateTime date = DateTime.Today;
// first generate all dates in the month of 'date'
var dates = Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month)).Select(n => new DateTime(date.Year, date.Month, n));
// then filter the only the start of weeks
var weekends = from d in dates
where d.DayOfWeek == DayOfWeek.Monday
select d;
回答by Glennular
Just change the response line to what ever you need to do with it
只需将响应行更改为您需要对其执行的操作
protected void PrintDay(int year, int month, DayOfWeek dayName)
{
CultureInfo ci = new CultureInfo("en-US");
for (int i = 1 ; i <= ci.Calendar.GetDaysInMonth (year, month); i++)
{
if (new DateTime (year, month, i).DayOfWeek == dayName)
Response.Write (i.ToString() + "<br/>");
}
}
Quick solution: i don't think there is a built in function for it....
快速解决方案:我认为它没有内置功能......
回答by Robert Wagner
public static List<DateTime> GetWeeks(
this DateTime month, DayOfWeek startOfWeek)
{
var firstOfMonth = new DateTime(month.Year, month.Month, 1);
var daysToAdd = ((Int32)startOfWeek - (Int32)month.DayOfWeek) % 7;
var firstStartOfWeek = firstOfMonth.AddDays(daysToAdd);
var current = firstStartOfWeek;
var weeks = new List<DateTime>();
while (current.Month == month.Month)
{
weeks.Add(current);
current = current.AddDays(7);
}
return weeks;
}
回答by Rune Grimstad
Something like the following pseudo-code should work:
类似于以下伪代码的东西应该可以工作:
- Determine the start date of the month (use month and year from a date and set the day to 1
- Determine the end date of the month (start date + 1 month)
- Determine the first date that is a monday (this is your first item in the list)
- Add 7 days to find the next date and repeat until you read or pass the month end
- 确定月份的开始日期(使用日期中的月份和年份并将日期设置为 1
- 确定月份的结束日期(开始日期 + 1 个月)
- 确定第一个日期是星期一(这是您在列表中的第一个项目)
- 添加 7 天以查找下一个日期并重复直到您阅读或通过月末
回答by Chaowlert Chaisrichalermpol
int year = 2009;
int month = 2;
DateTime startDate = new DateTime(year, month, 1);
DateTime endDate = startDate.AddMonths(1);
while (startDate.DayOfWeek != DayOfWeek.Monday)
startDate = startDate.AddDays(1);
for (DateTime result = startDate; result < endDate; result = result.AddDays(7))
DoWhatYouWant(result);
回答by Matt Brunell
How about this?
这个怎么样?
public IEnumerable<DateTime> GetWeeks(DateTime date, DayOfWeek startDay)
{
var list = new List<DateTime>();
DateTime first = new DateTime(date.Year, date.Month, 1);
for (var i = first; i < first.AddMonths(1); i = i.AddDays(1))
{
if (i.DayOfWeek == startDay)
list.Add(i);
}
return list;
}
回答by Noldorin
Here's a solution (effectively one line) using C# 3.0/LINQ, in case you're interested:
这是使用 C# 3.0/LINQ 的解决方案(实际上是一行),以防您有兴趣:
var month = new DateTime(2009, 2, 1);
var weeks = Enumerable.Range(0, 4).Select(n => month.AddDays(n * 7 - (int)month.DayOfWeek + 1)).TakeWhile(monday => monday.Month == month.Month);
回答by Adi
I see you got your answer, but I wanted to share with you a helper class I created for one of my projects. It's far to be a comprehansive class, but might help...
我看到你得到了答案,但我想与你分享我为我的一个项目创建的帮助类。这是一个全面的课程,但可能会有所帮助......
public static class WeekHelper {
#region Public Methods
public static DateTime GetWeekStart(DateTime date) {
DateTime weekStart;
int monday = 1;
int crtDay = (int)date.DayOfWeek;
if (date.DayOfWeek == DayOfWeek.Sunday)
crtDay = 7;
int difference = crtDay - monday;
weekStart = date.AddDays(-difference);
return weekStart;
}
public static DateTime GetWeekStop(DateTime date) {
DateTime weekStart;
int sunday = 7;
int crtDay = (int)date.DayOfWeek;
if (date.DayOfWeek == DayOfWeek.Sunday)
crtDay = 7;
int difference = sunday - crtDay;
weekStart = date.AddDays(difference);
return weekStart;
}
public static void GetWeekInterval(int year, int weekNo,
out DateTime weekStart, out DateTime weekStop) {
GetFirstWeekOfYear(year, out weekStart, out weekStop);
if (weekNo == 1)
return;
weekNo--;
int daysToAdd = weekNo * 7;
DateTime dt = weekStart.AddDays(daysToAdd);
GetWeekInterval(dt, out weekStart, out weekStop);
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime toDate) {
//gets week series from beginning of the year
DateTime dtStartYear = new DateTime(toDate.Year, 1, 1);
List<KeyValuePair<DateTime, DateTime>> list = GetWeekSeries(dtStartYear, toDate);
if (list.Count > 0) {
KeyValuePair<DateTime, DateTime> week = list[0];
list[0] = new KeyValuePair<DateTime, DateTime>(dtStartYear, week.Value);
}
return list;
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime fromDate, DateTime toDate) {
if (fromDate > toDate)
return null;
List<KeyValuePair<DateTime, DateTime>> list = new List<KeyValuePair<DateTime, DateTime>>(100);
DateTime weekStart, weekStop;
toDate = GetWeekStop(toDate);
while (fromDate <= toDate) {
GetWeekInterval(fromDate, out weekStart, out weekStop);
list.Add(new KeyValuePair<DateTime, DateTime>(weekStart, weekStop));
fromDate = fromDate.AddDays(7);
}
return list;
}
public static void GetFirstWeekOfYear(int year, out DateTime weekStart, out DateTime weekStop) {
DateTime date = new DateTime(year, 1, 1);
GetWeekInterval(date, out weekStart, out weekStop);
}
public static void GetWeekInterval(DateTime date,
out DateTime dtWeekStart, out DateTime dtWeekStop) {
dtWeekStart = GetWeekStart(date);
dtWeekStop = GetWeekStop(date);
}
#endregion Public Methods
}
}
回答by Tim
This works beautifully! All you have to do is get the first day of the month you want to get the weeks for and then this will give you the first day of every week. You need to get 5 weeks (not 4) so the Enumerable.Range counts out 5 instead of 4.
这很好用!您所要做的就是获取您想要获取周数的月份的第一天,然后这将为您提供每周的第一天。您需要获得 5 周(而不是 4),因此 Enumerable.Range 计数为 5 而不是 4。
var date = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
var weeks = from n in Enumerable.Range(0, 5)
select date.AddDays(7 * n + (-1 * (int)date.DayOfWeek));
回答by fjleon
Here's what i did, using Chaowlert's code as a starting base. Basically i modified that you need to check if adding the days in the for overflows to the next month, so i don't add 4 days (monday to friday), but actually the minimum between 4 and the number of remaining days in the month. Also, i check if the current day is a weekend, otherwise add days until it's a weekday. My purpose is to print the weeks in a month, from monday to friday
这就是我所做的,使用 Chaowlert 的代码作为起始基础。基本上我修改了你需要检查是否将 for 溢出中的天数添加到下个月,所以我不添加 4 天(周一到周五),但实际上是 4 和该月剩余天数之间的最小值. 另外,我检查当天是否是周末,否则添加天数直到它是工作日。我的目的是打印一个月中的几周,从星期一到星期五
DateTime fechaInicio = new DateTime(a?o, mes, 1);
DateTime fechaFin = fechaInicio.AddMonths(1);
int diasHastaFinMes = 0;
while (esFinDeSemana(fechaInicio))
fechaInicio = fechaInicio.AddDays(1);
for (DateTime fecha = fechaInicio; fecha < fechaFin; fecha = fecha.AddDays(7))
{
diasHastaFinMes = DateTime.DaysInMonth(fecha.Year, fecha.Month) - fecha.Day;
printWeeks(fecha, fecha.AddDays(Math.Min(4, diasHastaFinMes)));
}