var start = new Date('2020-10-14 09:00:00'); var end = new Date('2020-10-14 09:07:00'); 또는 id로 value값을 가져와서 그 값의 비교를 할 경우에는, var start = new Date($('#id').val()); var end = new Date($('#id').val()); 이렇게 가져온 value를 넣어주면 된다. * 초 var diffTime = (end.getTime() - start.getTime()) / (1000); => result) 420 (1초 =1000ms 이기 때문에) * 분 var diffTime = (end.getTime() - start.getTime()) / (1000*60); => result) 7 (1분 = 60초 = 60000ms) 시 차이를 명확히 알기 위해 예제 시간을 변경해보겠다. var start = new Date('2020-10-14 09:00:00'); var end = new Date('2020-10-14 14:00:00'); * 시 var diffTime = (end.getTime() - start.getTime()) / (1000*60*60); => result) 5 ( 1시간 = 60분 = 360초 = 3600000ms ) 날짜 차이를 알아보자. 날짜 차이를 명확히 알기 위해 예제를 변경! var start = new Date('2018-07-02 09:00:00'); var end = new Date('2020-10-14 09:00:00'); * 일 var diffTime = (end.getTime() - start.getTime()) / (1000*60*60*24); => result) 835 * 월 var diffTime = (end.getTime() - start.getTime()) / (1000*60*60*24*30); => result) 27.833333333333332 * 년 var diffTime = (end.getTime() - start.getTime()) / (1000*60*60*24*30*12); => result) 2.3194444444444446
일반적인 날짜 비교
위의 결과값은 예상한 바와 같이 궁금증은 moment.js를 사용하면서 시작되었다.
궁금증1 : moment로 변형된 날짜는 비교가 될까?
Date와 같은 결과를 보여주었다. 이렇게만 하고 넘어갔다면 아무런 궁금증을 갖을 수 없었을 것이다. 이제 호기심의 서막이 시작된다.🔥 우선, 포맷을 다르게 하여 비교해 보았다. 포맷을 다르게 하면 어떤 결과가 나올까?
오잉?! 결과값이 달라졌다. 단지 포맷을 바꿨을뿐인데...그래서 곰곰히 생각해본 결과, 위 결과값은 문자열 비교로 인해 나타난 것이였다. Date는 moment.js에 의해서 Date타입에서 문자열로 변형된다. 그래서 >, < 연산자는 사전 순서로 문자열을 하나씩 비교한다. 이미지를 보면, 첫번째 포맷의 비교에선 '11'과 '08'에서의 문자열 비교로 값이 결정됬다. 두번째 포맷은 '11th'과 '8th'에서의 문자열 비교가 된다. 이런 신기방기한 일이 일어나다니 참 재미있는(?) 자바스크립트 세계이다. 어쨌든 결과값이 날짜와 포맷에 따라서 일정하지 않다는 것은 매우 안좋은 소식이다. Date 타입은 비교가 가능했지만, Moment로 변형을 시켜서 비교하는 것은 비추한다 라는 결론을 내릴 수 있다. 궁금증2 : 그럼 다시 moment를 숫자로 형변환하여 비교하면 어떻게 될까?
이 결과값은 예상이 가능? 모두 false가 나온다. 위에서 언급했듯이 moment.js로 변형되면 Date타입에서 문자열로 변형된다. 문자열을 숫자형을 변형시키면 NaN이 되기 때문에 NaN끼리의 비교는 false가 나온다.
Date는 원래도 비교가 가능했기 때문에 숫자로 형변환해도 비교가 가능하다. 또한 그 값을 찍어보면 아래와 같이 내부적으로 갖고 있는 숫자값(밀리초단위의 시간)이 출력된다.
다시 한 번 확인해보자. Date는 객체타입이고 moment.js에 의해서 변형된 Date는 문자열 타입이다. 궁금증3이런 경우엔 어떻게 될까?
결과값을 예상해보자 🔥 true false true false 202103110813(현재날짜시간) 202103080900 왜 이런 결과값이 나오는지 설명할 수
있을까? 정리자바스크립트는 이상한(?) 형변환에 때문에 위와 같은 현상이 발생한다. 기본적으로 객체타입은 숫자로 형변환이 이루어지면 NaN(Not A Number)으로 변형된다. 그래서 비교할 수 없는 상태(?)로 되며, NaN과의 비교는 무조건 false가 나온다.
그런데 객체 타입인 날짜는 내부적으로 숫자로 바뀌게 됨으로서 비교가능해지는 독특한 특징을 갖게 된다. 반면 moment.js로 변형된 날짜의 경우 문자열 타입을 갖게 된다. 문자열의 숫자로의 형변환은 어떤 문자인지에 따라서 다르다.
첫번째는 당연히 false가 나오고 두번째는 true가 된다. 즉 숫자인 문자열은 형변환이 되어 숫자가 될 수 있지만, 숫자가 아닌 문자열은 NaN이 되어 비교할 수 없는 상태가 되는 것이다. 이처럼 moment.js로 변형된 날짜 문자열은 어떻게 변형되는냐에 따라서 비교가능할 수도, 비교 불가능할 수도 있다. 결론그냥 Date로 비교가 가능한데, 누가 보면 굳이 왜 저런 요상망측한 짓을 하는 것이냐고 물을 수도 있다. 그런데 개발을 하다보면 다양한 상황들이 나오고 그 상황에 맞추다 보면 요상한 짓(?)을 해야할 때가 생긴다. 그러다보면 기본에 대한 생각을 잊어버리고 상황에 맞춘 해결책으로 문제를 해결하고 또 그 해결책이 잘 돌아간다. 해결여부에 초첨을 맞추다보면 표준, 기준, 기본에 대해서 잊고 지나가는 경우가 많아진다. 위 호기심은 단순 호기심에서 시작되었지만, 결국 자바스크립트의 요상한(?) 형변환에 대해서 다시 한 번 리뷰할 수 있는 시간이였다. 이때문에 강제형변환으로 인한 예상치 못한 결과가 나오는 코드를 쓰지 않도록, 될 수 있으면 기본에 충실한 코드, 예상이 가능한 코드를 쓰도록 노력해자라는 나름 의미있는 교훈을 얻을 수 있었다.
|