Beispiel #1
0
        public static string GetRecurStr(DateTime start, TimeUnitId unitId, int interval = 1, DaysOfWeek dowBits = DaysOfWeek.Any)
        {
            // Describe the recurrence pattern. scheduled recurrence rules.
            // Ignore that start may be in the future.
            // TODO ITranslatorProvider1

            if (DateUtil.IsExtremeDate(start))
            {
                return("Never");
            }

            if (unitId <= TimeUnitId.None || unitId > TimeUnitId.Years)    // does not repeat.
            {
                // "Once at " + date time
                return(start.ToDtTmString());
            }

            if (interval <= 0)
            {
                interval = 1;
            }

            var sb    = new StringBuilder();
            int uniti = (int)unitId;

            sb.Append(interval > 1 ? $"Every {interval} {_Units[uniti * 2]}" : _Units[(uniti * 2) + 1]);    // pluralize?

            switch (unitId)
            {
            case TimeUnitId.MilliSec:       // fractional seconds.
            case TimeUnitId.Seconds:
            case TimeUnitId.Minutes:
                return(sb.ToString());      // done. // Say no more.

            case TimeUnitId.Hours:
                if (start.Minute > 0)
                {
                    sb.Append($" at {start.Minute} minutes past"); // minutes into the hour.
                }
                return(sb.ToString());                             // done.

            case TimeUnitId.Days:                                  // daily. can use bitmask of days of the week.
                if (dowBits != 0 && dowBits != DaysOfWeek.Any)
                {
                    // Only on specific days of the week.
                    if (interval == 1)
                    {
                        sb.Clear();
                        sb.Append("Every ");
                    }
                    else
                    {
                        sb.Append(" if ");
                    }
                    int  dowBit = 1;
                    bool hasBit = false;
                    for (int i = 0; i < 7; i++, dowBit <<= 1)
                    {
                        if ((((int)dowBits) & dowBit) != 0)
                        {
                            if (hasBit)
                            {
                                sb.Append(",");
                            }
                            sb.Append(((System.DayOfWeek)i).ToString());
                            hasBit = true;
                        }
                    }
                }
                break;

            case TimeUnitId.Weeks:         // a single day of the week.
                if (interval == 1)
                {
                    sb.Clear();
                    sb.Append($"Every {start.DayOfWeek.ToString()}");
                    break;
                }
                sb.Append($"on {start.DayOfWeek.ToString()}");
                break;

            // Approximate unit times.
            case TimeUnitId.Months:            // On same day of month.
                if (interval == 1)
                {
                    sb.Clear();
                    sb.Append($"Every {Formatter.ToOrdinal(start.Day)} of the month");
                    break;
                }
                sb.Append($" on {Formatter.ToOrdinal(start.Day)} of the month");
                break;

            case TimeUnitId.Quarters:
                // Name the months ?? Jan, Apr, Jul, Oct
                sb.Append($" on {Formatter.ToOrdinal(start.Day)} of the month");
                break;

            case TimeUnitId.Years:
                sb.Append($" on {start.ToDtString("MMM", CultureInfo.InvariantCulture)} {start.Day:D2}");
                break;

            default:
                return("?");    // not valid for TimeUnitId
            }

            sb.Append($" at {start.Hour:D2}:{start.Minute:D2}");    // at hr:minutes into the day.
            return(sb.ToString());
        }
Beispiel #2
0
        public static DateTime GetNextRecur(DateTime now, DateTime start, TimeUnitId unitId, int interval = 1, DaysOfWeek dowBits = DaysOfWeek.Any)
        {
            // Get the next date / time in the sequence after now.
            // start = anchor date. Was the last official time. for calculation of relative times, time of day, etc. kExtremeMax = never before
            // interval = quantity of TimeUnitId
            // dowBits = only on these days of the week.
            // RETURN: kExtremeMax = never again.
            // ASSUME times are GMT and have no DST weirdness.

            if (DateUtil.IsExtremeDate(start))
            {
                return(DateUtil.kExtremeMax); // never start
            }
            if (now < start)                  // not until start date.
            {
                return(start);
            }

            if (unitId <= TimeUnitId.None || unitId > TimeUnitId.Years)    // does not repeat.
            {
                return((now <= start) ? start : DateUtil.kExtremeMax);
            }

            if (interval <= 0)
            {
                interval = 1;
            }

            DateTime dtNext;

            int timeUnits = _TimeUnits[(int)unitId];

            if (unitId <= TimeUnitId.Weeks)
            {
                // Discreet/Exact time units.
                long tickDiff = now.Ticks - start.Ticks;

                long intervalUnits = (timeUnits * TimeSpan.TicksPerMillisecond) * interval;
                long intervalsDiff = tickDiff / intervalUnits;

                int intervalInc = ((tickDiff % intervalUnits) == 0) ? 0 : 1;    // increment?

                dtNext = new DateTime(start.Ticks + ((intervalsDiff + intervalInc) * intervalUnits));

                if (unitId == TimeUnitId.Days)
                {
                    // skips days if not on dowMask. if interval is multiple of 7 then this may never satisfy !!
                    for (int i = 0; true; i++)
                    {
                        if (IsDowSet(dowBits, dtNext.DayOfWeek))    // good.
                        {
                            break;
                        }
                        if (i > 7)
                        {
                            return(DateUtil.kExtremeMax);        // never
                        }
                        dtNext = dtNext.AddTicks(intervalUnits);
                    }
                }
            }
            else
            {
                // month based time. not exact/Discreet time units.
                int monthsStart = start.Year * 12 + start.Month;
                int monthsNow   = now.Year * 12 + now.Month;
                int monthsDiff  = monthsNow - monthsStart;

                int intervalUnits = timeUnits * interval;
                int intervalsDiff = monthsDiff / intervalUnits;

                int intervalInc = ((monthsDiff % intervalUnits) == 0 && start.Day == now.Day && start.TimeOfDay == now.TimeOfDay) ? 0 : 1;  // increment?

                dtNext = start.AddMonths((intervalsDiff + intervalInc) * intervalUnits);
            }

            return(dtNext);
        }