emacs lisp로 ISO 8601 날짜와 시간을 포맷 스트링으로 변환

1 minute read

(parse-time-string "2020-12-03T06:58:28.649Z")
(28 58 6 3 12 2020 nil nil 0)

parse-time-string 함수는 ISO 8601 날짜와 시간을 파싱(parsing)하지 못한다.

(iso8601-parse "2020-12-03T06:58:28.649Z")
(28 58 6 3 12 2020 nil nil 0)

다행히 iso8601-parse 함수도 있어서 사용하니 제대로 파싱된다. 2020 값이 리스트 첫번째 요소가 아니라서 찾아보니 (sec min hour day mon year dow dst tz) 역순이네.

time을 날리고 date만 표시하게 포맷팅(formatting)을 하고 싶다.

(format-time-string "%Y-%m-%d"
                    (iso8601-parse "2020-12-03T06:58:28.649Z"))
1970-01-22

1970-01-01 처럼 epoch 날짜가 나오는 것도 아니고 22 는 뭐람. iso8601-parse 함수 결과를 바로 넣으니 제대로 포맷팅이 안 된다.

Function: date-to-time string

This function parses the time-string string and returns the corresponding Lisp timestamp. The argument string should represent a date-time, and should be in one of the forms recognized by parse-time-string (see below). This function assumes Universal Time if string lacks explicit time zone information. The operating system limits the range of time and zone values.

40.8 Parsing and Formatting Times

lisp timestamp 라는 게 나온다. 이걸로 변환해서 format-time-string 으로 넣어야 하는가 보다. iso8601-parse 함수 리턴 값을 인자로 넣었을 때, 에러가 안 나는 걸로 봐서 lisp timestamp 는 리스트로 구성됐나 보다.

(format-time-string "%Y-%m-%d"
                    (encode-time (iso8601-parse "2020-12-03T06:58:28.649Z")))
2020-12-03

lisp timestamp 로 변환하는 encode-time 함수를 쓰니 이제야 제대로 나온다.

parse-iso8601-time-string 함수가 있는 parse-time.el 소스 코드를 보다가 하나 발견했다.

(defun parse-iso8601-time-string (date-string)
  "Parse an ISO 8601 time string, such as 2016-12-01T23:35:06-05:00.
If DATE-STRING cannot be parsed, it falls back to
`parse-time-string'."
  (when-let ((time
              (if (iso8601-valid-p date-string)
                  (decoded-time-set-defaults (iso8601-parse date-string))
                ;; Fall back to having `parse-time-string' do fancy
                ;; things for us.
                (parse-time-string date-string))))
    (encode-time time)))

문서화되지 않은 함수다. encode-time 함수 말고 이 함수를 쓰면 되겠네.

(format-time-string "%Y-%m-%d"
                    (parse-iso8601-time-string "2020-12-03T06:58:28.649Z"))
2020-12-03

끝~

C-x C-s C-x C-c