StartTimeOfWeek() public static method

dateTime이 속한 주(Week)의 첫째 날을 반환합니다.
public static StartTimeOfWeek ( this dateTime ) : System.DateTime
dateTime this
return System.DateTime
Exemplo n.º 1
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);
        }