示例#1
0
        public CalendarDateDiff(ITimeCalendar timeCalendar) {
            timeCalendar.ShouldNotBeNull("timeCalendar");
            Guard.Assert(timeCalendar.StartOffset == TimeSpan.Zero, "Calendar의 StartOffset은 TimeSpan.Zero이어야 합니다.");
            Guard.Assert(timeCalendar.EndOffset == TimeSpan.Zero, "Calendar의 StartOffset은 TimeSpan.Zero이어야 합니다.");

            _calendar = timeCalendar;
        }
示例#2
0
        /// <summary>
        /// 해당 년도의 주차산정방식에 따라 마지막 주차를 산정합니다.
        /// </summary>
        /// <param name="year">해당 년도</param>
        /// <param name="timeCalendar">TimeCalendar</param>
        /// <returns>해당 년도의 마지막 주차</returns>
        public static YearAndWeek GetEndYearAndWeek(this int year, ITimeCalendar timeCalendar)
        {
            timeCalendar.ShouldNotBeNull("timeCalendar");
            var yearStartMonth = timeCalendar.YearBaseMonth;

            if (IsDebugEnabled)
            {
                log.Debug("해당년도의 마지막 주차를 계산합니다... year=[{0}], yearStartMonth=[{1}], timeCalendar=[{2}]", year, yearStartMonth,
                          timeCalendar);
            }

            var yw        = GetYearAndWeek(TimeTool.EndTimeOfYear(year, yearStartMonth), timeCalendar);
            var endOfWeek = (yw.Year == year)
                                ? yw
                                : GetYearAndWeek(TimeTool.EndTimeOfYear(year, yearStartMonth).AddDays(-TimeSpec.DaysPerWeek));

            if (IsDebugEnabled)
            {
                log.Debug("해당년도의 마지막 주차를 얻었습니다. " +
                          "year=[{0}], yearStartMonth=[{1}], timeCalendar=[{2}], endOfWeek=[{3}]",
                          year, yearStartMonth, timeCalendar, endOfWeek);
            }

            return(endOfWeek);
        }
示例#3
0
        public CalendarDateAdd(ITimeCalendar timeCalendar)
        {
            timeCalendar.ShouldNotBeNull("timeCalendar");
            Guard.Assert(timeCalendar.StartOffset == TimeSpan.Zero, "Calendar의 StartOffset은 TimeSpan.Zero이어야 합니다.");
            Guard.Assert(timeCalendar.EndOffset == TimeSpan.Zero, "Calendar의 StartOffset은 TimeSpan.Zero이어야 합니다.");

            TimeCalendar = timeCalendar;
        }
示例#4
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);
        }
示例#5
0
        /// <summary>
        /// <paramref name="yearAndWeek"/>에 <paramref name="weeks"/>만큼의 주차를 더한 주차를 계산합니다.
        /// </summary>
        /// <param name="yearAndWeek">기준 주차</param>
        /// <param name="weeks">더할 주차 값</param>
        /// <param name="timeCalendar">TimeCalendar</param>
        /// <returns>기준 주차에 주차를 더한 주차 정보</returns>
        public static YearAndWeek AddWeekOfYears(this YearAndWeek yearAndWeek, int weeks, ITimeCalendar timeCalendar) {
            timeCalendar.ShouldNotBeNull("timeCalendar");


            if(IsDebugEnabled)
                log.Debug("주차 연산을 수행합니다... yearAndWeek=[{0}], weeks=[{1}], timeCalendar=[{2}]",
                          yearAndWeek, weeks, timeCalendar);


            var result = new YearAndWeek(yearAndWeek.Year, yearAndWeek.Week);

            if(weeks == 0)
                return result;

            if(weeks > 0) {
                weeks += result.Week.Value;
                if(weeks < GetEndYearAndWeek(yearAndWeek.Year.Value, timeCalendar).Week) {
                    result.Week = weeks;
                    return result;
                }
                while(weeks >= 0) {
                    var endWeek = GetEndYearAndWeek(result.Year.Value, timeCalendar);
                    if(weeks <= endWeek.Week) {
                        result.Week = Math.Max(weeks, 1);
                        return result;
                    }
                    weeks -= endWeek.Week.Value;
                    result.Year++;
                }
                result.Week = Math.Max(weeks, 1);
            }
            else {
                weeks += result.Week.Value;

                if(weeks == 0) {
                    result.Year--;
                    result.Week = GetEndYearAndWeek(result.Year.Value, timeCalendar).Week.Value;
                    return result;
                }
                if(weeks > 0) {
                    result.Week = weeks;
                    return result;
                }
                while(weeks <= 0) {
                    result.Year--;
                    var endWeek = GetEndYearAndWeek(result.Year.Value, timeCalendar);
                    weeks += endWeek.Week.Value;

                    if(weeks > 0) {
                        result.Week = Math.Max(weeks, 1);
                        return result;
                    }
                }
                result.Week = Math.Max(weeks, 1);
            }

            if(IsDebugEnabled)
                log.Debug("주차 연산을 수행했습니다!!! yearAndWeek=[{0}], weeks=[{1}], result=[{2}]", yearAndWeek, weeks, result);

            return result;
        }
