* 지난 회 게시물 [1]의 내용에서 이어집니다.
지난 회 게시물에서 C() 포맷 코드를 소개한 바 있는데, 오늘은 먼저 이와 관련된 내용을 조금 더 언급하기로 하겠습니다. 먼저 다음과 같이 2019년 6월 28일 14시 55분에 대한 JD 값을 변수에 먼저 담아봅니다.
IDL> tj = JULDAY(6, 28, 2019, 14, 55)
이제 이 JD 값을 C() 포맷으로 출력해 봅시다. 지난 회에서 언급했던 방법을 그대로 이용하여 다음과 같이 PRINT 명령의 FORMAT 키워드에 C() 포맷 코드를 지정하여 분 단위까지 출력되도록 합니다.
IDL> PRINT, tj, FORMAT='(C(CYI4.4, CMoI2.2, CDI2.2, CHI2.2, CMI2.2))'
출력된 내용은 다음과 같습니다.
201906281455
그런데 만약 출력에 있어서 함께 표시되어야 할 고정 문자가 있을 경우에는, 포맷 코드의 내용 안에 그 고정 문자를 더블따옴표(")를 이용하여 삽입하면 됩니다. 예를 들어 포맷 코드의 내용을 다음과 같이 수정해 봅시다.
IDL> PRINT, tj, FORMAT='(C(CYI4.4, "/", CMoI2.2, "/", CDI2.2, " ", CHI2.2, ":", CMI2.2))'
여기서는 년과 월 사이 및 월과 일 사이에 / 문자가 삽입되도록 하고, 시와 분 사이에 : 문자가 삽입되도록 하고 년월일과 시분 사이에는 공백 한 칸이 삽입되도록 하였습니다. 그러면 출력되는 내용은 다음과 같습니다.
2019/06/28 14:55
이렇게 하면 뭔가 우리 눈에 더 익숙한 형태로 날짜/시각이 표시되는 것을 볼 수 있습니다. 이번에는 C() 포맷 코드에서 월(month)에 해당되는 부분인 CMoI를 다음과 같이 CMoA로 바꿔봅시다.
IDL> PRINT, tj, FORMAT='(C(CYI4.4, "/", CMoA, "/", CDI2.2, " ", CHI2.2, ":", CMI2.2))'
이렇게 할 경우에는 다음과 같이 출력됩니다.
2019/Jun/28 14:55
이것은 월(month)을 숫자로 표시하느냐 아니면 약어 형태로 표시하느냐의 차이입니다. CMoI와 CMoA 사이의 차이는 I와 A인데 이 둘은 포맷코드에서 정수와 문자를 의미합니다. 그런데 월을 이와 같이 고유명 약어로 표시할 경우에는 전체적으로 다음과 같이 출력되도록 하는 것이 관습적으로는 더 익숙할 것 같습니다. 물론 이 부분은 여러분의 판단에 맡깁니다.
IDL> PRINT, tj, FORMAT='(C(CMoA, " ", CDI2.2, ", ", CYI4.4, " ", CHI2.2, ":", CMI2.2))'
Jun 28, 2019 14:55
어쨌든 이와 같이 C() 포맷 코드를 적절히 활용하여 날짜/시작에 대한 출력의 형식을 자유자재로 바꿀 수 있다는 것을 알아두면 굉장히 유용하다는 점을 강조하고 싶습니다. 자 그러면 이번에는 다음과 같이 tj 변수의 값에 100을 더한 값을 tj1이란 변수에 담아 봅시다.
IDL> tj1 = tj+100d
그리고 이 tj1 변수의 JD 값을 다음과 같이 C() 포맷 코드를 사용하여 출력해 봅시다.
IDL> PRINT, tj1, FORMAT='(C(CMoA, " ", CDI2.2, ", ", CYI4.4, " ", CHI2.2, ":", CMI2.2))'
출력된 내용은 다음과 같습니다.
Oct 06, 2019 14:55
이것은 tj의 날짜인 2019년 6월 28일 14시 55분으로부터 정확히 100일 직후에 해당되는 날짜가 2019년 10월 6일 14시 55분이란 얘기입니다. 만약 tj의 날짜로부터 300일 직후의 날짜가 궁금할 경우에는 다음과 같이 tj에 300을 더한 JD 값에 대한 날짜를 출력하면 됩니다.
IDL> tj1 = tj+300d
IDL> PRINT, tj1, FORMAT='(C(CMoA, " ", CDI2.2, ", ", CYI4.4, " ", CHI2.2, ":", CMI2.2))'
Apr 23, 2020 14:55
그러면 이와 같이 2020년 4월 23일이라는 결과가 출력됩니다. 이미 언급한 바와 같이 JD 값은 그 단위가 일(day)입니다. 따라서 위와 같이 100 또는 300과 같은 값을 더해주면 그만큼의 일수(number of days)가 더해진 날짜가 됩니다. 참고로 여기서 100 또는 300을 표시할 때알파벳 d를 붙여준 이유는 JD 값 자체가 2배 정밀도 실수이기 때문에 변수 tj와 동일한 자료형으로 맞추기 위한 목적도 있고, 바로 아래의 내용과도 연관이 있기도 합니다(숫자에 d를 붙이면 그 숫자는 2배 정밀도 실수형 값이 됩니다).
즉 바로 위의 예제와 같이 일 단위의 값을 더해주는 대신 시간 또는 분 단위의 값을 더해주는 경우도 있습니다. 예를 들어 tj로부터 17시간 이후의 날짜가 궁금할 경우에는 다음과 같이 처리하면 됩니다.
IDL> tj1 = tj+17d/24
IDL> PRINT, tj1, FORMAT='(C(CMoA, " ", CDI2.2, ", ", CYI4.4, " ", CHI2.2, ":", CMI2.2))'
Jun 29, 2019 07:55
왜냐하면 17시간은 일 단위 값이 되려면 24시간(1일)을 나눠서 17/24가 되어야 하기 때문입니다. JD가 일 단위이기 때문에 서로 보조를 맞추기 위하여 이런 식으로 처리해야 합니다. 이런 방식으로 생각한다면 분, 초 단위까지 고려해야 할 경우에도 비슷한 방식으로 처리할 수 있습니다. 예를 들어 tj로부터 63시간 44분 이후의 날짜가 궁금하다면 다음과 같이 처리하면 됩니다.
IDL> tj1 = tj+63d/24+44d/(24*60)
IDL> PRINT, tj1, FORMAT='(C(CMoA, " ", CDI2.2, ", ", CYI4.4, " ", CHI2.2, ":", CMI2.2))'
Jul 01, 2019 06:39
즉 63시간은 24시간으로 나눠서 일 단위로 변환하고, 44분은 1440(=24*60)분으로 나눠서 일 단위로 변환하여 처리하는 방식입니다. 만약 초 단위까지 고려해야 할 경우라면, 초 단위의 값을 24*60*60으로 나눠주면 됩니다.
앞서 언급했던 예제들에서는 특정한 날짜로부터 일정 기간 이후의 날짜를 알아내는 방법들을 살펴보았는데요. 이번에는 특정한 두 날짜 사이의 차이를 알아내는 방법을 보고자 합니다. 예를 들어 축구선수 손흥민 선수의 생일이 1992년 7월 8일입니다. 그러면 2019년 7월 1일 현재 손흥민 선수가 지금까지 살아온 일수(number of days)를 어떻게 계산하면 될까요? 이를 위해서는 다음과 같이 두 날짜에 대한 JD 값을 각각 변수로 담은 후 서로 빼주면 됩니다.
IDL> tj0 = JULDAY(7, 8, 1992)
IDL> tj1 = JULDAY(7, 1, 2019)
IDL> PRINT, tj1-tj0
이렇게 하면 9854라는 값이 출력되는 것을 볼 수 있습니다. 물론 이것은 생일로부터 경과한 일수가 9854일이란 뜻이기 때문에, 생일 당일을 제 1일로 포함시켜야 한다면 답은 9855일이 될 것입니다. 둘 중 어떤 값이 사용되어야 하느냐는 경우에 따라 다를 겁니다. 커플이신 분들은 교제를 시작한 날짜가 명확하다면 오늘까지 며칠이 지났는지 또는 100일이나 200일 기념일이 언제가 될 것인지도 이러한 방식으로 계산하는 것이 가능합니다.
지금까지 1, 2회에 걸쳐서 Julian Date 기반으로 날짜/시각 값을 다루는 여러가지 방법들을 살펴보았습니다. 다소 단편적이면서도 기본적인 내용들 위주로 알아보았는데요. 이제 다음번에는 날짜 기반의 데이터를 처리하는 방법을 좀 더 실전에 가까운 예제를 활용하여 소개해보기로 하겠습니다.
'IDL > Programming' 카테고리의 다른 글
격자점들의 다각형 내부/외부 판별 (Grids inside Polygon) (Part 1) (0) | 2019.10.28 |
---|---|
포인트들의 다각형 내부/외부 판별 (Points inside Polygon) (0) | 2019.10.11 |
Julian Date 및 날짜/시간 포맷(Date Format) 다루기 [1] (0) | 2019.07.07 |
작업 스케줄러를 이용한 IDL 프로그램의 자동 실행 (0) | 2018.08.20 |
IDL Task 소개 (Part 3) (0) | 2018.05.15 |