查找日历的第一天

发布于 2024-10-15 19:27:13 字数 1378 浏览 1 评论 0原文

我想做的是创建一个简单的日历,我想找到特定月份第一周的第一天。我的日历是星期一 ->星期日日历和以下代码可以工作,但正如您所看到的,它并不是那么好。任何人都对如何获取日历中的第一个日期有更好的想法。

var now = new DateTime(Year, Month, 1);
now = now.AddDays(1-(int)now.DayOfWeek);
now = now.Day > 15 ? now : now.AddDays(-7);

日历最终看起来像这样:

| <  |        Jan  2011       |  > |
------------------------------------
| Mo | Tu | We | Th | Fr | Sa | Su |
|[27]| 28 | 29 | 30 | 31 | 01 | 02 |
| 03 | 04 | 05 | 06 | 07 | 08 | 09 |
| .. | .. | .. | .. | .. | .. | .. |
| .. | .. | .. | .. | .. | .. | .. |
| 31 | 01 | 02 | 03 | 04 | 05 | 06 |

在这个“图像”中,它是我要查找的 [27] 日期。

解决方案(发现我更好/更干净地循环然后计算):

    public DateTime FirstDay()
    {
        var date = new DateTime(Date.Year, Date.Month, 1);
        while (true)
        {
            if (date.DayOfWeek == DayOfWeek.Monday)
                return date;
            date = date.AddDays(-1);
        }
        return date;
    }

    public DateTime LastDay()
    {
        var date = new DateTime(Date.Year, Date.Month, 
                                DateTime.DaysInMonth(Date.Year, Date.Month));
        while (true)
        {
            if (date.DayOfWeek == DayOfWeek.Sunday)
                return date;
            date = date.AddDays(1);
        }
        return date;
    }

/BR 安德烈亚斯

What i want to do is to create a simple calendar, and I want to find the first day of the first week of a specific month. My calendar is a Monday -> Sunday calendar and the following code works, but as you can see it's not that nice. Anyone have any better idea on how to get the first date in the calendar.

var now = new DateTime(Year, Month, 1);
now = now.AddDays(1-(int)now.DayOfWeek);
now = now.Day > 15 ? now : now.AddDays(-7);

The calendar will end up looking like this:

| <  |        Jan  2011       |  > |
------------------------------------
| Mo | Tu | We | Th | Fr | Sa | Su |
|[27]| 28 | 29 | 30 | 31 | 01 | 02 |
| 03 | 04 | 05 | 06 | 07 | 08 | 09 |
| .. | .. | .. | .. | .. | .. | .. |
| .. | .. | .. | .. | .. | .. | .. |
| 31 | 01 | 02 | 03 | 04 | 05 | 06 |

And in this "image" it's the [27] date that i'm trying to find.

Solution (Found i better/cleaner to loop then calculate):

    public DateTime FirstDay()
    {
        var date = new DateTime(Date.Year, Date.Month, 1);
        while (true)
        {
            if (date.DayOfWeek == DayOfWeek.Monday)
                return date;
            date = date.AddDays(-1);
        }
        return date;
    }

    public DateTime LastDay()
    {
        var date = new DateTime(Date.Year, Date.Month, 
                                DateTime.DaysInMonth(Date.Year, Date.Month));
        while (true)
        {
            if (date.DayOfWeek == DayOfWeek.Sunday)
                return date;
            date = date.AddDays(1);
        }
        return date;
    }

/BR
Andreas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

贩梦商人 2024-10-22 19:27:13

我就这么做。它非常容易理解:

var firstDayOfMonth = new DateTime(year, month, 1);
DateTime startOfCalendar = 
    FirstDayOfWeekOnOrBefore(
        firstDayOfMonth,
        DayOfWeek.Monday
    );

public static DateTime FirstDayOfWeekOnOrBefore(
    DateTime date,
    DayOfWeek dayOfWeek
) {
    while(date.DayOfWeek != dayOfWeek) {
        date = date.AddDays(-1);
    }
    return date;
}

