Files
zellyy-finance/src/utils/dateParser.ts
gpt-engineer-app[bot] e947a84dcb Fix: Display 0 for expenses
2025-04-05 06:02:31 +00:00

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');
};