Наследование: TimePeriodBase, ITimeRange
Пример #1
0
        private static ProjectTaskTimeSheet CreateTimeSheet() {
            var timeRange = new TimeRange(DateTime.Today.AddDays(Rnd.Next(0, 356)), TimeSpan.FromDays(1));

            return new ProjectTaskTimeSheet(Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid())
                   {
                       StartTime = timeRange.Start,
                       EndTime = timeRange.End,
                       PlanCostValue = Rnd.Next(0, 100).AsDecimal(),
                       PlanProgressValue = Rnd.Next(0, 100),
                       PlanWeightValue = Rnd.Next(0, 100).AsDecimal(),
                       PlanWorkValue = Rnd.Next(0, 100).AsDecimal(),
                       ActualCostValue = Rnd.Next(0, 100).AsDecimal(),
                       ActualProgressValue = Rnd.Next(0, 100),
                       ActualWeightValue = Rnd.Next(0, 100).AsDecimal(),
                       ActualWorkValue = Rnd.Next(0, 100).AsDecimal(),
                       Creator = "debop",
                       LastUpdator = "debop",
                       CreateDate = DateTime.Today
                   };
        }
        public TimeRangePeriodRelationTestData(DateTime start, DateTime end, TimeSpan offset) {
            Guard.Assert<ArgumentOutOfRangeException>(offset >= TimeSpan.Zero, "offset은 0 이상의 기간을 가져야 합니다.");

            Reference = new TimeRange(start, end, true);

            var beforeEnd = start.Subtract(offset);
            var beforeStart = beforeEnd.Subtract(Reference.Duration);
            var insideStart = start.Add(offset);
            var insideEnd = end.Subtract(offset);
            var afterStart = end.Add(offset);
            var afterEnd = afterStart.Add(Reference.Duration);

            After = new TimeRange(beforeStart, beforeEnd, true);
            StartTouching = new TimeRange(beforeStart, start, true);
            StartInside = new TimeRange(beforeStart, insideStart, true);
            InsideStartTouching = new TimeRange(start, afterStart, true);
            EnclosingStartTouching = new TimeRange(start, insideEnd, true);
            Enclosing = new TimeRange(insideStart, insideEnd, true);
            EnclosingEndTouching = new TimeRange(insideStart, end, true);
            ExactMatch = new TimeRange(start, end, true);
            Inside = new TimeRange(beforeStart, afterEnd, true);
            InsideEndTouching = new TimeRange(beforeStart, end, true);
            EndInside = new TimeRange(insideEnd, afterEnd, true);
            EndTouching = new TimeRange(end, afterEnd, true);
            Before = new TimeRange(afterStart, afterEnd, true);

            _allPeriods.Add(Reference);
            _allPeriods.Add(After);
            _allPeriods.Add(StartTouching);
            _allPeriods.Add(StartInside);
            _allPeriods.Add(InsideStartTouching);
            _allPeriods.Add(EnclosingStartTouching);
            _allPeriods.Add(Enclosing);
            _allPeriods.Add(EnclosingEndTouching);
            _allPeriods.Add(ExactMatch);
            _allPeriods.Add(Inside);
            _allPeriods.Add(InsideEndTouching);
            _allPeriods.Add(EndInside);
            _allPeriods.Add(EndTouching);
            _allPeriods.Add(Before);
        }
Пример #3
0
        protected virtual void CreateUserLoginHistory()
        {
            // 1년동안 매일 로그인 했다고 설정
            //
            var dateRange = new TimeRange(DateTime.Now, DurationUtil.Days(30));

            var activeProducts = NAccessContext.Domains.ProductRepository.FindAllActiveProduct();
            var activeCompanys = NAccessContext.Domains.OrganizationRepository.FindAllActiveCompany();

            dateRange
                .ForEachDays()
                .AsParallel()
                .AsOrdered()
                .RunEach(loginTime =>
                         {
                             foreach(var product in activeProducts)
                                 foreach(var company in activeCompanys)
                                     foreach(var user in NAccessContext.Domains.OrganizationRepository.FindAllUserByCompany(company))
                                         NAccessContext.Domains.LoggingRepository
                                             .InsertUserLoginLog(product, user, null, loginTime.Start);
                         });
        }