此外,如果您想更改日历以从星期一以外的时间开始,现在很简单。使用模算术的解决方案不太可维护。

I would just do this. It is so easy to understand:

var firstDayOfMonth = new DateTime(year, month, 1);
DateTime startOfCalendar = 
    FirstDayOfWeekOnOrBefore(
        firstDayOfMonth,
        DayOfWeek.Monday
    );

public static DateTime FirstDayOfWeekOnOrBefore(
    DateTime date,
    DayOfWeek dayOfWeek
) {
    while(date.DayOfWeek != dayOfWeek) {
        date = date.AddDays(-1);
    }
    return date;
}

Additionally, if you want to change your calendar to start on something other than Monday, it's trivial now. A solution using modulo arithmetic would not be as maintainable.

萌梦深 2024-10-22 19:27:13

您可以使用模来计算填充天数,而无需条件语句:

DateTime firstOfMonth=new DateTime(year,month,1);
var weekDay=firstOfMonth.DayOfWeek;
int fillerDays=((int)weekDay+6)%7;
DateTime firstDayInCalendar=firstOfMonth.AddDays(-fillerDays);

You can use modulo to calculate the number of filler days without a conditional statement:

DateTime firstOfMonth=new DateTime(year,month,1);
var weekDay=firstOfMonth.DayOfWeek;
int fillerDays=((int)weekDay+6)%7;
DateTime firstDayInCalendar=firstOfMonth.AddDays(-fillerDays);
冷血 2024-10-22 19:27:13

你可以尝试这个假设你指的第一天是星期一

DateTime dt = new DateTime(2011, 2, 2);
Console.WriteLine(dt.AddDays((8 - (int)dt.DayOfWeek) % 7));

You can try this assuming first day ur referring to is Monday

DateTime dt = new DateTime(2011, 2, 2);
Console.WriteLine(dt.AddDays((8 - (int)dt.DayOfWeek) % 7));
毁虫ゝ 2024-10-22 19:27:13

我不喜欢 while 循环,因为与 LINQ 一起使用时它们的成本很高
希望其他人可以重用此代码:(如果您在美国,则只需删除两行中的 [ + 6) % 7)] )

    /// <summary>
    /// Expands the month.
    /// | <  |        Jan  2011       |  > |
    /// ------------------------------------
    /// | Mo | Tu | We | Th | Fr | Sa | Su |
    /// |[27]| 28 | 29 | 30 | 31 | 01 | 02 |
    /// | 03 | 04 | 05 | 06 | 07 | 08 | 09 |
    /// | .. | .. | .. | .. | .. | .. | .. |
    /// | .. | .. | .. | .. | .. | .. | .. |
    /// | 31 | 01 | 02 | 03 | 04 | 05 | 06 |
    /// </summary>
    /// <param name="start">Some day in the month of interest, the start date is updated to become the date of firstDayInCalendar</param>
    /// <returns>The number of days to show. This value is either (28, 35 or 42)</returns>
    public static int ExpandMonth(ref DateTime start)
    {
        DateTime first = new DateTime(start.Year, start.Month, 1);
        DateTime last = new DateTime(start.Year, start.Month, DateTime.DaysInMonth(start.Year, start.Month));
        start = first.AddDays(-((int)first.DayOfWeek + 6) % 7);
        last = last.AddDays(7 - ((int)last.DayOfWeek + 6) % 7);
        return last.Subtract(start).Days;
    }

//Thomas