示例#6
0
        /// <summary>
        /// 해당 년도의 주차산정방식에 따라 마지막 주차를 산정합니다. 
        /// </summary>
        /// <param name="year">해당 년도</param>
        /// <param name="timeCalendar">TimeCalendar</param>
        /// <returns>해당 년도의 마지막 주차</returns>
        public static YearAndWeek GetEndYearAndWeek(this int year, ITimeCalendar timeCalendar) {
            timeCalendar.ShouldNotBeNull("timeCalendar");
            var yearStartMonth = timeCalendar.YearBaseMonth;

            if(IsDebugEnabled)
                log.Debug("해당년도의 마지막 주차를 계산합니다... year=[{0}], yearStartMonth=[{1}], timeCalendar=[{2}]", year, yearStartMonth,
                          timeCalendar);

            var yw = GetYearAndWeek(TimeTool.EndTimeOfYear(year, yearStartMonth), timeCalendar);
            var endOfWeek = (yw.Year == year)
                                ? yw
                                : GetYearAndWeek(TimeTool.EndTimeOfYear(year, yearStartMonth).AddDays(-TimeSpec.DaysPerWeek));

            if(IsDebugEnabled)
                log.Debug("해당년도의 마지막 주차를 얻었습니다. " +
                          "year=[{0}], yearStartMonth=[{1}], timeCalendar=[{2}], endOfWeek=[{3}]",
                          year, yearStartMonth, timeCalendar, endOfWeek);

            return endOfWeek;
        }
示例#7
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;
        }
示例#8
0
        /// <summary>
        /// <paramref name="yearAndWeek"/>에 <paramref name="weeks"/>만큼의 주차를 더한 주차를 계산합니다.
        /// </summary>
        /// <param name="yearAndWeek">기준 주차</param>
        /// <param name="weeks">더할 주차 값</param>
        /// <param name="timeCalendar">TimeCalendar</param>
        /// <returns>기준 주차에 주차를 더한 주차 정보</returns>
        public static YearAndWeek AddWeekOfYears(this YearAndWeek yearAndWeek, int weeks, ITimeCalendar timeCalendar)
        {
            timeCalendar.ShouldNotBeNull("timeCalendar");


            if (IsDebugEnabled)
            {
                log.Debug("주차 연산을 수행합니다... yearAndWeek=[{0}], weeks=[{1}], timeCalendar=[{2}]",
                          yearAndWeek, weeks, timeCalendar);
            }


            var result = new YearAndWeek(yearAndWeek.Year, yearAndWeek.Week);

            if (weeks == 0)
            {
                return(result);
            }

            if (weeks > 0)
            {
                weeks += result.Week.Value;
                if (weeks < GetEndYearAndWeek(yearAndWeek.Year.Value, timeCalendar).Week)
                {
                    result.Week = weeks;
                    return(result);
                }
                while (weeks >= 0)
                {
                    var endWeek = GetEndYearAndWeek(result.Year.Value, timeCalendar);
                    if (weeks <= endWeek.Week)
                    {
                        result.Week = Math.Max(weeks, 1);
                        return(result);
                    }
                    weeks -= endWeek.Week.Value;
                    result.Year++;
                }
                result.Week = Math.Max(weeks, 1);
            }
            else
            {
                weeks += result.Week.Value;

                if (weeks == 0)
                {
                    result.Year--;
                    result.Week = GetEndYearAndWeek(result.Year.Value, timeCalendar).Week.Value;
                    return(result);
                }
                if (weeks > 0)
                {
                    result.Week = weeks;
                    return(result);
                }
                while (weeks <= 0)
                {
                    result.Year--;
                    var endWeek = GetEndYearAndWeek(result.Year.Value, timeCalendar);
                    weeks += endWeek.Week.Value;

                    if (weeks > 0)
                    {
                        result.Week = Math.Max(weeks, 1);
                        return(result);
                    }
                }
                result.Week = Math.Max(weeks, 1);
            }

            if (IsDebugEnabled)
            {
                log.Debug("주차 연산을 수행했습니다!!! yearAndWeek=[{0}], weeks=[{1}], result=[{2}]", yearAndWeek, weeks, result);
            }

            return(result);
        }