Пример #4
0
        public void WeekOfYearCalendarTest() {
            var period = new TimeRange(new DateTime(2007, 12, 31), new DateTime(2009, 12, 31));

            var moments =
                TimeTool.ForEachDays(period)
#if !SILVERLIGHT
                    .AsParallel()
                    .AsOrdered()
#endif
                    .Select(p => p.Start);

            foreach(var culture in CultureTestData.Default) {
                var rule = WeekTool.GetWeekOfYearRuleKind(culture.DateTimeFormat.CalendarWeekRule, culture.DateTimeFormat.FirstDayOfWeek);

                if(rule == WeekOfYearRuleKind.Iso8601)
                    continue;

                foreach(var moment in moments) {
                    var calendarWeekOfYear = culture.Calendar.GetWeekOfYear(moment,
                                                                            culture.DateTimeFormat.CalendarWeekRule,
                                                                            culture.DateTimeFormat.FirstDayOfWeek);

                    var yearAndWeek = TimeTool.GetWeekOfYear(moment, culture, WeekOfYearRuleKind.Calendar);

                    Assert.AreEqual(calendarWeekOfYear, yearAndWeek.Week,
                                    "calendar WeekOfYear=[{0}], yearAndWeek=[{1}], culture=[{2}], momnent=[{3}], weekRule=[{4}], FirstDayOfWeek=[{5}]",
                                    calendarWeekOfYear, yearAndWeek, culture, moment, culture.DateTimeFormat.CalendarWeekRule,
                                    culture.DateTimeFormat.FirstDayOfWeek);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// <paramref name="yearAndWeek"/> 주차에 해당하는 기간을 <see cref="WeekRange"/> 로 반환합니다. (예: 2011년 28주차의 실제 기간)
        /// </summary>
        /// <param name="yearAndWeek">년도와 주차 정보</param>
        /// <param name="timeCalendar">TimeCalendar 옵션</param>
        /// <returns>주차에 해당하는 한주의 기간</returns>
        public static WeekRange GetWeekRange(this YearAndWeek yearAndWeek, ITimeCalendar timeCalendar) {
            //var timeCalendar = new TimeCalendar(new TimeCalendarConfig
            //                                    {
            //                                        Culture = culture,
            //                                        WeekOfYearRule = GetWeekOfYearRuleKind(weekRule, firstDayOfWeek),
            //                                        EndOffset = TimeSpan.Zero
            //                                    });


            yearAndWeek.Year = yearAndWeek.Year ?? 0;
            var endYearAndWeek = GetEndYearAndWeek(yearAndWeek.Year.Value, timeCalendar);
            yearAndWeek.Week = Math.Max(1, Math.Min(yearAndWeek.Week.Value, endYearAndWeek.Week.Value));

            // 년/주에 가장 가까운 월을 선택해서 2개월만 검사한다.
            // 1년 범위는 너무 느리다.
            // var searchDays = RwDate.GetStartOfYear(yearWeek.Year).GetYearRange();
            // 년/주에 가장 가까운 월을 선택해서 2개월만 검사한다.
            var nearMonth =
                yearAndWeek.Year.Value
                    .GetStartOfMonth(Math.Max(1, Math.Min(TimeSpec.MonthsPerYear, (yearAndWeek.Week.Value - 1) / 4 + 1)))
                    .GetMonthRange();

            var searchDays = new TimeRange(nearMonth.GetPreviousMonth().Start, nearMonth.GetNextMonth().End);

            var weekPeriod = new TimeRange();

            // 년도 경계 때문에 전년도 마지막 7일, 후년 첫 7일을 검색에 포함시킨다.
            //if (yearWeek.Week == 1)
            //    searchDays.Start = searchDays.Start.Value.AddDays(-7);
            //else if (yearWeek.Week > 50)
            //    searchDays.End = searchDays.End.Value.AddDays(7);

            // 지정 년도의 주차에 해당하는 날짜를 계산한다.
            var dayCount = 0;
            foreach(TimeRange dayRange in searchDays.ForEachDays()) {
                var startDay = dayRange.Start;
                var dayYearWeek = GetYearAndWeek(startDay, timeCalendar);

                if(dayYearWeek.Equals(yearAndWeek)) {
                    if(weekPeriod.HasStart == false) {
                        weekPeriod.Start = startDay;

                        if(timeCalendar.WeekOfYearRule == WeekOfYearRuleKind.Iso8601) {
                            weekPeriod.End = startDay.AddDays(TimeSpec.DaysPerWeek);
                            break;
                        }
                    }
                    else
                        weekPeriod.End = startDay;

                    dayCount++;
                }
                else if(dayCount > 0) {
                    // 연속된 날짜 이후가 같은 주차가 아니라면 더 찾을 필요가 없다.
                    break;
                }
            }
            if(weekPeriod.HasStart && weekPeriod.HasEnd == false) {
                // 다음해 새해 첫날이 첫주라면, 12월31로 끝나야 하고, 아니면 마지막 주의 끝은 다음해의 토요일까지이다.
                weekPeriod.End = (timeCalendar.CalendarWeekRule == CalendarWeekRule.FirstDay)
                                     ? weekPeriod.Start
                                     : weekPeriod.Start.AddDays(TimeSpec.DaysPerWeek);
            }

            Guard.Assert(weekPeriod.HasPeriod, "해당 주차의 범위를 찾지 못했습니다. YearAndWeek=[{0}]", yearAndWeek);

            return new WeekRange(weekPeriod, timeCalendar);
        }
Пример #6
0
        /// <summary>
        /// 해당일자의 주차를 구한다. 문화권(Culture) 및 새해 첫주차에 대한 정의에 따라 주차가 달라진다.
        /// ref : http://www.simpleisbest.net/archive/2005/10/27/279.aspx
        /// ref : http://en.wikipedia.org/wiki/ISO_8601#Week_dates
        /// </summary>
        /// <remarks>
        /// <see cref="CalendarWeekRule"/> 값에 따라 WeekOfYear 가 결정된다.
        /// 
        /// FirstDay : 1월1일이 포함된 주를 무조건 첫째 주로 삼는다. (우리나라, 미국 등의 기준) : .NET의 설정대로 하면 이렇게 된다.
        /// FirstFourDayWeek : 1월1일이 포함된 주가 4일 이상인 경우에만 그 해의 첫 번째 주로 삼는다.	(ISO 8601)
        ///					   예) 한 주의 시작 요일이 일요일이고 1월1일이 일/월/화/수 중 하나이면 1월1일이 포함된 주는 해당 해의 첫 번째 주이다.
        ///					   예) 한 주의 시작 요일이 일요일이고 1월1일이 목/금/토 중 하나이면 1월1일이 포함된 주는 해당 해의 첫 번째 주로 간주하지 않는다.
        ///					   예) 2005년 1월 1일은 토요일이므로 1월1일이 포함된 주는 2005년의 첫 번째 주로 간주하지 않는다.
        /// FirstFullWeek : 1월의 첫 번째 주가 7일이 아니면 해당 해의 첫 번째 주로 삼지 않는다.
        ///				    예) 한 주의 시작 요일이 일요일인 경우, 1월1일이 일요일이 아니라면 1월1일이 포함된 주는 해당 해의 첫 번째 주로 간주하지 않는다.
        /// </remarks>
        /// <param name="moment">주차(WeekOfYear)를 산정하기 위한 일자</param>
        /// <param name="timeCalendar">주차 계산을 위한 규칙 정보를 가진 TimeCalendar 인스턴스</param>
        /// <returns>지정된 일자가 속한 Week Of Year를 반환</returns>
        public static YearAndWeek GetYearAndWeek(this DateTime moment, ITimeCalendar timeCalendar) {
            timeCalendar.ShouldNotBeNull("timeCalendar");

            var culture = timeCalendar.Culture.GetOrCurrentCulture();
            var weekRule = timeCalendar.CalendarWeekRule;
            var firstDayOfWeek = timeCalendar.FirstDayOfWeek;

            if(IsDebugEnabled)
                log.Debug("특정일[{0}] 의 주차를 계산합니다. culture=[{1}], weekRule=[{2}], firstDayOfWeek=[{3}]", moment, culture, weekRule,
                          firstDayOfWeek);

            var week = culture.Calendar.GetWeekOfYear(moment, weekRule, firstDayOfWeek);
            var year = moment.Year;

            //!+ NOTE: .NET 라이브러리가 1월1일 기준으로는 정상작동하지만, 12월 31로 계산하면, 무조건 FirstDay 형식으로 작업해버린다.
            //!+ FirstFourDayWeek Rule에 따르면 12월 31일이 다음해의 첫주차에 속할 경우도 있지만, .NET에서는 53주차로 반환해 버린다.
            //!+ 예 12월 31일이 월요일 경우 2001년 53주차가 아니라 2002년 1주차가 되어야 한다.
            //!+ 이를 해결하기 위해 부가적인 작업이 들어간다.
            //
            if(weekRule == CalendarWeekRule.FirstFourDayWeek && firstDayOfWeek == DayOfWeek.Monday) {
                var weekRange = new TimeRange(TimeTool.StartTimeOfWeek(moment, (DayOfWeek?)firstDayOfWeek), DurationUtil.Week);
                if(moment.Month == 12 && weekRange.HasInside(new DateTime(year + 1, 1, 1))) {
                    var startDate = moment.AddYears(1).StartTimeOfYear();
                    if((int)startDate.DayOfWeek > (int)firstDayOfWeek &&
                       (int)startDate.DayOfWeek - (int)firstDayOfWeek < 4) {
                        year++;
                        week = 1;
                    }
                }
            }
            // NOTE : 연도 보정 (1월인데, Week가 충분히 큰 숫자 이상이라면, 전년도의 주차를 따른다는 것이다. 그러므로 Year를 전년도로 설정해준다.
            if(moment.Month == 1 && week > 10)
                year--;

            var result = new YearAndWeek(year, week);

            if(IsDebugEnabled)
                log.Debug("일자[{0}] 의 주차는 [{4}]입니다. culture=[{1}], weekRule=[{2}], firstDayOfWeek=[{3}]", moment, culture, weekRule,
                          firstDayOfWeek, result);

            return result;
        }
Пример #7
0
        /// <summary>
        /// 두 기간의 합집합 기간을 반환한다.
        /// </summary>
        /// <param name="period"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static TimeRange GetUnionRange(this ITimePeriod period, ITimePeriod target) {
            target.ShouldNotBeNull("target");

            TimeRange unionPeriod = null;

            if(period.HasPeriod && target.HasPeriod) {
                unionPeriod = new TimeRange(period.StartAsNullable < target.StartAsNullable
                                                ? period.StartAsNullable
                                                : target.StartAsNullable,
                                            period.EndAsNullable > target.EndAsNullable
                                                ? period.EndAsNullable
                                                : target.EndAsNullable,
                                            period.IsReadOnly);
            }
            else {
                var start = (period.StartAsNullable.HasValue && target.StartAsNullable.HasValue)
                                ? Min(period.Start, target.Start)
                                : (period.StartAsNullable ?? target.StartAsNullable);
                var end = (period.EndAsNullable.HasValue && target.EndAsNullable.HasValue)
                              ? Max(period.End, target.End)
                              : (period.EndAsNullable ?? target.EndAsNullable);

                unionPeriod = new TimeRange(start, end, period.IsReadOnly);
            }

            if(IsDebugEnabled)
                log.Debug("period[{0}]와 target[{1}] 의 합집합 TimeRange [{2}]를 구했습니다!!!", period.AsString(), target.AsString(),
                          unionPeriod.AsString());

            return unionPeriod;
        }
Пример #8
0
        /// <summary>
        /// 두 기간의 공통되는 기간을 반환한다. (교집합)
        /// </summary>
        /// <param name="period"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static TimeRange GetIntersectionRange(this ITimePeriod period, ITimePeriod target) {
            target.ShouldNotBeNull("target");

            TimeRange intersectionPeriod = null;

            if(IntersectsWith(period, target)) {
                var start = Max(period.Start, target.Start);
                var end = Min(period.End, target.End);

                intersectionPeriod = new TimeRange(start, end, period.IsReadOnly);
            }

            if(IsDebugEnabled)
                log.Debug("period[{0}]와 target[{1}] 의 교집합 TimeRange [{2}]를 구했습니다!!!", period.AsString(), target.AsString(),
                          intersectionPeriod.AsString());

            return intersectionPeriod;
        }