C# - 在工作日开始的情况下,获得一个月内周列表的最佳方法是什么?

时间:2009-02-02 22:13:47

标签: c# datetime

我需要获得一个月的周列表,周一作为开始日。

例如,对于2009年2月,此方法将返回:

2/2/2009
2/9/2009
2/16/2009
2/23/2009

10 个答案:

答案 0 :(得分:25)

 // 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;

答案 1 :(得分:10)

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;
}

答案 2 :(得分:3)

以下是使用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);

答案 3 :(得分:1)

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);

答案 4 :(得分:1)

这个怎么样?

  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;
  }

答案 5 :(得分:0)

只需将响应行更改为您需要执行的操作

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/>");
  }
}

快速解决方案:我认为它没有内置功能....

答案 6 :(得分:0)

以下伪代码应该可以工作:

  • 确定月份的开始日期(使用日期中的月份和年份,并将日期设置为1
  • 确定月份的结束日期(开始日期+ 1个月)
  • 确定星期一的第一个日期(这是您列表中的第一个项目)
  • 添加7天以查找下一个日期并重复,直至您阅读或通过月末

答案 7 :(得分:0)

我看到你得到了答案,但我想与你分享我为我的一个项目创建的帮助班。这是一个综合性的课程,但可能有所帮助......

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

}

答案 8 :(得分:0)

这很好用!所有你需要做的就是获得你想要获得周数的月份的第一天,然后这将给你每周的第一天。您需要获得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));

答案 9 :(得分:0)

这就是我所做的,使用Chaowlert的代码作为起始基础。基本上我修改了你需要检查是否将溢出的天数添加到下个月,所以我不会添加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)));
}