/// <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); }
/// <summary> /// 지정한 달력 기준으로 지정년도, 분기의 기간을 구합니다. /// </summary> /// <param name="calendar"></param> /// <param name="year"></param> /// <param name="quarter"></param> /// <returns></returns> public static TimeSpan Quarter(int year, QuarterKind quarter = QuarterKind.First, Calendar calendar = null) { calendar = calendar ?? CurrentCalendar; var quarterMonths = TimeTool.GetMonthsOfQuarter(quarter); var duration = TimeSpec.NoDuration; foreach (var quarterMonth in quarterMonths) { duration = duration.Add(Month(year, quarterMonth, calendar)); } return(duration); }
/// <summary> /// 지정한 달력 기준으로 지정된 년도의 반기(전반기/후반기)의 기간 /// </summary> public static TimeSpan Halfyear(int year, HalfyearKind halfyear = HalfyearKind.First, Calendar calendar = null) { calendar = calendar ?? CurrentCalendar; var halfyearMonths = TimeTool.GetMonthsOfHalfyear(halfyear); var duration = TimeSpec.NoDuration; foreach (var halfyearMonth in halfyearMonths) { duration = duration.Add(Month(year, halfyearMonth, calendar)); } return(duration); }
/// <summary> /// 기간을 설정합니다. /// </summary> /// <param name="newStart">설정할 시작 시각</param> /// <param name="newEnd">설정할 완료 시각</param> public virtual void Setup(DateTime?newStart, DateTime?newEnd) { if (IsDebugEnabled) { log.Debug("기간을 새로 설정합니다. newStart=[{0}], newEnd=[{1}]", newStart, newEnd); } AssertMutable(); TimeTool.AdjustPeriod(ref newStart, ref newEnd); _start = newStart.GetValueOrDefault(TimeSpec.MinPeriodTime); _end = newEnd.GetValueOrDefault(TimeSpec.MaxPeriodTime); }
public void WeekOfYearIso8601Test() { var moment = new DateTime(2007, 12, 31); CultureTestData.Default .RunEach(culture => { if (culture.DateTimeFormat.CalendarWeekRule != CalendarWeekRule.FirstFourDayWeek || culture.DateTimeFormat.FirstDayOfWeek != DayOfWeek.Monday) { return; } TimeTool.GetWeekOfYear(moment, culture, WeekOfYearRuleKind.Iso8601).Week.Should().Be(1); }); }
public void AddDayTest() { TimeTool.AddDays(DayOfWeek.Monday, 14).Should().Be(DayOfWeek.Monday); TimeTool.AddDays(DayOfWeek.Tuesday, 14).Should().Be(DayOfWeek.Tuesday); TimeTool.AddDays(DayOfWeek.Wednesday, 14).Should().Be(DayOfWeek.Wednesday); TimeTool.AddDays(DayOfWeek.Thursday, 14).Should().Be(DayOfWeek.Thursday); TimeTool.AddDays(DayOfWeek.Friday, 14).Should().Be(DayOfWeek.Friday); TimeTool.AddDays(DayOfWeek.Saturday, 14).Should().Be(DayOfWeek.Saturday); TimeTool.AddDays(DayOfWeek.Sunday, 14).Should().Be(DayOfWeek.Sunday); TimeTool.AddDays(DayOfWeek.Monday, -14).Should().Be(DayOfWeek.Monday); TimeTool.AddDays(DayOfWeek.Tuesday, -14).Should().Be(DayOfWeek.Tuesday); TimeTool.AddDays(DayOfWeek.Wednesday, -14).Should().Be(DayOfWeek.Wednesday); TimeTool.AddDays(DayOfWeek.Thursday, -14).Should().Be(DayOfWeek.Thursday); TimeTool.AddDays(DayOfWeek.Friday, -14).Should().Be(DayOfWeek.Friday); TimeTool.AddDays(DayOfWeek.Saturday, -14).Should().Be(DayOfWeek.Saturday); TimeTool.AddDays(DayOfWeek.Sunday, -14).Should().Be(DayOfWeek.Sunday); }
public void AddMonthTest() { for (int i = 1; i <= TimeSpec.MonthsPerYear; i++) { TimeTool.AddMonth(1, i).Month.Should().Be(i % TimeSpec.MonthsPerYear + 1); } for (var i = 1; i <= TimeSpec.MonthsPerYear; i++) { TimeTool.AddMonth(1, -i).Month.Should().Be((1 - i) <= 0 ? (TimeSpec.MonthsPerYear + 1 - i) : 1 - i); } const int ThreeYears = 3 * TimeSpec.MonthsPerYear; for (var i = 1; i < ThreeYears; i++) { var yearAndMonth = TimeTool.AddMonth(new YearAndMonth(2008, 1), i); yearAndMonth.Year.Should().Be(2008 + i / TimeSpec.MonthsPerYear); yearAndMonth.Month.Should().Be(i % TimeSpec.MonthsPerYear + 1); } }
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); } } }
public void AddQuarterTest() { TimeTool.AddQuarter(QuarterKind.First, 1).Quarter.Should().Be(QuarterKind.Second); TimeTool.AddQuarter(QuarterKind.Second, 1).Quarter.Should().Be(QuarterKind.Third); TimeTool.AddQuarter(QuarterKind.Third, 1).Quarter.Should().Be(QuarterKind.Fourth); TimeTool.AddQuarter(QuarterKind.Fourth, 1).Quarter.Should().Be(QuarterKind.First); TimeTool.AddQuarter(QuarterKind.First, -1).Quarter.Should().Be(QuarterKind.Fourth); TimeTool.AddQuarter(QuarterKind.Second, -1).Quarter.Should().Be(QuarterKind.First); TimeTool.AddQuarter(QuarterKind.Third, -1).Quarter.Should().Be(QuarterKind.Second); TimeTool.AddQuarter(QuarterKind.Fourth, -1).Quarter.Should().Be(QuarterKind.Third); TimeTool.AddQuarter(QuarterKind.First, 2).Quarter.Should().Be(QuarterKind.Third); TimeTool.AddQuarter(QuarterKind.Second, 2).Quarter.Should().Be(QuarterKind.Fourth); TimeTool.AddQuarter(QuarterKind.Third, 2).Quarter.Should().Be(QuarterKind.First); TimeTool.AddQuarter(QuarterKind.Fourth, 2).Quarter.Should().Be(QuarterKind.Second); TimeTool.AddQuarter(QuarterKind.First, -2).Quarter.Should().Be(QuarterKind.Third); TimeTool.AddQuarter(QuarterKind.Second, -2).Quarter.Should().Be(QuarterKind.Fourth); TimeTool.AddQuarter(QuarterKind.Third, -2).Quarter.Should().Be(QuarterKind.First); TimeTool.AddQuarter(QuarterKind.Fourth, -2).Quarter.Should().Be(QuarterKind.Second); TimeTool.AddQuarter(QuarterKind.First, 3).Quarter.Should().Be(QuarterKind.Fourth); TimeTool.AddQuarter(QuarterKind.Second, 3).Quarter.Should().Be(QuarterKind.First); TimeTool.AddQuarter(QuarterKind.Third, 3).Quarter.Should().Be(QuarterKind.Second); TimeTool.AddQuarter(QuarterKind.Fourth, 3).Quarter.Should().Be(QuarterKind.Third); TimeTool.AddQuarter(QuarterKind.First, -3).Quarter.Should().Be(QuarterKind.Second); TimeTool.AddQuarter(QuarterKind.Second, -3).Quarter.Should().Be(QuarterKind.Third); TimeTool.AddQuarter(QuarterKind.Third, -3).Quarter.Should().Be(QuarterKind.Fourth); TimeTool.AddQuarter(QuarterKind.Fourth, -3).Quarter.Should().Be(QuarterKind.First); TimeTool.AddQuarter(QuarterKind.First, 4).Quarter.Should().Be(QuarterKind.First); TimeTool.AddQuarter(QuarterKind.Second, 4).Quarter.Should().Be(QuarterKind.Second); TimeTool.AddQuarter(QuarterKind.Third, 4).Quarter.Should().Be(QuarterKind.Third); TimeTool.AddQuarter(QuarterKind.Fourth, 4).Quarter.Should().Be(QuarterKind.Fourth); TimeTool.AddQuarter(QuarterKind.First, -4).Quarter.Should().Be(QuarterKind.First); TimeTool.AddQuarter(QuarterKind.Second, -4).Quarter.Should().Be(QuarterKind.Second); TimeTool.AddQuarter(QuarterKind.Third, -4).Quarter.Should().Be(QuarterKind.Third); TimeTool.AddQuarter(QuarterKind.Fourth, -4).Quarter.Should().Be(QuarterKind.Fourth); TimeTool.AddQuarter(QuarterKind.First, 2008, 1).Year.Should().Be(2008); TimeTool.AddQuarter(QuarterKind.Second, 2008, 1).Year.Should().Be(2008); TimeTool.AddQuarter(QuarterKind.Third, 2008, 1).Year.Should().Be(2008); TimeTool.AddQuarter(QuarterKind.Fourth, 2008, 1).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.First, 2008, 2).Year.Should().Be(2008); TimeTool.AddQuarter(QuarterKind.Second, 2008, 2).Year.Should().Be(2008); TimeTool.AddQuarter(QuarterKind.Third, 2008, 2).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.Fourth, 2008, 2).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.First, 2008, 4).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.Second, 2008, 4).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.Third, 2008, 4).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.Fourth, 2008, 4).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.First, 2008, 5).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.Second, 2008, 5).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.Third, 2008, 5).Year.Should().Be(2009); TimeTool.AddQuarter(QuarterKind.Fourth, 2008, 5).Year.Should().Be(2010); }
/// <summary> /// 다른 TimePeriod와의 관계를 판단합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual PeriodRelation GetRelation(ITimePeriod other) { return(TimeTool.GetReleation(this, other)); }
/// <summary> /// 두 기간의 합집합 기간을 반환합니다. /// </summary> /// <param name="other">대상기간</param> /// <returns>합집합 기간</returns> public ITimePeriod GetUnion(ITimePeriod other) { return(TimeTool.GetUnionRange(this, other)); }
/// <summary> /// 지정한 기간이 현 기간과 겹치는 부분이 있는지 검사합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual bool IntersectsWith(ITimePeriod other) { return(TimeTool.IntersectsWith(this, other)); }
/// <summary> /// 지정한 기간이 현 기간과 겹치는 부분이 있는지 검사합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual bool OverlapsWith(ITimePeriod other) { return(TimeTool.OverlapsWith(this, other)); }
/// <summary> /// 다른 TimePeriod와의 관계를 나타냅니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual PeriodRelation GetRelation(ITimePeriod other) { other.ShouldNotBeNull("other"); return(TimeTool.GetReleation(this, other)); }
/// <summary> /// 지정한 기간이 현 기간 내에 속하는지 검사합니다. /// </summary> /// <param name="other">대상 기간</param> /// <returns></returns> public virtual bool HasInside(ITimePeriod other) { return(TimeTool.HasInside(this, other)); }
/// <summary> /// 두 기간의 합집합 기간을 반환합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual TimePeriodBase GetUnion(ITimePeriod other) { other.ShouldNotBeNull("other"); return(TimeTool.GetUnionRange(this, other)); }
public void NextHalfyearTest() { TimeTool.NextHalfyear(HalfyearKind.First).Halfyear.Should().Be(HalfyearKind.Second); TimeTool.NextHalfyear(HalfyearKind.Second).Halfyear.Should().Be(HalfyearKind.First); }
/// <summary> /// 두 기간의 합집합 기간을 반환합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public new TimeBlock GetUnion(ITimePeriod other) { other.ShouldNotBeNull("other"); return(TimeTool.GetUnionBlock(this, other)); }
/// <summary> /// 시간 간격을 문자열로 표현합니다. /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="startEdge"></param> /// <param name="endEdge"></param> /// <param name="duration"></param> /// <returns></returns> public string GetInterval(DateTime start, DateTime end, IntervalEdge startEdge, IntervalEdge endEdge, TimeSpan duration) { if (end < start) { throw new ArgumentOutOfRangeException("end"); } StringBuilder sb = new StringBuilder(); // interval start switch (startEdge) { case IntervalEdge.Closed: sb.Append("["); break; case IntervalEdge.Open: sb.Append(UseIsoIntervalNotation ? "]" : "("); break; } bool addDuration = true; bool startHasTimeOfDay = TimeTool.HasTimePart(start); // no duration - schow start date (optionally with the time part) if (duration == TimeSpec.MinPeriodDuration) { sb.Append(startHasTimeOfDay ? GetDateTime(start) : GetShortDate(start)); addDuration = false; } // within one day: show full start, end time and suration else if (TimeTool.IsSameDay(start, end)) { sb.Append(GetDateTime(start)); sb.Append(StartEndSeparator); sb.Append(GetLongTime(end)); sb.Append(GetShortDate(start)); } else { bool endHasTimeOfDay = TimeTool.HasTimePart(start); bool hasTimeOfDays = startHasTimeOfDay || endHasTimeOfDay; if (hasTimeOfDays) { sb.Append(GetDateTime(start)); sb.Append(StartEndSeparator); sb.Append(GetDateTime(start)); } else { sb.Append(GetShortDate(start)); sb.Append(StartEndSeparator); sb.Append(GetShortDate(end)); } } // interval end switch (endEdge) { case IntervalEdge.Closed: sb.Append("]"); break; case IntervalEdge.Open: sb.Append(UseIsoIntervalNotation ? "[" : ")"); break; } // duration if (addDuration) { sb.Append(DurationSeparator); sb.Append(GetDuration(duration)); } return(sb.ToString()); }
/// <summary> /// 지정한 기간이 현 기간과 겹치는 부분이 있는지 검사합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual bool IntersectsWith(ITimePeriod other) { other.ShouldNotBeNull("other"); return(TimeTool.IntersectsWith(this, other)); }
/// <summary> /// 두 기간의 합집합 기간을 반환합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public new ITimeInterval GetUnion(ITimePeriod other) { other.ShouldNotBeNull("other"); return((TimeInterval)TimeTool.GetUnionRange(this, other)); }
/// <summary> /// 두 기간의 겹치는 기간을 반환합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public new ITimeRange GetIntersection(ITimePeriod other) { other.ShouldNotBeNull("other"); return(TimeTool.GetIntersectionRange(this, other)); }
public void GetCalendarHalfyearOfMonthTest() { TimeSpec.FirstHalfyearMonths.RunEach(m => TimeTool.GetHalfyearOfMonth(m).Should().Be(HalfyearKind.First)); TimeSpec.SecondHalfyearMonths.RunEach(m => TimeTool.GetHalfyearOfMonth(m).Should().Be(HalfyearKind.Second)); }
/// <summary> /// 지정한 기간이 현 기간 내에 속하는지 검사합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual bool HasInside(ITimePeriod other) { other.ShouldNotBeNull("other"); return(TimeTool.HasInside(this, other)); }
/// <summary> /// <paramref name="moment"/> 을 기간안에 포함하는 TimePeriod 들을 열거합니다. /// </summary> /// <param name="moment"></param> /// <returns></returns> public virtual IEnumerable <ITimePeriod> IntersectionPeriods(DateTime moment) { return(_periods.Where(p => TimeTool.HasInside(p, moment))); }
/// <summary> /// 지정한 기간이 현 기간과 겹치는 부분이 있는지 검사합니다. /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual bool OverlapsWith(ITimePeriod other) { other.ShouldNotBeNull("other"); return(TimeTool.OverlapsWith(this, other)); }
public void PreviousHalfyearTest() { TimeTool.PreviousHalfyear(HalfyearKind.First).Halfyear.Should().Be(HalfyearKind.Second); TimeTool.PreviousHalfyear(HalfyearKind.Second).Halfyear.Should().Be(HalfyearKind.First); }
/// <summary> /// 대상 TimePeriod 기간과 교차하는 TimePeriod 들을 열거합니다. /// </summary> /// <param name="target"></param> /// <returns></returns> public virtual IEnumerable <ITimePeriod> IntersectionPeriods(ITimePeriod target) { return(_periods.Where(p => TimeTool.IntersectsWith(target, p))); }
public void GetMonthsOfHalfyearTest() { Assert.AreEqual(TimeSpec.FirstHalfyearMonths, TimeTool.GetMonthsOfHalfyear(HalfyearKind.First)); Assert.AreEqual(TimeSpec.SecondHalfyearMonths, TimeTool.GetMonthsOfHalfyear(HalfyearKind.Second)); }
/// <summary> /// 지정된 시각이 기간에 속하는지 검사합니다. /// </summary> /// <param name="moment">검사할 일자</param> /// <returns></returns> public virtual bool HasInside(DateTime moment) { return(TimeTool.HasInside(this, moment)); }