Example #1
0
        public DateTime ExpirationDate(int year, int month, string countryCode = "US")
        {
            var referenceDay = new DateTime(year, month, 1);
            var calendar     = MyUtils.GetCalendarFromCountryCode(countryCode);
            int day;

            referenceDay = referenceDay.AddMonths((int)Rule.ReferenceRelativeMonth);

            if (Rule.ReferenceDayIsLastBusinessDayOfMonth)
            {
                var tmpDay = referenceDay.AddMonths(1).AddDays(-1);

                while (!calendar.isBusinessDay(tmpDay))
                {
                    tmpDay = tmpDay.AddDays(-1);
                }

                day = tmpDay.Day;
            }
            else if (Rule.ReferenceUsesDays) // we use a fixed number of days from the start of the month
            {
                day = Rule.ReferenceDays;
            }
            else // we use a number of weeks and then a weekday of that week
            {
                if (Rule.ReferenceWeekDayCount == WeekDayCount.Last) //the last week of the month
                {
                    var tmpDay = referenceDay.AddMonths(1).AddDays(-1);

                    while (tmpDay.DayOfWeek.ToInt() != (int)Rule.ReferenceWeekDay)
                    {
                        tmpDay = tmpDay.AddDays(-1);
                    }

                    day = tmpDay.Day;
                }
                else // 1st to 4th week of the month, just loop until we find the right day
                {
                    var weekCount = 0;

                    while (weekCount < (int)Rule.ReferenceWeekDayCount + 1)
                    {
                        if (referenceDay.DayOfWeek.ToInt() == (int)Rule.ReferenceWeekDay)
                        {
                            weekCount++;
                        }

                        referenceDay = referenceDay.AddDays(1);
                    }

                    day = referenceDay.Day - 1;
                }
            }

            referenceDay = new DateTime(year, month, day).AddMonths((int)Rule.ReferenceRelativeMonth);

            if (Rule.ReferenceDayMustBeBusinessDay)
            {
                while (!calendar.isBusinessDay(referenceDay))
                {
                    referenceDay = referenceDay.AddDays(-1);
                }
            }

            switch (Rule.DayType)
            {
            case DayType.Business:
                var daysLeft = Rule.DaysBefore;
                var daysBack = 0;

                while (daysLeft > 0)
                {
                    daysBack++;

                    if (calendar.isBusinessDay(referenceDay.AddDays(-daysBack)))
                    {
                        daysLeft--;
                    }
                }

                return(referenceDay.AddDays(-daysBack));

            case DayType.Calendar:
                return(referenceDay.AddDays(-Rule.DaysBefore));

            default:
                return(referenceDay);
            }
        }