I do not like while loops, because they are expensive when used with LINQ
Hope someone else can reuse this code: (if you are in the USA, then just remove [ + 6) % 7)] in two lines)

    /// <summary>
    /// Expands the month.
    /// | <  |        Jan  2011       |  > |
    /// ------------------------------------
    /// | Mo | Tu | We | Th | Fr | Sa | Su |
    /// |[27]| 28 | 29 | 30 | 31 | 01 | 02 |
    /// | 03 | 04 | 05 | 06 | 07 | 08 | 09 |
    /// | .. | .. | .. | .. | .. | .. | .. |
    /// | .. | .. | .. | .. | .. | .. | .. |
    /// | 31 | 01 | 02 | 03 | 04 | 05 | 06 |
    /// </summary>
    /// <param name="start">Some day in the month of interest, the start date is updated to become the date of firstDayInCalendar</param>
    /// <returns>The number of days to show. This value is either (28, 35 or 42)</returns>
    public static int ExpandMonth(ref DateTime start)
    {
        DateTime first = new DateTime(start.Year, start.Month, 1);
        DateTime last = new DateTime(start.Year, start.Month, DateTime.DaysInMonth(start.Year, start.Month));
        start = first.AddDays(-((int)first.DayOfWeek + 6) % 7);
        last = last.AddDays(7 - ((int)last.DayOfWeek + 6) % 7);
        return last.Subtract(start).Days;
    }

//Thomas

染火枫林 2024-10-22 19:27:13

我发现自己经常需要这样做,所以我创建了以下扩展方法。

public static DateTime FirstDateOfCalendarMonth(this DateTime dt, DayOfWeek firstDayOfWeek = DayOfWeek.Sunday)
{
  dt = new DateTime(dt.Year, dt.Month, 1);
  while (dt.DayOfWeek != firstDayOfWeek){
    dt = dt.AddDays(-1);
  }
  return dt;
}

像这样使用

var firstCalDate = DateTime.Now.FirstDateOfCalendarMonth();

它默认将星期日作为第一个 DayOfWeek,但您可以将其传递给您喜欢的任何 DayOfWeek,如下所示:

var firstCalDate = DateTime.Now.FirstDateOfCalendarMonth(DayOfWeek.Monday);

I found myself needing to do this quite often, so I created the following extension method.

public static DateTime FirstDateOfCalendarMonth(this DateTime dt, DayOfWeek firstDayOfWeek = DayOfWeek.Sunday)
{
  dt = new DateTime(dt.Year, dt.Month, 1);
  while (dt.DayOfWeek != firstDayOfWeek){
    dt = dt.AddDays(-1);
  }
  return dt;
}

Use it like this

var firstCalDate = DateTime.Now.FirstDateOfCalendarMonth();

It defaults to Sunday as the first DayOfWeek, but you can pass it whatever DayOfWeek you like, like this:

var firstCalDate = DateTime.Now.FirstDateOfCalendarMonth(DayOfWeek.Monday);
椵侞 2024-10-22 19:27:13
DateTime start_date = Cal_start_date.SelectedDate;
DateTime end_date = Cal_end_date.SelectedDate;

Dictionary<string, int> dic_week_day = new Dictionary<string, int>();
dic_week_day["Sunday"] = 1;
dic_week_day["Monday"] = 2;
dic_week_day["Tuesday"] = 3;
dic_week_day["Wednesday"] = 4;
dic_week_day["Thursday"] = 5;
dic_week_day["Friday"] = 6;
dic_week_day["Saturday"] = 7;

DateTime first_day = start_date.AddDays(1 - start_date.Day);
int selected_day = dic_week_day[Drp_day_of_week.SelectedValue.ToString()];

string str_html = "";
for (DateTime i = first_day; i <= end_date; i = i.AddMonths(1))
{
    int day_of_week = dic_week_day[i.DayOfWeek.ToString()];
    DateTime temp_date;
    if (day_of_week > selected_day)
    {
        temp_date = i.AddDays((7 - day_of_week) + selected_day);
    }
    else
    {
        temp_date = i.AddDays(selected_day - day_of_week);
    }

    DateTime last_day_of_month = (temp_date.AddMonths(1)).AddDays(-temp_date.Day);

    if (Drp_occurrence.SelectedValue.ToString() == "odd")
    {
        if (start_date <= temp_date && temp_date <= end_date && temp_date <= last_day_of_month)
        {
            str_html += "<br />" + temp_date.ToString();
        }

        DateTime res_date = temp_date.AddDays(14);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "  ,  " + res_date.ToString();
        }

        res_date = temp_date.AddDays(28);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "  ,  " + res_date.ToString();
        }
    }
    else if (Drp_occurrence.SelectedValue.ToString() == "even")
    {
        DateTime res_date = temp_date.AddDays(7);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "<br />" + res_date.ToString();
        }

        res_date = temp_date.AddDays(21);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "  ,  " + res_date.ToString();
        }
    }
    else
    {
        int occurrence = Int32.Parse(Drp_occurrence.SelectedValue.ToString());

        DateTime res_date = temp_date.AddDays((occurrence - 1) * 7);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "<br />" + res_date.ToString();
        }
    }
}

