문제 상황
"HH:MM:SS" 형식의 시간 문자열을 입력받아 처리하는 JavaScript 함수를 작성해야 합니다.
그런데 기존 덧셈 로직에 오류가 있었던 탓에, 상당수의 시간 문자열이 깨져 있는 상태입니다. 즉 분(MM) 부분이 60을 초과하거나, 초(SS) 부분 역시 60을 넘는 비정상적인 값이 저장되어 있을 수 있습니다.
따라서 이 함수는 잘못된 값을 올바른 시간으로 보정한 뒤, 새로 수정된 문자열을 반환해야 합니다.
예를 들면 다음과 같습니다 −
"08:11:71" -> "08:12:11"
해결 코드
다음은 위 문제를 해결하는 전체 코드입니다 −
const str = '08:11:71';
const rectifyTime = (str = '') => {
if(!Boolean(str)){
return str;
};
const re = /^(\d\d):(\d\d):(\d\d)$/;
if (!re.test(str)){
return null;
};
let [h, m, s] = str.match(re).slice(1,4).map(Number);
let time = h * 3600 + m * 60 + s;
s = time % 60;
m = (time / 60 |0) % 60;
h = (time / 3600 |0) % 24;
return [h, m, s]
.map(String)
.join(':');
};
console.log(rectifyTime(str));
코드 동작 원리
핵심 아이디어는 시간을 모두 초 단위로 환산한 뒤 다시 분배하는 것입니다. 순서대로 살펴보면 다음과 같습니다.
1. 먼저 빈 문자열 여부를 확인하고, 그대로 반환합니다.
2. 정규식 /^(\d\d):(\d\d):(\d\d)$/로 "HH:MM:SS" 형식인지 검증하고, 형식이 맞지 않으면 null을 반환합니다.
3. 정규식 매칭 결과에서 시, 분, 초를 추출해 숫자로 변환합니다.
4. 시 × 3600 + 분 × 60 + 초 공식으로 전체 시간을 초 단위로 합산합니다.
5. 나머지 연산(%)과 비트 OR(|0)을 활용해 초, 분, 시를 차례대로 재계산합니다. 이때 시간은 % 24로 24시간을 넘지 않도록 처리합니다.
6. 마지막으로 각 값을 문자열로 변환한 뒤 콜론(:)으로 연결해 결과를 만듭니다.
이 방식은 분이나 초가 60을 초과하더라도 자동으로 자릿수를 올려 올바른 시간으로 변환해 주기 때문에, 별도의 조건 분기 없이 간결하게 문제를 해결할 수 있습니다.
실행 결과
다음은 콘솔 출력 결과입니다 −
08:12:11