Exemple #1
0
        /// <summary>取得日期時間區段清單的交集</summary>
        public static IEnumerable <DateTimeSection> IntersectSection(this IEnumerable <DateTimeSection> source, IEnumerable <DateTimeSection> target)
        {
            source = source.Where(x => x != null && x.Start < x.End).OrderBy(x => x.End);
            target = target.Where(x => x != null && x.Start < x.End).OrderBy(x => x.End);

            using (IEnumerator <DateTimeSection> sIter = source.GetEnumerator(), tIter = target.GetEnumerator())
            {
                bool hasS = sIter.MoveNext();
                bool hasT = tIter.MoveNext();

                while (hasS && hasT)
                {
                    DateTimeSection overlap = Overlap(sIter.Current, tIter.Current);
                    if (overlap.End == sIter.Current.End)
                    {
                        hasS = sIter.MoveNext();
                    }
                    if (overlap.End == tIter.Current.End)
                    {
                        hasT = tIter.MoveNext();
                    }

                    if (overlap.Start < overlap.End)
                    {
                        yield return(overlap);
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>取得日期時間區段清單的聯集</summary>
        public static IEnumerable <DateTimeSection> UnionSection(this IEnumerable <DateTimeSection> source, IEnumerable <DateTimeSection> target)
        {
            source = source.Concat(target).Where(x => x != null).OrderBy(x => x.Start);

            using (IEnumerator <DateTimeSection> iter = source.GetEnumerator())
            {
                if (!iter.MoveNext())
                {
                    yield break;
                }
                var cursor = new DateTimeSection(iter.Current);

                while (iter.MoveNext())
                {
                    if (iter.Current.Start <= cursor.End)
                    {
                        cursor.End = OrionUtils.Max(iter.Current.End, cursor.End);
                        continue;
                    }

                    yield return(cursor);

                    cursor = new DateTimeSection(iter.Current);
                }

                yield return(cursor);
            }
        }
Exemple #3
0
        /// <summary>
        /// 修正时间至某一节,保留那一节
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public static DateTime RequireDateTime(DateTime dt, DateTimeSection state)
        {
            switch (state)
            {
            case DateTimeSection.Year:
                return(new DateTime(dt.Year, 1, 1, 0, 0, 0, dt.Kind));

            case DateTimeSection.Month:
                return(new DateTime(dt.Year, dt.Month, 1, 0, 0, 0, dt.Kind));

            case DateTimeSection.Week:
                dt = dt.AddDays(-(int)dt.DayOfWeek);
                return(new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0, dt.Kind));

            case DateTimeSection.Day:
                return(new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0, dt.Kind));

            case DateTimeSection.Hour:
                return(new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0, dt.Kind));

            case DateTimeSection.Minute:
                return(new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0, dt.Kind));

            case DateTimeSection.Second:
                return(new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Kind));

            default:
                return(dt);
            }
        }
Exemple #4
0
 /// <summary>取得重疊日期時間區段</summary>
 public static DateTimeSection Overlap(this DateTimeSection sectionA, DateTimeSection sectionB)
 {
     return(new DateTimeSection
     {
         Start = OrionUtils.Max(sectionA.Start, sectionB.Start),
         End = OrionUtils.Min(sectionA.End, sectionB.End),
     });
 }
Exemple #5
0
        /// <summary>
        /// 修正时间为一个时间段
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="state">0:年,1:月,2:日,3:时,4:分</param>
        public static void RequireDateTime(ref DateTime start, ref DateTime end, DateTimeSection state)
        {
            start = RequireDateTime(start, state);
            end   = RequireDateTime(end, state);

            switch (state)
            {
            case DateTimeSection.Year:
                end = end.AddYears(1);
                break;

            case DateTimeSection.Month:
                end = end.AddMonths(1);
                break;

            case DateTimeSection.Week:
                end = end.AddDays(7);
                break;

            case DateTimeSection.Day:
                end = end.AddDays(1);
                break;

            case DateTimeSection.Hour:
                end = end.AddHours(1);
                break;

            case   DateTimeSection.Minute:
                end = end.AddMinutes(1);
                break;

            case DateTimeSection.Second:
                end = end.AddSeconds(1);
                break;

            default:
                start = DateTime.Now.AddDays(-1);
                end   = DateTime.Now;
                break;
            }
            end = end.AddSeconds(-1);
        }
Exemple #6
0
        /// <summary>將日期時間區段清單反轉成空缺區段</summary>
        public static IEnumerable <DateTimeSection> ComplementSection(this IEnumerable <DateTimeSection> source)
        {
            source = source.Where(x => x != null).OrderBy(x => x.Start);
            var cursor = new DateTimeSection {
                Start = DateTime.MinValue
            };

            foreach (var item in source)
            {
                cursor.End = item.Start;

                yield return(cursor);

                cursor = new DateTimeSection {
                    Start = item.End
                };
            }

            cursor.End = DateTime.MaxValue;
            yield return(cursor);
        }
Exemple #7
0
        /// <summary>檢查日期時間區段是否重疊</summary>
        public static void CheckOverlap(this IEnumerable <DateTimeSection> source)
        {
            source = source.Where(x => x != null).OrderBy(x => x.Start);

            using (IEnumerator <DateTimeSection> iter = source.GetEnumerator())
            {
                if (!iter.MoveNext())
                {
                    return;
                }
                DateTimeSection prev = iter.Current;

                while (iter.MoveNext())
                {
                    if (prev.End <= iter.Current.Start)
                    {
                        continue;
                    }
                    throw new DataException($"Section overlap {prev} and {iter.Current}");
                }
            }
        }