[JS]Unix TimeStamp to DATE Time
그냥 공부용도로 만든것이다. 더 좋은 함수들이 많다…
Time Stamp
타임 스템프는 date = new Date()
에서 .getTime()
메소드를 사용하여 가져왔다.
초(sec)
초는 .
getTime()
으로 가져온 (1/1000)초를 1초로 바꾸기 위해 .getTime() * 1000
으로 계산 하였다.
분(min)
초를 기반으로 sec / 60
을 하여 분을 구하고, 나머지를 sec
변수에 다시 넣어 주었다.
시(hour)
이 역시 분을 기반으로 min / 60
으로 시를 구하고, 나머지를 min
변수에 다시 넣어 주었다.
일(day)
여기까지는 지금까지와 마찬가지로,
hour / 24로 일을 구하고 나머지를 day 변수에 다시 넣어 주었다.
문제가 생기기 시작하는 월, 년, 요일
매달 같은 일 수가 다른 ‘월’과 4년에 한번씩 윤년이 있는 ‘년’ 그리고 어떻게 찾아야 할지 막막한 ‘요일’
해당 문제들에 대해 해결한 과정을 순서대로 써보겠다.
윤년을 구하는 함수(is_leap)를 만들자.
윤년은
– 4로 나누어 떨어지는 년도는 윤년이다.(year % 4 == 0)
– 하지만 100으로 나누어 떨어지는 년도는 윤년이 아니다. (year % 100 != 0)
– 하지만 400으로 나누어 떨어지는 년도는 무조건 윤년이다. (year % 400 == 0)
((_year % 4) == 0) && ((_year %100) != 0) || ((_year % 400) == 0)
이를 조건으로 윤년임을 확인하는 함수를 만들 수 있다.
function is_leap(_year){ if(_year){ // 0은 윤년이 아니다. if(((_year % 4) == 0) && ((_year %100) != 0) || ((_year % 400) == 0)) return true return false } }
이는 정말 유용하게 사용된다.
‘년’을 먼저 구하고 ‘월’을 구하자.
먼저 코드를 보자.
function calc_year(day_){ leap_stamp_cnt = 477 // Number of leap years by 1970 year_= Math.floor(day_ / 365) + 1970; day_ = day_ % 365 leap_now_cnt = Math.floor((year_ - 1) / 4) - Math.floor((year_ - 1) / 100) + Math.floor((year_ - 1) / 400) return { day_: day_ - (leap_now_cnt - leap_stamp_cnt), // remove day of leap year year_: year_ }
원리는 간단하다.
1970부터 2017(현재)까지의 윤년의 수를 구해 남은 day
변수에서 빼주는 방식이다,
L은 1년부터 Y년 까지 윤년의 개수이다.
해당 방식에 좀 더 나은 코드가 있을 거라고 생각되어 1에 1970을 넣었지만, 1에 1970을 넣으니 12가 아닌 11이 나온다.
‘월’을 구하자.
1월 1일 부터 남은 ‘일’수를 더 해 월을 구하자.
function calc_month(day_,year_){ month_ = 1 while(month_ <= 7 && ((day_ >= 31 && month_ & 1) || (day_ >= 30 && !(month_ & 1))) ) { if(month_ == 2){ day_ -= 28 if(is_leap(year_)){ day_-- } month_++ } else if(month_ & 1){ day_ -= 31 month_++ } else { day_ -= 30 month_++ } } while(month_ <= 12 && ((day_ >= 30 && month_ & 1) || (day_ >= 31 && !(month_ & 1))) ){ if(month_ & 0){ day_ -= 31 month_++ } else { day_ -= 30 month_++ } } return { day_: day_ + 1, month_: month_ } }
원리는 7월까지는 홀수 달이 31이고 2월만 28일이고 윤년에 따라 변하니 구분해주었고,
8월 부터는 짝수달이 31일인점을 이용하였다. return의 +1은 1월 1일 부터 시작하니 1을 더해주 었다.
이도 좀 더 나은 방법이 있을 것이라고 생각된다.
자, 년 월 일 시 분 초 모두 구했다. 이를 가지고 요일을 찾아보자
요일을 찾는 방법이 제일 골치 아팟다. 하지만 zeller’s congruence 을 사용한다면 생각만큼 어렵지는 않다.
zeller’s congruence에 대한 자세한 내용은 링크에서 볼 알아 볼 수 있다.
function calc_weekday (day_,month_,year_){ /* Using zeller's congruence */ k = year_ % 100 j = year_ / 100 return Math.floor((day_ + Math.floor(13 * (month_ + 1) / 5) + k + Math.floor(k / 4) + 5 * j + Math.floor(j / 4) ) % 7) }
0이면 토요일 6이면 금요일이니 이를 이용하여 요일을 표현 할 수 있다.
github 에 모든 소스코드를 올려 놓았다.