ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [DB] DB에서 특정한 형식으로 출력하기(시간, 문자열) (TO_CHAR()이용하기), 타임존 설정하기
    TIL 2024. 4. 5. 17:02

    프로젝트를 진행하던 중 해당 게임의 위키 수정내역(히스토리) 목록을 보여줘야 했다.

     

    각각의 히스토리들의 제목은 작성된 < 시각 + 사용자닉네임 >의 형태로 보여줘야했고, 이와 같은 형태로 API 내에서 값을

     

    후처리해서 반환해줘야 했다.

     

     

    DB에서 SELECT 해온 값을 타임존설정하기특정한 시간 형식으로 바꾸거나 특정한 문자열 형식으로 변환해서 반환하는 법을 알아보았다.

     

     

     

    1.특정한 시간형식으로 변경하기)

    TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD HH24:MI:SS');

     

    첫번째 매개변수에 시간 값, 두번째 매개변수에 출력형식을 입력한다.

     

    여기서 주의할점은 시는 HH24로 해줘야 24시간 형식으로 출력이되고,  분은 MI로 해줘야한다는것. 

     

    월(MM)과 분(MI)을 잘 분리해줘야한다

     

     

     

     

    2.타임존설정하기

     

    SELECT
    	created_at  AT TIME ZONE 'Asia/Seoul'

     

     

    불러온 created_at (타임스탬프)를 서울 시간으로 적용해준다

     

     

     

    3. 특정 문자열 형식으로 처리해서 출력하기 

    SELECT 
        TO_CHAR(h.created_at AT TIME ZONE 'Asia/Seoul', 'YYYY-MM-DD HH24:MI:SS') || ' ' || u.nickname

     

     

     

     

     

     

     

     

    기존 코드) 잘못된예시)

    //히스토리 목록보기
    router.get('/:gameidx/history/all', async (req, res, next) => {
        const gameIdx = req.params.gameidx;
        try {
            //특정게임 히스토리목록 최신순으로 출력
            const selectHistorySQLResult = await pool.query(
                `
                SELECT 
                    h.idx, h.created_at AS "createdAt", u.nickname
                FROM 
                    history h 
                JOIN 
                    "user" u
                ON 
                    h.user_idx = u.idx
                WHERE 
                    game_idx = $1
                AND
                    h.created_at IS NOT NULL
                ORDER BY
                    h.created_at DESC`,
                [gameIdx]
            );
            const beforeHistoryList = selectHistorySQLResult.rows;
    
    // db에서 불러온값들을 불편하게 직접 후처리 해줬던 방식)
            let idx;
            let createdAt;
            let nickname;
            let timeStamp;
            let historyTitle;
            let history;
            let historyList = [];
    
            beforeHistoryList.forEach((element) => {
            // 불러온값 직접 반복문으로 후처리 했던 기존 코드)  
            //timestamp에 타임존을 적용해서 특정 시간형식으로 만들기
            // 만든 시간형식 뒤에 문자열 닉네임 붙이기
                history = {};
                idx = element.idx;
                timeStamp = element.createdAt;
                nickname = element.nickname;
                createdAt = moment(timeStamp).format('YYYY-MM-DD HH:mm:ss');
    
                historyTitle = createdAt + ' ' + nickname;
    
                history.idx = idx;
                history.title = historyTitle;
    
                historyList.push(history);
            });
    
            res.status(200).send({ data: historyList });
        } catch (e) {
            next(e);
        }
    });

     

    db에서 불러온 값을 직접 timezone을 적용해서 특정 시간 형식으로 만든다음,

     

    뒤에 원하는 문자열을 붙여줬던 방식이다.

     

     

     

     

    수정한 코드)

    db에서 timezone설정, 시간형식 설정, 문자열 형식설정 다해주기

     

     

     

    //히스토리 목록보기
    router.get('/:gameidx/history/all', async (req, res, next) => {
        const gameIdx = req.params.gameidx;
        try {
            //특정게임 히스토리목록 최신순으로 출력
            const selectHistorySQLResult = await pool.query(
                // history idx, 히스토리 제목(YYYY-MM-DD HH24:MI:SS 사용자닉네임) 출력
                `
                SELECT 
                    h.idx, 
                    TO_CHAR(h.created_at AT TIME ZONE 'Asia/Seoul', 'YYYY-MM-DD HH24:MI:SS') || ' ' || u.nickname AS "title"
                FROM 
                    history h 
                JOIN 
                    "user" u
                ON 
                    h.user_idx = u.idx
                WHERE 
                    game_idx = $1
                AND
                    h.created_at IS NOT NULL
                ORDER BY
                    h.created_at DESC`,
                [gameIdx]
            );
    
            const historyList = selectHistorySQLResult.rows;
    
            res.status(200).send({ data: historyList });
        } catch (e) {
            next(e);
        }
    });
Designed by Tistory.