如何获取给定月份的每个星期一?

2024-02-12

如何获取给定月份的每个“星期一”?

一个例子;
输入:2017 年 7 月 11 日 (11.07.2017)
输出:( 3,10,17,24,31 )
2017年7月3日 星期一
2017年7月10日 星期一
2017年7月17日 星期一
2017年7月24日 星期一
2017年7月31日

我可以获得给定月份的天数(2017 年 7 月为 31 天)。然后编写一个迭代(for 循环 a.e.),如果 dayOfWeek 等于星期一,则添加到列表中。但这不是好代码,因为 for 循环将运行 31 次。应该有更好的算法来归档目标。

我正在使用 C# .net 框架 4.6

UPDATE
感谢大家的帮助,到目前为止我已经得到了一些答案;我用简单而肮脏的基准代码测试了所有代码,以找到更快的算法。

这是我的基准代码;

using System;
using System.Collections.Generic;
using System.Linq;

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Columns;
using BenchmarkDotNet.Attributes.Jobs;
using BenchmarkDotNet.Engines;

using X.Core.Helpers;

namespace X.ConsoleBenchmark
{
    [SimpleJob(RunStrategy.ColdStart, targetCount: 5)]
    [MinColumn, MaxColumn, MeanColumn, MedianColumn]
    public class LoopTest
    {
        [Benchmark]
        public void CalculateNextSalaryDateWithLoopAllDays()
        {
            DateTime date = new DateTime(2017, 7, 3);
            const int oneMillion = 1000000;
            for (int i = 0; i < oneMillion; i++)
            {
                List<DateTime> allXDaysInMonth = date.GetAllXDaysInMonthWithLoopAllDays(DayOfWeek.Tuesday);
                if (allXDaysInMonth != null && allXDaysInMonth.FirstOrDefault().Day != 4)
                {
                    throw new ApplicationException("Calculate method has errors.");
                }
            }
        }

        [Benchmark]
        public void CalculateNextSalaryDate()
        {
            DateTime date = new DateTime(2017, 7, 3);
            const int oneMillion = 1000000;
            for (int i = 0; i < oneMillion; i++)
            {
                List<DateTime> allXDaysInMonth = date.GetAllXDaysInMonth(DayOfWeek.Tuesday);
                if (allXDaysInMonth != null && allXDaysInMonth.FirstOrDefault().Day != 4)
                {
                    throw new ApplicationException("Calculate method has errors.");
                }
            }
        }

        [Benchmark]
        public void Maccettura_GetAllDayOfWeekPerMonth()
        {
            DateTime exampleDate = new DateTime(2017, 7, 3);
            const int oneMillion = 1000000;
            for (int i = 0; i < oneMillion; i++)
            {
                var date = new DateTime(exampleDate.Year, exampleDate.Month, 1);

                if (date.DayOfWeek != DayOfWeek.Thursday)
                {
                    int daysUntilDayOfWeek = ((int)DayOfWeek.Thursday - (int)date.DayOfWeek + 7) % 7;
                    date = date.AddDays(daysUntilDayOfWeek);
                }

                List<DateTime> days = new List<DateTime>();

                while (date.Month == exampleDate.Month)
                {
                    days.Add(date);
                    date = date.AddDays(7);
                }

                if (days.FirstOrDefault().Day != 6)
                {
                    throw new ApplicationException("Calculate method has errors.");
                }
            }
        }

        [Benchmark]
        public void ScottHannen_GetWeekdaysForMonth()
        {
            DateTime exampleDate = new DateTime(2017, 7, 3);
            const int oneMillion = 1000000;
            for (int i = 0; i < oneMillion; i++)
            {
                IEnumerable<DateTime> days = ScottHannen_GetDaysInMonth(exampleDate).Where(day => day.DayOfWeek == DayOfWeek.Thursday);

                if (days.FirstOrDefault().Day != 6)
                {
                    throw new ApplicationException("Calculate method has errors.");
                }
            }
        }

