feat: dayjs 라이브러리로 날짜 계산 로직 통합
- dayjs 패키지 설치 (타임존 지원) - utils/date.js 유틸리티 생성 (getTodayKST, formatDate, parseDateKST 등) - PC/모바일 Home.jsx의 날짜 계산을 유틸리티로 교체 - PC Schedule.jsx, AdminSchedule.jsx의 getTodayKST 함수를 유틸리티로 교체 - KST 타임존 기준으로 정확한 날짜 계산 보장
This commit is contained in:
parent
cca25b456c
commit
0d72dfe456
7 changed files with 96 additions and 23 deletions
7
frontend/package-lock.json
generated
7
frontend/package-lock.json
generated
|
|
@ -9,6 +9,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/react-query": "^5.90.16",
|
"@tanstack/react-query": "^5.90.16",
|
||||||
|
"dayjs": "^1.11.19",
|
||||||
"framer-motion": "^11.0.8",
|
"framer-motion": "^11.0.8",
|
||||||
"lucide-react": "^0.344.0",
|
"lucide-react": "^0.344.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
|
@ -1519,6 +1520,12 @@
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/dayjs": {
|
||||||
|
"version": "1.11.19",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
|
||||||
|
"integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/react-query": "^5.90.16",
|
"@tanstack/react-query": "^5.90.16",
|
||||||
|
"dayjs": "^1.11.19",
|
||||||
"framer-motion": "^11.0.8",
|
"framer-motion": "^11.0.8",
|
||||||
"lucide-react": "^0.344.0",
|
"lucide-react": "^0.344.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { motion } from 'framer-motion';
|
||||||
import { ChevronRight, Clock, Tag } from 'lucide-react';
|
import { ChevronRight, Clock, Tag } from 'lucide-react';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { getTodayKST } from '../../utils/date';
|
||||||
|
|
||||||
// 모바일 홈 페이지
|
// 모바일 홈 페이지
|
||||||
function MobileHome() {
|
function MobileHome() {
|
||||||
|
|
@ -24,8 +25,8 @@ function MobileHome() {
|
||||||
.then(data => setAlbums(data.slice(0, 2)))
|
.then(data => setAlbums(data.slice(0, 2)))
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
|
|
||||||
// 다가오는 일정 로드 (startDate + limit 방식)
|
// 다가오는 일정 로드
|
||||||
const today = new Date().toISOString().split('T')[0];
|
const today = getTodayKST();
|
||||||
fetch(`/api/schedules?startDate=${today}&limit=3`)
|
fetch(`/api/schedules?startDate=${today}&limit=3`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => setSchedules(data))
|
.then(data => setSchedules(data))
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Calendar, ArrowRight, Clock, Link2, Tag } from 'lucide-react';
|
import { Calendar, ArrowRight, Clock, Link2, Tag } from 'lucide-react';
|
||||||
|
import { getTodayKST } from '../../utils/date';
|
||||||
|
|
||||||
function Home() {
|
function Home() {
|
||||||
const [members, setMembers] = useState([]);
|
const [members, setMembers] = useState([]);
|
||||||
|
|
@ -15,11 +16,7 @@ function Home() {
|
||||||
.catch(error => console.error('멤버 데이터 로드 오류:', error));
|
.catch(error => console.error('멤버 데이터 로드 오류:', error));
|
||||||
|
|
||||||
// 다가오는 일정 로드 (오늘 이후 3개)
|
// 다가오는 일정 로드 (오늘 이후 3개)
|
||||||
// KST 기준으로 오늘 날짜 계산
|
const todayStr = getTodayKST();
|
||||||
const now = new Date();
|
|
||||||
const kstOffset = 9 * 60; // KST는 UTC+9
|
|
||||||
const kstTime = new Date(now.getTime() + (kstOffset + now.getTimezoneOffset()) * 60000);
|
|
||||||
const todayStr = kstTime.toISOString().split('T')[0];
|
|
||||||
|
|
||||||
fetch(`/api/schedules?startDate=${todayStr}&limit=3`)
|
fetch(`/api/schedules?startDate=${todayStr}&limit=3`)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,11 @@ import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { Clock, ChevronLeft, ChevronRight, ChevronDown, Tag, Search, ArrowLeft, Link2 } from 'lucide-react';
|
import { Clock, ChevronLeft, ChevronRight, ChevronDown, Tag, Search, ArrowLeft, Link2 } from 'lucide-react';
|
||||||
import { useInfiniteQuery } from '@tanstack/react-query';
|
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||||
import { useInView } from 'react-intersection-observer';
|
import { useInView } from 'react-intersection-observer';
|
||||||
|
import { getTodayKST } from '../../utils/date';
|
||||||
|
|
||||||
function Schedule() {
|
function Schedule() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// KST 기준 오늘 날짜 (YYYY-MM-DD)
|
|
||||||
const getTodayKST = () => {
|
|
||||||
const now = new Date();
|
|
||||||
const kstOffset = 9 * 60 * 60 * 1000; // 9시간
|
|
||||||
const kstDate = new Date(now.getTime() + kstOffset);
|
|
||||||
return kstDate.toISOString().split('T')[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
const [currentDate, setCurrentDate] = useState(new Date());
|
const [currentDate, setCurrentDate] = useState(new Date());
|
||||||
const [selectedDate, setSelectedDate] = useState(getTodayKST()); // KST 기준 오늘
|
const [selectedDate, setSelectedDate] = useState(getTodayKST()); // KST 기준 오늘
|
||||||
const [showYearMonthPicker, setShowYearMonthPicker] = useState(false);
|
const [showYearMonthPicker, setShowYearMonthPicker] = useState(false);
|
||||||
|
|
|
||||||
|
|
@ -11,18 +11,11 @@ import { useInView } from 'react-intersection-observer';
|
||||||
import Toast from '../../../components/Toast';
|
import Toast from '../../../components/Toast';
|
||||||
import Tooltip from '../../../components/Tooltip';
|
import Tooltip from '../../../components/Tooltip';
|
||||||
import useScheduleStore from '../../../stores/useScheduleStore';
|
import useScheduleStore from '../../../stores/useScheduleStore';
|
||||||
|
import { getTodayKST } from '../../../utils/date';
|
||||||
|
|
||||||
function AdminSchedule() {
|
function AdminSchedule() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
// KST 기준 오늘 날짜 (YYYY-MM-DD)
|
|
||||||
const getTodayKST = () => {
|
|
||||||
const now = new Date();
|
|
||||||
const kstOffset = 9 * 60 * 60 * 1000;
|
|
||||||
const kstDate = new Date(now.getTime() + kstOffset);
|
|
||||||
return kstDate.toISOString().split('T')[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Zustand 스토어에서 상태 가져오기
|
// Zustand 스토어에서 상태 가져오기
|
||||||
const {
|
const {
|
||||||
searchInput, setSearchInput,
|
searchInput, setSearchInput,
|
||||||
|
|
|
||||||
81
frontend/src/utils/date.js
Normal file
81
frontend/src/utils/date.js
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
* 날짜 관련 유틸리티 함수
|
||||||
|
* dayjs를 사용하여 KST(한국 표준시) 기준으로 날짜 처리
|
||||||
|
*/
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import utc from "dayjs/plugin/utc";
|
||||||
|
import timezone from "dayjs/plugin/timezone";
|
||||||
|
|
||||||
|
// 플러그인 확장
|
||||||
|
dayjs.extend(utc);
|
||||||
|
dayjs.extend(timezone);
|
||||||
|
|
||||||
|
// 기본 타임존 설정
|
||||||
|
const KST = "Asia/Seoul";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KST 기준 오늘 날짜 (YYYY-MM-DD)
|
||||||
|
* @returns {string} 오늘 날짜 문자열
|
||||||
|
*/
|
||||||
|
export const getTodayKST = () => {
|
||||||
|
return dayjs().tz(KST).format("YYYY-MM-DD");
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KST 기준 현재 시각
|
||||||
|
* @returns {dayjs.Dayjs} dayjs 객체
|
||||||
|
*/
|
||||||
|
export const nowKST = () => {
|
||||||
|
return dayjs().tz(KST);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 날짜 문자열 포맷팅
|
||||||
|
* @param {string|Date} date - 날짜
|
||||||
|
* @param {string} format - 포맷 (기본: 'YYYY-MM-DD')
|
||||||
|
* @returns {string} 포맷된 날짜 문자열
|
||||||
|
*/
|
||||||
|
export const formatDate = (date, format = "YYYY-MM-DD") => {
|
||||||
|
return dayjs(date).tz(KST).format(format);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 날짜에서 년, 월, 일, 요일 추출
|
||||||
|
* @param {string|Date} date - 날짜
|
||||||
|
* @returns {object} { year, month, day, weekday }
|
||||||
|
*/
|
||||||
|
export const parseDateKST = (date) => {
|
||||||
|
const d = dayjs(date).tz(KST);
|
||||||
|
const weekdays = ["일", "월", "화", "수", "목", "금", "토"];
|
||||||
|
return {
|
||||||
|
year: d.year(),
|
||||||
|
month: d.month() + 1,
|
||||||
|
day: d.date(),
|
||||||
|
weekday: weekdays[d.day()],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 두 날짜 비교 (같은 날인지)
|
||||||
|
* @param {string|Date} date1
|
||||||
|
* @param {string|Date} date2
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export const isSameDay = (date1, date2) => {
|
||||||
|
return (
|
||||||
|
dayjs(date1).tz(KST).format("YYYY-MM-DD") ===
|
||||||
|
dayjs(date2).tz(KST).format("YYYY-MM-DD")
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 날짜가 오늘인지 확인
|
||||||
|
* @param {string|Date} date
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export const isToday = (date) => {
|
||||||
|
return isSameDay(date, dayjs());
|
||||||
|
};
|
||||||
|
|
||||||
|
// dayjs 인스턴스도 export (고급 사용용)
|
||||||
|
export { dayjs };
|
||||||
Loading…
Add table
Reference in a new issue