Div_result.InnerHtml = str_html;
DateTime start_date = Cal_start_date.SelectedDate;
DateTime end_date = Cal_end_date.SelectedDate;

Dictionary<string, int> dic_week_day = new Dictionary<string, int>();
dic_week_day["Sunday"] = 1;
dic_week_day["Monday"] = 2;
dic_week_day["Tuesday"] = 3;
dic_week_day["Wednesday"] = 4;
dic_week_day["Thursday"] = 5;
dic_week_day["Friday"] = 6;
dic_week_day["Saturday"] = 7;

DateTime first_day = start_date.AddDays(1 - start_date.Day);
int selected_day = dic_week_day[Drp_day_of_week.SelectedValue.ToString()];

string str_html = "";
for (DateTime i = first_day; i <= end_date; i = i.AddMonths(1))
{
    int day_of_week = dic_week_day[i.DayOfWeek.ToString()];
    DateTime temp_date;
    if (day_of_week > selected_day)
    {
        temp_date = i.AddDays((7 - day_of_week) + selected_day);
    }
    else
    {
        temp_date = i.AddDays(selected_day - day_of_week);
    }

    DateTime last_day_of_month = (temp_date.AddMonths(1)).AddDays(-temp_date.Day);

    if (Drp_occurrence.SelectedValue.ToString() == "odd")
    {
        if (start_date <= temp_date && temp_date <= end_date && temp_date <= last_day_of_month)
        {
            str_html += "<br />" + temp_date.ToString();
        }

        DateTime res_date = temp_date.AddDays(14);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "  ,  " + res_date.ToString();
        }

        res_date = temp_date.AddDays(28);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "  ,  " + res_date.ToString();
        }
    }
    else if (Drp_occurrence.SelectedValue.ToString() == "even")
    {
        DateTime res_date = temp_date.AddDays(7);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "<br />" + res_date.ToString();
        }

        res_date = temp_date.AddDays(21);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "  ,  " + res_date.ToString();
        }
    }
    else
    {
        int occurrence = Int32.Parse(Drp_occurrence.SelectedValue.ToString());

        DateTime res_date = temp_date.AddDays((occurrence - 1) * 7);

        if (start_date <= res_date && res_date <= end_date && res_date <= last_day_of_month)
        {
            str_html += "<br />" + res_date.ToString();
        }
    }
}

Div_result.InnerHtml = str_html;
眼眸里的那抹悲凉 2024-10-22 19:27:13

更新:以下代码有错误!使用模运算,为了补偿这种情况,.NET 从周日开始一周!请参阅此处的其他解决方案(没有具有额外功能的解决方案)。

如果您需要查找“27”(即显示月份的第一天),只需使用以下命令:

DateTime monthStart = new DateTime(year, month, 1); 
DateTime monthDisplayStart = monthStart.AddDays(-((int)monthStart.DayOfWeek - 1));

UPDATE: Following code has a bug! Use modulo arithmetic, to compensate the circumstance, .NET begins the week on sunday! See other solutions here (without the one with an extra function).

If you need to find the "27" (i.e. the first day for the display of a month) simply use this:

DateTime monthStart = new DateTime(year, month, 1); 
DateTime monthDisplayStart = monthStart.AddDays(-((int)monthStart.DayOfWeek - 1));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文