        private IEnumerable<DateTime> ScottHannen_GetDaysInMonth(DateTime date)
        {
            var dateLoop = new DateTime(date.Year, date.Month, 1);

            while (dateLoop.Month == date.Month)
            {
                yield return dateLoop;
                dateLoop = dateLoop.AddDays(1);
            }
        }

        [Benchmark]
        public void Trioj_GetWeekdaysForMonth()
        {
            DateTime exampleDate = new DateTime(2017, 7, 3);
            const int oneMillion = 1000000;
            for (int i = 0; i < oneMillion; i++)
            {
                IEnumerable<DateTime> days = Trioj_GetDatesInMonthByWeekday(exampleDate, DayOfWeek.Thursday);

                if (days.FirstOrDefault().Day != 6)
                {
                    throw new ApplicationException("Calculate method has errors.");
                }
            }
        }

        private List<DateTime> Trioj_GetDatesInMonthByWeekday(DateTime date, DayOfWeek dayOfWeek)
        {
            // We know the first of the month falls on, well, the first.
            var first = new DateTime(date.Year, date.Month, 1);
            int daysInMonth = DateTime.DaysInMonth(date.Year, date.Month);

            // Find the first day of the week that matches the requested day of week.
            if (first.DayOfWeek != dayOfWeek)
            {
                first = first.AddDays(((((int)dayOfWeek - (int)first.DayOfWeek) + 7) % 7));
            }

            // A weekday in a 31 day month will only occur five times if it is one of the first three weekdays.
            // A weekday in a 30 day month will only occur five times if it is one of the first two weekdays.
            // A weekday in February will only occur five times if it is the first weekday and it is a leap year.
            // Incidentally, this means that if we subtract the day of the first occurrence of our weekday from the 
            // days in month, then if that results in an integer greater than 27, there will be 5 occurrences.
            int maxOccurrences = (daysInMonth - first.Day) > 27 ? 5 : 4;
            var list = new List<DateTime>(maxOccurrences);

            for (int i = 0; i < maxOccurrences; i++)
            {
                list.Add(new DateTime(first.Year, first.Month, (first.Day + (7 * i))));
            }

            return list;
        }

        [Benchmark]
        public void Jonathan_GetWeekdaysForMonth()
        {
            DateTime exampleDate = new DateTime(2017, 7, 3);
            const int oneMillion = 1000000;
            for (int i = 0; i < oneMillion; i++)
            {
                IEnumerable<DateTime> days = Jonathan_AllDatesInMonth(exampleDate.Year, exampleDate.Month).Where(x => x.DayOfWeek == DayOfWeek.Thursday);

                if (days.FirstOrDefault().Day != 6)
                {
                    throw new ApplicationException("Calculate method has errors.");
                }
            }
        }

        private static IEnumerable<DateTime> Jonathan_AllDatesInMonth(int year, int month)
        {
            int days = DateTime.DaysInMonth(year, month);
            for (int day = 1; day <= days; day++)
            {
                yield return new DateTime(year, month, day);
            }
        }

        [Benchmark]
        public void Swatsonpicken_GetWeekdaysForMonth()
        {
            DateTime exampleDate = new DateTime(2017, 7, 3);
            const int oneMillion = 1000000;
            for (int i = 0; i < oneMillion; i++)
            {
                IEnumerable<DateTime> days = Swatsonpicken_GetDaysOfWeek(exampleDate, DayOfWeek.Thursday);

                if (days.FirstOrDefault().Day != 6)
                {
                    throw new ApplicationException("Calculate method has errors.");
                }
            }
        }

        private static IEnumerable<DateTime> Swatsonpicken_GetDaysOfWeek(DateTime startDate, DayOfWeek desiredDayOfWeek)
        {
            var daysOfWeek = new List<DateTime>();
            var workingDate = new DateTime(startDate.Year, startDate.Month, 1);
            var offset = ((int)desiredDayOfWeek - (int)workingDate.DayOfWeek + 7) % 7;

            // Jump to the first desired day of week.
            workingDate = workingDate.AddDays(offset);

            do
            {
                daysOfWeek.Add(workingDate);

                // Jump forward seven days to get the next desired day of week.
                workingDate = workingDate.AddDays(7);
            } while (workingDate.Month == startDate.Month);

            return daysOfWeek;
        }

