如何在c#中确定给定日期时间类型的第n天?

本文关键字:类型 时间 日期 | 更新日期: 2023-09-27 18:16:32

UPDATE 6/1/2013

我开发了一个扩展方法来解决这个特定的问题,我把代码贴在下面。我希望它能帮助到一些人。

<标题> 的背景

我的任务是为一个应用程序添加功能,允许设置定期会议(与Outlook完全相同)。

因此,例如,用户可能想要在每个月的第一个星期五,或每个月的最后一个星期一,或每个月的第二个工作日建立一个会议,以此类推。

是否存在一个标准的算法?我已经找到了很多部分的答案,但是没有一个,比如说,允许这样一个干净的扩展方法:

  /// <summary>
        /// Accepts a date object and finds the next date given an ordinality and type.
        /// </summary>
        /// <param name="ordinality">The ordinality (e.g. "first", "second", "last", etc.)</param>
        /// <param name="dayType">The day type (e.g. "weekday", "Monday", "day", etc)</param>
        /// <returns>A new date object</returns>
 public static DateTime GetNextDateOfType(this DateTime date, string ordinality, string dayType)
 {
 //do stuff
return newDate;
}

我一直在断断续续地研究这个,但我一直在想一定已经有什么东西了。

目前为止我有什么:

     public static DateTime GetNextDateOfType(this DateTime date, string ordinality, string dayType)
        {
            var dateTest = new DateTime(date.Year, date.Month, 1);
            var dateFound = false;
            var ordinal = 1;
            var targetOrdinal = ordinality.ToOrdinal();
            while (!dateFound)
            {
                //Test for type:
                switch (dayType)
                {
                    case "day":
                        if (dateTest >= date)
                        {
                            if (ordinality == "last" && dateTest == dateTest.GetLastDayOfMonth() || dateTest.Day == targetOrdinal)
                            {
                                dateFound = true;
                            }
                        }
                        break;
                    case "weekday":
                        if (dateTest >= date && dateTest.IsWeekDay())
                        {
                            if (targetOrdinal == ordinal)
                            {
                                dateFound = true;
                            }
                            ordinal++;
                        }
                        break;
                    case "weekend day":
                        if (dateTest >= date && !dateTest.IsWeekDay())
                        {
                            dateFound = true;
                        }
                        break;
                    default:
                        if (dateTest >= date && dateTest.DayOfWeek == HelperMethods.GetDayOfWeekFromString(dayType))
                        {
                            dateFound = true;
                        }
                        break;
                }
   
                dateTest = dateTest.AddDays(1);
            }
            return dateTest;
        }
   public static DateTime GetLastDayOfMonth(this DateTime date)
        {
            return new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
        }
        public static int ToOrdinal(this string ordinal)
        {
            var result = 0;
            switch (ordinal.ToLower())
            {
                case "first":
                    result = 1;
                    break;
                case "second":
                    result = 2;
                    break;
                case "third":
                    result = 3;
                    break;
                case "fourth":
                    result = 4;
                    break;
                case "fifth":
                    result = 5;
                    break;
                default:
                    result = -1;
                    break;
            }
            return result;
        }
        public static bool IsWeekDay(this DateTime date)
        {
            var weekdays = new List<DayOfWeek>
                {
                    DayOfWeek.Monday,
                    DayOfWeek.Tuesday,
                    DayOfWeek.Wednesday,
                    DayOfWeek.Thursday,
                    DayOfWeek.Friday
                };
            return weekdays.Contains(date.DayOfWeek);
        }
        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;
        }
        public static int GetWeekOfMonth(this DateTime date)
        {
            var beginningOfMonth = new DateTime(date.Year, date.Month, 1);
            while (date.Date.AddDays(1).DayOfWeek != CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
                date = date.AddDays(1);
            return (int)Math.Truncate((double)date.Subtract(beginningOfMonth).TotalDays / 7f) + 1;
        }

如何在c#中确定给定日期时间类型的第n天?

经过一段时间的挣扎,这是我想出的解决方案。它是一个扩展方法(在它下面有其他引用的扩展方法)。这不是我写的最优雅的代码,但它可以工作。如果我在我自己的环境中简化它,我将稍后更新代码。

获取第二个 *星期一*最接近传入日期的一个月的简单用法示例:

var newDate= someDate.GetNextDateOfType("second", "Monday");
<标题>代码:
    public static DateTime GetNextDateOfType(this DateTime date, string ordinality, string dayType)
            {
                var targetOrdinal = ordinality.ToOrdinal();
                var dateTest = (targetOrdinal > -1) ? new DateTime(date.Year, date.Month, 1) : date.GetLastDayOfMonth();
                var dateFound = false;
                var ordinal = 1;
                var ordinalReset = false;
                if (targetOrdinal > -1) //All cases EXCEPT "last"
                {
                    while (!dateFound)
                    {
                        if (dateTest.Month > date.Month && !ordinalReset)
                        {
                            ordinal = 1;
                            ordinalReset = true;
                        }
                        //Test for type:
                        switch (dayType)
                        {
                            case "day":
                                if (dateTest >= date)
                                {
                                    if (dateTest.Day == targetOrdinal)
                                    {
                                        dateFound = true;
                                    }
                                }
                                break;
                            case "weekday":
                                if (dateTest >= date && dateTest.IsWeekDay())
                                {
                                    if (targetOrdinal == ordinal)
                                    {
                                        dateFound = true;
                                    }
                                }
                                if (dateTest.IsWeekDay())
                                {
                                    ordinal++;
                                }
                                break;
                            case "weekend day":
                                if (dateTest >= date && !dateTest.IsWeekDay())
                                {
                                    if (targetOrdinal == ordinal)
                                    {
                                        dateFound = true;
                                    }
                                }
                                if (!dateTest.IsWeekDay())
                                {
                                    ordinal++;
                                }
                                break;
                            default:
                                if (dateTest >= date && dateTest.DayOfWeek == HelperMethods.GetDayOfWeekFromString(dayType))
                                {
                                    if (targetOrdinal == ordinal)
                                    {
                                        dateFound = true;
                                    }
                                }
                                if (dateTest.DayOfWeek == HelperMethods.GetDayOfWeekFromString(dayType))
                                {
                                    ordinal++;
                                }
                                break;
                        }
                        dateTest = (dateFound) ? dateTest : dateTest.AddDays(1);
                    }
                }
                else //for "last"
                {
                    while (!dateFound)
                    {
                        if (dateTest <= date && !ordinalReset)
                        {
                            dateTest = date.GetLastDayOfMonth().AddMonths(1);
                            ordinalReset = true;
                        }
                        //Test for type:
                        switch (dayType)
                        {
                            case "day":
                                dateFound = true;
                                break;
                            case "weekday":
                                if (dateTest.IsWeekDay())
                                {
                                        dateFound = true;
                                }
                                break;
                            case "weekend day":
                                if (!dateTest.IsWeekDay())
                                {
                                    dateFound = true;
                                }
                                break;
                            default:
                                if (dateTest.DayOfWeek == HelperMethods.GetDayOfWeekFromString(dayType))
                                {
                                    dateFound = true;
                                }
                                break;
                        }
                        dateTest = (dateFound) ? dateTest : dateTest.AddDays(-1);
                    }
                }
                return dateTest;
            }
            public static DateTime GetLastDayOfMonth(this DateTime date)
            {
                return new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
            }
            public static int ToOrdinal(this string ordinal)
            {
                var result = 0;
                switch (ordinal.ToLower())
                {
                    case "first":
                        result = 1;
                        break;
                    case "second":
                        result = 2;
                        break;
                    case "third":
                        result = 3;
                        break;
                    case "fourth":
                        result = 4;
                        break;
                    case "fifth":
                        result = 5;
                        break;
                    default:
                        result = -1;
                        break;
                }
                return result;
            }
            public static bool IsWeekDay(this DateTime date)
            {
                var weekdays = new List<DayOfWeek>
                    {
                        DayOfWeek.Monday,
                        DayOfWeek.Tuesday,
                        DayOfWeek.Wednesday,
                        DayOfWeek.Thursday,
                        DayOfWeek.Friday
                    };
                return weekdays.Contains(date.DayOfWeek);
            }
            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;
            }
            public static int GetWeekOfMonth(this DateTime date)
            {
                var beginningOfMonth = new DateTime(date.Year, date.Month, 1);
                while (date.Date.AddDays(1).DayOfWeek != CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
                    date = date.AddDays(1);
                return (int)Math.Truncate((double)date.Subtract(beginningOfMonth).TotalDays / 7f) + 1;
            }

 public static DayOfWeek GetDayOfWeekFromString(string day)
        {
            var dow = DayOfWeek.Sunday;
            switch (day)
            {
                case "Sunday":
                    dow = DayOfWeek.Sunday;
                    break;
                case "Monday":
                    dow = DayOfWeek.Monday;
                    break;
                case "Tuesday":
                    dow = DayOfWeek.Tuesday;
                    break;
                case "Wednesday":
                    dow = DayOfWeek.Wednesday;
                    break;
                case "Thursday":
                    dow = DayOfWeek.Thursday;
                    break;
                case "Friday":
                    dow = DayOfWeek.Friday;
                    break;
                case "Saturday":
                    dow = DayOfWeek.Saturday;
                    break;
            }
            return dow;
        }
相关文章: