/* * Copyright 2011-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package kr.debop4j.timeperiod.tools; import kr.debop4j.core.Guard; import kr.debop4j.timeperiod.DayOfWeek; import kr.debop4j.timeperiod.ITimeCalendar; import kr.debop4j.timeperiod.TimeCalendar; import kr.debop4j.timeperiod.YearAndWeek; import kr.debop4j.timeperiod.timerange.WeekRange; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Locale; /** * 주(Week) 관련 Utility Class * * @author 배성혁 sunghyouk.bae@gmail.com * @since 13. 5. 13. 오후 2:34 */ public abstract class Weeks { private static final Logger log = LoggerFactory.getLogger(Weeks.class); private static final boolean isTraceEnabled = log.isTraceEnabled(); private static final boolean isDebugEnabled = log.isDebugEnabled(); private Weeks() {} /** * Gets first day of week. * * @return the first day of week */ public static DayOfWeek getFirstDayOfWeek() { return TimeSpec.FirstDayOfWeek; } /** * Gets first day of week. * * @param locale the locale * @return the first day of week */ public static DayOfWeek getFirstDayOfWeek(Locale locale) { return TimeSpec.FirstDayOfWeek; } /** * 지정한 일자의 주차를 구합니다. * * @param moment the moment * @return the year and week */ public static YearAndWeek getYearAndWeek(DateTime moment) { return getYearAndWeek(moment, 1); } /** * 지정한 일자의 주차를 구합니다. * * @param moment the moment * @param baseMonth the base month * @return the year and week */ public static YearAndWeek getYearAndWeek(DateTime moment, int baseMonth) { return new YearAndWeek(moment.getWeekyear(), moment.getWeekOfWeekyear()); } /** * Gets year and week. * * @param moment the moment * @param timeCalendar the time calendar * @return the year and week */ public static YearAndWeek getYearAndWeek(DateTime moment, ITimeCalendar timeCalendar) { return new YearAndWeek(moment); } /** * 해당년도의 마지막 주차를 산정합니다. * * @param year the year * @return the end year and week */ public static YearAndWeek getEndYearAndWeek(int year) { return getEndYearAndWeek(year, TimeCalendar.getDefault()); } /** * 해당년도의 마지막 주차를 산정합니다. * * @param year the year * @param timeCalendar the time calendar * @return the end year and week */ public static YearAndWeek getEndYearAndWeek(int year, ITimeCalendar timeCalendar) { return new YearAndWeek(Times.asDate(year, 12, 28)); } /** * Gets week range. * * @param yearAndWeek the year and week * @return the week range */ public static WeekRange getWeekRange(YearAndWeek yearAndWeek) { return getWeekRange(yearAndWeek, TimeCalendar.getDefault()); } /** * Gets week range. * * @param yearAndWeek the year and week * @param timeCalendar the time calendar * @return the week range */ public static WeekRange getWeekRange(YearAndWeek yearAndWeek, ITimeCalendar timeCalendar) { return new WeekRange(yearAndWeek.getYear(), yearAndWeek.getWeekOfYear(), timeCalendar); } /** * 해당년도의 시작 주의 기간 * * @param year the year * @return the start week range of year */ public static WeekRange getStartWeekRangeOfYear(int year) { return getStartWeekRangeOfYear(year, TimeCalendar.getDefault()); } /** * 해당년도의 시작 주의 기간 * * @param year the year * @param timeCalendar the time calendar * @return the start week range of year */ public static WeekRange getStartWeekRangeOfYear(int year, ITimeCalendar timeCalendar) { return getWeekRange(new YearAndWeek(year, 1), timeCalendar); } /** * 해당년도의 마지막 주의 기간 * * @param year the year * @return the end week range of year */ public static WeekRange getEndWeekRangeOfYear(int year) { return getEndWeekRangeOfYear(year, TimeCalendar.getDefault()); } /** * 해당년도의 마지막 주의 기간 * * @param year the year * @param timeCalendar the time calendar * @return the end week range of year */ public static WeekRange getEndWeekRangeOfYear(int year, ITimeCalendar timeCalendar) { YearAndWeek endyw = getEndYearAndWeek(year, timeCalendar); return getWeekRange(endyw, timeCalendar); } /** * Add week of years. * * @param year the year * @param weekOfYear the week of year * @param weeks the weeks * @return the year and week */ public static YearAndWeek addWeekOfYears(int year, int weekOfYear, int weeks) { return addWeekOfYears(year, weekOfYear, weeks, TimeCalendar.getDefault()); } /** * Add week of years. * * @param year the year * @param weekOfYear the week of year * @param weeks the weeks * @param timeCalendar the time calendar * @return the year and week */ public static YearAndWeek addWeekOfYears(int year, int weekOfYear, int weeks, ITimeCalendar timeCalendar) { return addWeekOfYears(new YearAndWeek(year, weekOfYear), weeks, timeCalendar); } /** * Add week of years. * * @param yearAndWeek the year and week * @param weeks the weeks * @return the year and week */ public static YearAndWeek addWeekOfYears(YearAndWeek yearAndWeek, int weeks) { return addWeekOfYears(yearAndWeek, weeks, TimeCalendar.getDefault()); } /** * Add week of years. * * @param yearAndWeek the year and week * @param weeks the weeks * @param timeCalendar the time calendar * @return the year and week */ public static YearAndWeek addWeekOfYears(YearAndWeek yearAndWeek, int weeks, ITimeCalendar timeCalendar) { Guard.shouldNotBeNull(yearAndWeek, "yearAndWeek"); if (isTraceEnabled) log.trace("주차 연산을 수행합니다. year=[{}], weekOfYear=[{}], weeks=[{}], timeCalendar=[{}]", yearAndWeek.getYear(), yearAndWeek.getWeekOfYear(), weeks, timeCalendar); YearAndWeek result = new YearAndWeek(yearAndWeek.getYear(), yearAndWeek.getWeekOfYear()); if (weeks == 0) return result; result = (weeks > 0) ? plusWeeks(yearAndWeek, weeks, timeCalendar) : minusWeeks(yearAndWeek, weeks, timeCalendar); if (isTraceEnabled) log.trace("주차 연산을 수행했습니다. year=[{}], weekOfYear=[{}], weeks=[{}], result=[{}]", yearAndWeek.getYear(), yearAndWeek.getWeekOfYear(), weeks, result); return result; } private static YearAndWeek plusWeeks(YearAndWeek yearAndWeek, int weeks, ITimeCalendar timeCalendar) { YearAndWeek result = new YearAndWeek(yearAndWeek); weeks += result.getWeekOfYear(); if (weeks < getEndYearAndWeek(result.getYear(), timeCalendar).getWeekOfYear()) { result.setWeekOfYear(weeks); return result; } while (weeks >= 0) { YearAndWeek endWeek = getEndYearAndWeek(result.getYear(), timeCalendar); if (weeks <= endWeek.getWeekOfYear()) { result.setWeekOfYear(Math.max(weeks, 1)); return result; } weeks -= endWeek.getWeekOfYear(); result.setYear(result.getYear() + 1); } result.setWeekOfYear(Math.max(weeks, 1)); return result; } private static YearAndWeek minusWeeks(YearAndWeek yearAndWeek, int weeks, ITimeCalendar timeCalendar) { YearAndWeek result = new YearAndWeek(yearAndWeek); weeks += result.getWeekOfYear(); if (weeks == 0) { result.setYear(result.getYear() - 1); result.setWeekOfYear(getEndYearAndWeek(result.getYear(), timeCalendar).getWeekOfYear()); return result; } if (weeks > 0) { result.setWeekOfYear(weeks); return result; } while (weeks <= 0) { result.setYear(result.getYear() - 1); YearAndWeek endWeek = getEndYearAndWeek(result.getYear(), timeCalendar); weeks += endWeek.getWeekOfYear(); if (weeks > 0) { result.setWeekOfYear(Math.max(weeks, 1)); return result; } } result.setWeekOfYear(Math.max(weeks, 1)); return result; } }