        [Benchmark]
        public void AliaksandrHmyrak_GetWeekdaysForMonth()
        {
            DateTime exampleDate = new DateTime(2017, 7, 3);
            const int oneMillion = 1000000;
            for (int i = 0; i < oneMillion; i++)
            {
                IEnumerable<DateTime> days = AliaksandrHmyrak_GetDaysOfWeek(exampleDate, DayOfWeek.Thursday);

                if (days.FirstOrDefault().Day != 6)
                {
                    throw new ApplicationException("Calculate method has errors.");
                }
            }
        }

        private static List<DateTime> AliaksandrHmyrak_GetDaysOfWeek(DateTime date, DayOfWeek dayOfWeek)
        {
            var daysInMonth = DateTime.DaysInMonth(date.Year, date.Month);
            var i = 1;

            List<DateTime> result = new List<DateTime>(5);

            do
            {
                var testDate = new DateTime(date.Year, date.Month, i);

                if (testDate.DayOfWeek == dayOfWeek)
                {
                    result.Add(testDate);
                    i += 7;
                }
                else
                {
                    i++;
                }

            } while (i <= daysInMonth);

            return result;
        }

    }
}

And this is the results table; Benchmarkdotnet Results

如果您愿意,我可以删除任何代码和图片名称
我标记了乔纳森的答案。简单、干净、更快(有趣)。


其他答案也有效,但我更喜欢使用 Jon Skeet 的 AllDaysInMonth 函数对于一个月中的每一天 https://stackoverflow.com/questions/9097027/foreach-day-in-month

public static IEnumerable<DateTime> AllDatesInMonth(int year, int month)
    {
        int days = DateTime.DaysInMonth(year, month);
        for (int day = 1; day <= days; day++)
        {
            yield return new DateTime(year, month, day);
        }
    }

然后你可以像这样使用 LINQ 进行调用:

var mondays = AllDatesInMonth(2017, 7).Where(i => i.DayOfWeek == DayOfWeek.Monday);

但我想这取决于你要使用它多少次来决定是否值得将其分解为一个单独的函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何获取给定月份的每个星期一? 的相关文章

