122 lines
3.5 KiB
TypeScript
122 lines
3.5 KiB
TypeScript
|
|
import { format, parse, isValid, parseISO } from 'date-fns';
|
|
import { ko } from 'date-fns/locale';
|
|
|
|
/**
|
|
* 다양한 형식의 날짜 문자열을 Date 객체로 변환하는 유틸리티
|
|
*/
|
|
export const parseTransactionDate = (dateStr: string): Date | null => {
|
|
// 빈 문자열 체크
|
|
if (!dateStr || dateStr === '') {
|
|
console.log('빈 날짜 문자열');
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
// 특수 키워드 처리
|
|
if (dateStr.toLowerCase().includes('오늘')) {
|
|
console.log('오늘 날짜로 변환');
|
|
return new Date();
|
|
}
|
|
|
|
if (dateStr.toLowerCase().includes('어제')) {
|
|
console.log('어제 날짜로 변환');
|
|
const yesterday = new Date();
|
|
yesterday.setDate(yesterday.getDate() - 1);
|
|
return yesterday;
|
|
}
|
|
|
|
// ISO 형식 (yyyy-MM-dd) 시도
|
|
if (/^\d{4}-\d{2}-\d{2}/.test(dateStr)) {
|
|
console.log('ISO 형식 날짜 감지');
|
|
const date = parseISO(dateStr);
|
|
if (isValid(date)) {
|
|
return date;
|
|
}
|
|
}
|
|
|
|
// "M월 d일" 형식 (한국어) 시도
|
|
const koreanDatePattern = /(\d+)월\s*(\d+)일/;
|
|
const koreanMatch = dateStr.match(koreanDatePattern);
|
|
|
|
if (koreanMatch) {
|
|
console.log('한국어 날짜 형식 감지', koreanMatch);
|
|
const month = parseInt(koreanMatch[1]) - 1; // 0-based month
|
|
const day = parseInt(koreanMatch[2]);
|
|
const date = new Date();
|
|
date.setMonth(month);
|
|
date.setDate(day);
|
|
return date;
|
|
}
|
|
|
|
// 쉼표 구분 형식 처리 (예: "오늘, 14:52 PM")
|
|
const commaSplit = dateStr.split(',');
|
|
if (commaSplit.length > 1) {
|
|
console.log('쉼표 구분 날짜 감지');
|
|
// 첫 부분이 오늘/어제 등의 키워드인 경우 처리
|
|
const firstPart = commaSplit[0].trim().toLowerCase();
|
|
if (firstPart === '오늘') {
|
|
return new Date();
|
|
} else if (firstPart === '어제') {
|
|
const yesterday = new Date();
|
|
yesterday.setDate(yesterday.getDate() - 1);
|
|
return yesterday;
|
|
}
|
|
}
|
|
|
|
// parse를 사용한 다양한 형식 시도
|
|
const formats = [
|
|
'yyyy-MM-dd',
|
|
'yyyy/MM/dd',
|
|
'MM-dd-yyyy',
|
|
'MM/dd/yyyy',
|
|
'yyyy년 MM월 dd일',
|
|
'MM월 dd일',
|
|
'yyyy년 M월 d일',
|
|
'M월 d일'
|
|
];
|
|
|
|
for (const formatStr of formats) {
|
|
try {
|
|
console.log(`날짜 형식 시도: ${formatStr}`);
|
|
const date = parse(dateStr, formatStr, new Date(), { locale: ko });
|
|
if (isValid(date)) {
|
|
console.log('날짜 파싱 성공:', formatStr);
|
|
return date;
|
|
}
|
|
} catch (e) {
|
|
// 이 형식이 실패하면 다음 형식 시도
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// 위 모든 형식이 실패하면 마지막으로 Date 생성자 시도
|
|
const dateFromConstructor = new Date(dateStr);
|
|
if (isValid(dateFromConstructor)) {
|
|
console.log('Date 생성자로 파싱 성공');
|
|
return dateFromConstructor;
|
|
}
|
|
|
|
// 모든 방법이 실패하면 null 반환
|
|
console.warn(`날짜 파싱 실패: ${dateStr}`);
|
|
return null;
|
|
} catch (error) {
|
|
console.error(`날짜 파싱 중 오류 발생: ${dateStr}`, error);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Date 객체를 yyyy-MM-dd 형식의 문자열로 변환
|
|
*/
|
|
export const formatDateToYMD = (date: Date): string => {
|
|
return format(date, 'yyyy-MM-dd');
|
|
};
|
|
|
|
/**
|
|
* 현재 년월 포맷 (yyyy-MM)
|
|
*/
|
|
export const getCurrentYearMonth = (): string => {
|
|
return format(new Date(), 'yyyy-MM');
|
|
};
|