대시보드와 주간보고 기능 업데이트
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
/**
|
||||
* ISO 8601 주차 계산 composable
|
||||
* - 1월 4일이 포함된 주 = 1주차
|
||||
* - 주의 시작 = 월요일
|
||||
* - 예: 2026년 2주차 = 2026-01-05(월) ~ 2026-01-11(일)
|
||||
*/
|
||||
|
||||
interface WeekInfo {
|
||||
export interface WeekInfo {
|
||||
year: number
|
||||
week: number
|
||||
startDate: Date
|
||||
@@ -13,28 +16,114 @@ interface WeekInfo {
|
||||
}
|
||||
|
||||
export function useWeekCalc() {
|
||||
|
||||
/**
|
||||
* 날짜를 YYYY-MM-DD 형식으로 포맷
|
||||
*/
|
||||
function formatDate(date: Date): string {
|
||||
const y = date.getFullYear()
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const d = String(date.getDate()).padStart(2, '0')
|
||||
return `${y}-${m}-${d}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 한국어 날짜 포맷 (M월 D일)
|
||||
*/
|
||||
function formatDateKr(date: Date): string {
|
||||
return `${date.getMonth() + 1}월 ${date.getDate()}일`
|
||||
}
|
||||
|
||||
/**
|
||||
* 해당 날짜의 월요일 반환
|
||||
*/
|
||||
function getMonday(date: Date): Date {
|
||||
const d = new Date(date)
|
||||
d.setHours(0, 0, 0, 0)
|
||||
const day = d.getDay()
|
||||
const diff = d.getDate() - day + (day === 0 ? -6 : 1)
|
||||
d.setDate(diff)
|
||||
return d
|
||||
}
|
||||
|
||||
/**
|
||||
* 해당 날짜의 일요일 반환
|
||||
*/
|
||||
function getSunday(date: Date): Date {
|
||||
const monday = getMonday(date)
|
||||
const sunday = new Date(monday)
|
||||
sunday.setDate(monday.getDate() + 6)
|
||||
return sunday
|
||||
}
|
||||
|
||||
/**
|
||||
* 해당 연도의 1주차 월요일 반환 (ISO 8601)
|
||||
* - 1월 4일이 포함된 주의 월요일
|
||||
*/
|
||||
function getWeek1Monday(year: number): Date {
|
||||
const jan4 = new Date(year, 0, 4)
|
||||
return getMonday(jan4)
|
||||
}
|
||||
|
||||
/**
|
||||
* 해당 연도의 총 주차 수 반환
|
||||
*/
|
||||
function getWeeksInYear(year: number): number {
|
||||
const dec31 = new Date(year, 11, 31)
|
||||
const weekInfo = getWeekNumber(dec31)
|
||||
// 12월 31일이 다음 해 1주차면 52주, 아니면 해당 주차
|
||||
return weekInfo.year === year ? weekInfo.week : 52
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 날짜의 ISO 주차 번호 반환
|
||||
*/
|
||||
function getWeekNumber(date: Date): { year: number; week: number } {
|
||||
const d = new Date(date)
|
||||
d.setHours(0, 0, 0, 0)
|
||||
|
||||
// 목요일 기준으로 연도 판단 (ISO 8601)
|
||||
const thursday = new Date(d)
|
||||
thursday.setDate(d.getDate() + 3 - ((d.getDay() + 6) % 7))
|
||||
|
||||
const year = thursday.getFullYear()
|
||||
const week1Monday = getWeek1Monday(year)
|
||||
|
||||
const diffTime = getMonday(d).getTime() - week1Monday.getTime()
|
||||
const diffDays = Math.round(diffTime / (24 * 60 * 60 * 1000))
|
||||
const week = Math.floor(diffDays / 7) + 1
|
||||
|
||||
return { year, week }
|
||||
}
|
||||
|
||||
/**
|
||||
* 특정 날짜의 ISO 주차 정보 반환
|
||||
*/
|
||||
function getWeekInfo(date: Date = new Date()): WeekInfo {
|
||||
const target = new Date(date)
|
||||
target.setHours(0, 0, 0, 0)
|
||||
const monday = getMonday(date)
|
||||
const sunday = getSunday(date)
|
||||
const { year, week } = getWeekNumber(date)
|
||||
|
||||
// 목요일 기준으로 연도 판단 (ISO 규칙)
|
||||
const thursday = new Date(target)
|
||||
thursday.setDate(target.getDate() - ((target.getDay() + 6) % 7) + 3)
|
||||
return {
|
||||
year,
|
||||
week,
|
||||
startDate: monday,
|
||||
endDate: sunday,
|
||||
startDateStr: formatDate(monday),
|
||||
endDateStr: formatDate(sunday),
|
||||
weekString: `${year}-W${week.toString().padStart(2, '0')}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 연도/주차로 날짜 범위 반환
|
||||
*/
|
||||
function getWeekDates(year: number, week: number): WeekInfo {
|
||||
const week1Monday = getWeek1Monday(year)
|
||||
|
||||
const year = thursday.getFullYear()
|
||||
const firstThursday = new Date(year, 0, 4)
|
||||
firstThursday.setDate(firstThursday.getDate() - ((firstThursday.getDay() + 6) % 7) + 3)
|
||||
const monday = new Date(week1Monday)
|
||||
monday.setDate(week1Monday.getDate() + (week - 1) * 7)
|
||||
|
||||
const week = Math.ceil((thursday.getTime() - firstThursday.getTime()) / (7 * 24 * 60 * 60 * 1000)) + 1
|
||||
|
||||
// 해당 주의 월요일
|
||||
const monday = new Date(target)
|
||||
monday.setDate(target.getDate() - ((target.getDay() + 6) % 7))
|
||||
|
||||
// 해당 주의 일요일
|
||||
const sunday = new Date(monday)
|
||||
sunday.setDate(monday.getDate() + 6)
|
||||
|
||||
@@ -49,6 +138,24 @@ export function useWeekCalc() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 주차 이동 (delta: +1 다음주, -1 이전주)
|
||||
*/
|
||||
function changeWeek(year: number, week: number, delta: number): { year: number; week: number } {
|
||||
let newYear = year
|
||||
let newWeek = week + delta
|
||||
|
||||
if (newWeek < 1) {
|
||||
newYear--
|
||||
newWeek = getWeeksInYear(newYear)
|
||||
} else if (newWeek > getWeeksInYear(newYear)) {
|
||||
newYear++
|
||||
newWeek = 1
|
||||
}
|
||||
|
||||
return { year: newYear, week: newWeek }
|
||||
}
|
||||
|
||||
/**
|
||||
* 이번 주 정보 (보고서 기준)
|
||||
* - 금~일: 현재 주차
|
||||
@@ -85,13 +192,6 @@ export function useWeekCalc() {
|
||||
return getWeekInfo(lastWeek)
|
||||
}
|
||||
|
||||
/**
|
||||
* 날짜 포맷 (YYYY-MM-DD)
|
||||
*/
|
||||
function formatDate(date: Date): string {
|
||||
return date.toISOString().split('T')[0]
|
||||
}
|
||||
|
||||
/**
|
||||
* 주차 문자열 파싱
|
||||
*/
|
||||
@@ -102,39 +202,43 @@ export function useWeekCalc() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 주차별 날짜 범위 텍스트
|
||||
* 주차별 날짜 범위 텍스트 (예: "1월 5일 ~ 1월 11일")
|
||||
*/
|
||||
function getWeekRangeText(year: number, week: number): string {
|
||||
// 해당 연도 첫 번째 목요일 찾기
|
||||
const jan4 = new Date(year, 0, 4)
|
||||
const firstThursday = new Date(jan4)
|
||||
firstThursday.setDate(jan4.getDate() - ((jan4.getDay() + 6) % 7) + 3)
|
||||
|
||||
// 해당 주차의 월요일
|
||||
const monday = new Date(firstThursday)
|
||||
monday.setDate(firstThursday.getDate() - 3 + (week - 1) * 7)
|
||||
|
||||
const sunday = new Date(monday)
|
||||
sunday.setDate(monday.getDate() + 6)
|
||||
|
||||
return `${formatDateKr(monday)} ~ ${formatDateKr(sunday)}`
|
||||
const { startDate, endDate } = getWeekDates(year, week)
|
||||
return `${formatDateKr(startDate)} ~ ${formatDateKr(endDate)}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 한국어 날짜 포맷 (M월 D일)
|
||||
* 주차별 날짜 범위 텍스트 - ISO 형식 (예: "2026-01-05 ~ 2026-01-11")
|
||||
*/
|
||||
function formatDateKr(date: Date): string {
|
||||
return `${date.getMonth() + 1}월 ${date.getDate()}일`
|
||||
function getWeekRangeTextISO(year: number, week: number): string {
|
||||
const { startDateStr, endDateStr } = getWeekDates(year, week)
|
||||
return `${startDateStr} ~ ${endDateStr}`
|
||||
}
|
||||
|
||||
return {
|
||||
// 기본 유틸
|
||||
formatDate,
|
||||
formatDateKr,
|
||||
getMonday,
|
||||
getSunday,
|
||||
|
||||
// 주차 계산
|
||||
getWeekNumber,
|
||||
getWeekInfo,
|
||||
getWeekDates,
|
||||
getWeeksInYear,
|
||||
changeWeek,
|
||||
|
||||
// 현재/지난주
|
||||
getCurrentWeekInfo,
|
||||
getActualCurrentWeekInfo,
|
||||
getLastWeekInfo,
|
||||
formatDate,
|
||||
|
||||
// 파싱/포맷
|
||||
parseWeekString,
|
||||
getWeekRangeText,
|
||||
formatDateKr
|
||||
getWeekRangeTextISO
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user