随机推荐

  • 在 iPhone 上创建弹出窗口?

    我想在 iPhone 上创建一个自定义样式的弹出框 我希望它有一个向上的箭头 关于如何实现这一目标有什么想法吗 尝试这个FP 弹出窗口 https github com 50pixels FPPopover它会对你有所帮助
  • 如何使用rails控制台进行调试并放入应用程序

    我想在通过 Rails 控制台打开的 irb 中打印一些行 我见过很多关于如何实现它的问题 但我在 irb 中什么也没得到 下面是代码 def show puts in show method post Feed find by id pa
  • 如何同时使用 CGAffineTransformMakeScale 和 Rotation?

    UIImageView dsry objectAtIndex 0 transform CGAffineTransformMakeRotation 1 57 2 UIImageView dsry objectAtIndex 0 transfo
  • 最喜欢的内容未在 webview 上正确显示

    我正在开发一个语言词典应用程序 我将最喜欢的单词保存到首选项中 XML 文件中的收藏夹内容如下所示
  • 伪代码的标准? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我需要将一些 python 和 java 例程翻译成我的硕士论文的伪代码 但在想出语法 风格时遇到了困难 持续的 容易明白 不太详细 不太接近自
  • 嵌入随机命名的 MP3

    这是我的代码 我希望 mp3 的 src 考虑到存在许多随机命名的 mp3 文件 sound 目录 并在每次打开页面时随机选择一个 有什么线索给我吗 我的服务器启用了 PHP 但我想让它尽可能简单 这应该可以做到 files glob pa
  • Android 通知上的表情符号

    我正在尝试在通知栏上显示表情符号 这是我的字符串 ue057 getString R string notification sent hey 我已经尝试过使用 Softbank 以及每种可能的格式 U 1F601 xF0 x9F x98
  • 在 Windows 上的 VSCode 中调试 Python C/C++ 扩展

    问题总结 我正在为 Python 开发一个自 C 扩展 以提高特定代码段的性能 我想调试这个扩展 但到目前为止还没有成功 我关注了几个链接 例如这是纳迪亚的 https nadiah org 2020 03 01 example debug
  • sklearn 维度问题“发现数组具有暗淡 3。预计估计器 <= 2”

    我正在尝试使用 KNN 将 wav 文件正确分类为两组 组 0 和组 1 我提取了数据 创建了模型 拟合了模型 但是当我尝试使用 predict 方法时 出现以下错误 Traceback most recent call last File
  • MAMP 与 Laravel Unix Socket

    我正在我的 laravel 应用程序的本地开发服务器上使用 MAMP 我试图弄清楚如何安全地设置我的服务器 这样我就不必在数据库连接 mysql 数组中使用以下内容 因为那应该只当我在我的开发服务器上时使用 当我将行添加到 mysql 数组
  • git merge 在cherry-pick之后如何工作?

    让我们想象一下我们有一个master branch 然后我们创建一个newbranch git checkout b newbranch 并做出两个新的承诺newbranch commit1 and commit2 然后我们切换到maste
  • GCC 中 -O0 和 -O1 的区别

    在编译一些代码时 我注意到 O0 和 O1 之间创建的汇编器存在很大差异 我想运行启用 禁用优化 直到找出导致汇编器发生某种变化的原因 如果我使用 fverbose asm 准确找出 O1 与 O0 相比启用了哪些标志 然后手动禁用它们 为
  • 如何删除输入日期的 x 和向上/向下箭头元素?

    我唯一需要在框中显示的是橙色三角形 并且我不确定是否需要 CSS 或其他内容来删除三角形左侧的两个元素 有办法这样做吗 我只是使用输入类型date Fiddle http jsfiddle net 5M2PD 1 http jsfiddle
  • 队列性能明智哪个是更好的实现 - 数组或链表

    当我必须插入很少的元素时 哪种方式可以更快地入队和出队 数组比链表更好吗 我需要插入一些元素 并且必须从队列中删除并读取该删除的元素 如果它是数组 每次删除元素时我可能都必须修改索引 插入和删除也可能同时发生 从下面的案例来看 哪一个更好呢
  • 有什么理由避免 return 语句

    有时我会看到大段的 Scala 代码 其中包含多个嵌套级别的条件和匹配 使用显式 return 退出函数会更加清晰 避免那些显式的 return 语句有什么好处吗 A return may be通过抛出异常来实现 所以它may have与声
  • 我需要帮助设置 .NET HttpWebRequest 超时

    我的目标是在最短的时间内从多达 6000 个 URL 中获得答案 它运行得非常好 5200 个 LAN 地址需要 12 秒 直到开始出现一些延迟 我的代码最多同时使用 20 个 HttpWebRequest BeginGetResponse
  • 如何使用 R 找到最适合的圆/椭圆?

    我一直在阅读一些将圆适合数据的方法 例如this http www cs bsu edu homepages kerryj kjones circles pdf 我想看看这些方法如何在真实数据上发挥作用 并考虑使用 R 来实现这一点 我尝试
  • 为什么我的文本文件不断覆盖其中的数据?

    我试图从产品的 Facebook 页面中提取一些数据并将其全部转储到文本文件中 但我发现该文件不断用数据覆盖自身 我不确定这是分页问题还是我必须制作多个文件 这是我的代码 Modules import requests import fac
  • 不同图像方向和纵横比的 CollectionView 布局?

    我想知道我们如何使用 CollectionView 来显示不同尺寸 长宽比和方向的图像 有没有办法在这些图像中找到 匹配 看一下 DeviantArt iOS 应用程序的屏幕截图 您可能已经注意到 具有相同高度并且可以安装在屏幕中的图像位于
  • 如何获取给定月份的每个星期一?

    如何获取给定月份的每个 星期一 一个例子 输入 2017 年 7 月 11 日 11 07 2017 输出 3 10 17 24 31 2017年7月3日 星期一2017年7月10日 星期一2017年7月17日 星期一2017年7月24日