Skip to content

Commit

Permalink
[Fix] 주식 폐장시간 관련 데이터 갱신로직 수정
Browse files Browse the repository at this point in the history
- 주식 폐장시간 도래 시 (15시 30분) 주가관련 데이터 refetch 로직 중단되도록 로직 수정

Issues #122
  • Loading branch information
novice1993 committed Oct 2, 2023
1 parent 2adea98 commit c553adf
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 22 deletions.
29 changes: 19 additions & 10 deletions client/src/hooks/useGetStockData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,42 +9,51 @@ const useGetStockData = (companyId: number) => {
const [autoRefetch, setAutoRefetch] = useState(false);

// 1) 주말, 공휴일 여부 체크
const today = new Date();
const isBusinessDay = !isHoliday(today, { include: { saturday: true, sunday: true } }); // 토요일, 일요일, 공휴일 (임시 공휴일 포함)
const currentTime = new Date();
const isBusinessDay = !isHoliday(currentTime, { include: { saturday: true, sunday: true } }); // 토요일, 일요일, 공휴일 (임시 공휴일 포함)

// 2) 개장시간 여부 체크
const currentHour = today.getHours();
const currentMinute = today.getMinutes();
const currentHour = currentTime.getHours();
const currentMinute = currentTime.getMinutes();
const isBefore9AM = currentHour < 9;
const isAfter330PM = currentHour > 15 || (currentHour === 15 && currentMinute >= 30);
const marketCloseTime = isBefore9AM || isAfter330PM;

const dataRenewalTime = isBusinessDay || !marketCloseTime;

// 시간대 (timeZone) 별로 queryKey를 다르게 설정해서, 서버 데이터가 동일할 때는 캐싱된 데이터 활용하고 서버 데이터가 갱신됐을 때는 새롭게 받아옴 (서버 데이터 30분마다 갱신)
const currentTime = new Date();
const [month, day, hour, minute] = [currentTime.getMonth(), currentTime.getDate(), currentTime.getHours(), currentTime.getMinutes()];
const timeZone = minute === 0 || minute === 30 ? "30 or 60" : 0 < minute && minute < 30 ? "1~29" : "31~59";
const queryKey = dataRenewalTime ? `chartData${companyId} ${month}${day}${hour}${timeZone}` : `chartData${companyId}`;

// 개장 시간 이내일 경우, 현재 시각이 30분, 정각이 아닌 경우 남은 시간 계산하여 checkTime 함수 다시 실행
useEffect(() => {
if (dataRenewalTime) {
if (minute === 0 || minute === 30) {
if (currentMinute === 0 || currentMinute === 30) {
setAutoRefetch(true);
} else if (0 < minute && minute < 30) {
const delayTime = (30 - minute) * 60000;
} else if (0 < currentMinute && currentMinute < 30) {
const delayTime = (30 - currentMinute) * 60000;
setTimeout(() => {
refetch();
setAutoRefetch(true);
}, delayTime);
} else if (30 < minute && minute < 60) {
const delayTime = (60 - minute) * 60000;
} else if (30 < currentMinute && currentMinute < 60) {
const delayTime = (60 - currentMinute) * 60000;
setTimeout(() => {
refetch();
setAutoRefetch(true);
}, delayTime);
}

// 15시 30분까지 남은 시간 계산 → 폐장시간 autoRefetch 중단
const targetTime = new Date();
targetTime.setHours(15);
targetTime.setMinutes(30);
const remainTime = targetTime.getTime() - currentTime.getTime();

setTimeout(() => {
setAutoRefetch(false);
}, remainTime);
}
}, []);

Expand Down
33 changes: 21 additions & 12 deletions client/src/hooks/useGetStockInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,55 @@ const useGetStockInfo = (companyId: number) => {
const [autoRefetch, setAutoRefetch] = useState(false);

// 1) 주말, 공휴일 여부 체크
const today = new Date();
const isBusinessDay = !isHoliday(today, { include: { saturday: true, sunday: true } }); // 토요일, 일요일, 공휴일 (임시 공휴일 포함)
const currentTime = new Date();
const isBusinessDay = !isHoliday(currentTime, { include: { saturday: true, sunday: true } }); // 토요일, 일요일, 공휴일 (임시 공휴일 포함)

// 2) 개장시간 여부 체크
const currentHour = today.getHours();
const currentMinute = today.getMinutes();
const currentHour = currentTime.getHours();
const currentMinute = currentTime.getMinutes();
const isBefore9AM = currentHour < 9;
const isAfter330PM = currentHour > 15 || (currentHour === 15 && currentMinute >= 30);
const marketCloseTime = isBefore9AM || isAfter330PM;

const dataRenewalTime = isBusinessDay || !marketCloseTime;

// 시간대 (timeZone) 별로 queryKey를 다르게 설정해서, 서버 데이터가 동일할 때는 캐싱된 데이터 활용하고 서버 데이터가 갱신됐을 때는 새롭게 받아옴 (서버 데이터 30분마다 갱신)
const currentTime = new Date();
const [month, day, hour, minute] = [currentTime.getMonth(), currentTime.getDate(), currentTime.getHours(), currentTime.getMinutes()];
const timeZone = minute === 0 || minute === 30 ? "30 or 60" : 0 < minute && minute < 30 ? "1~29" : "31~59";
const queryKey = dataRenewalTime ? `chartData${companyId} ${month}${day}${hour}${timeZone}` : `chartData${companyId}`;
const queryKey = dataRenewalTime ? `stockInfo${companyId} ${month}${day}${hour}${timeZone}` : `stockInfo${companyId}`;

// 개장 시간 이내일 경우, 현재 시각이 30분, 정각이 아닌 경우 남은 시간 계산하여 checkTime 함수 다시 실행
useEffect(() => {
if (dataRenewalTime) {
if (minute === 0 || minute === 30) {
if (currentMinute === 0 || currentMinute === 30) {
setAutoRefetch(true);
} else if (0 < minute && minute < 30) {
const delayTime = (30 - minute) * 60000;
} else if (0 < currentMinute && currentMinute < 30) {
const delayTime = (30 - currentMinute) * 60000;
setTimeout(() => {
refetch();
setAutoRefetch(true);
}, delayTime);
} else if (30 < minute && minute < 60) {
const delayTime = (60 - minute) * 60000;
} else if (30 < currentMinute && currentMinute < 60) {
const delayTime = (60 - currentMinute) * 60000;
setTimeout(() => {
refetch();
setAutoRefetch(true);
}, delayTime);
}

// 15시 30분까지 남은 시간
const targetTime = new Date();
targetTime.setHours(15);
targetTime.setMinutes(30);
const remainTime = targetTime.getTime() - currentTime.getTime();

setTimeout(() => {
setAutoRefetch(false);
}, remainTime);
}
}, []);

const { data, isLoading, error, refetch } = useQuery(`stockInfo${companyId} ${queryKey}`, () => getStockInfo(companyId), {
const { data, isLoading, error, refetch } = useQuery(queryKey, () => getStockInfo(companyId), {
staleTime: Infinity,
cacheTime: Infinity,
refetchInterval: autoRefetch && dataRenewalTime ? 60000 * 30 : false, // 정각 혹은 30분에 맞춰서 30분 마다 데이터 리패칭
Expand Down

0 comments on commit c553adf

Please sign in to comment.