Emacs: xah-fix-datetime π
Here's a command that fix datetime under cursor into yyyy-mm-dd format.
put this in your Emacs Init File:
(defun xah-fix-datetime (&optional Begin End) "Change timestamp under cursor into a yyyy-mm-dd format. If there's a text selection, use that as input, else use current line. Replace the text in selection or current line. Any βday of weekβ, or βtimeβ info, or any other parts of the string, are discarded. For example: TUESDAY, FEB 15, 2011 05:16 ET β 2011-02-15 November 28, 1994 β 1994-11-28 Nov. 28, 1994 β 1994-11-28 11/28/1994 β 1994-11-28 1994/11/28 β 1994-11-28 1994.11.28 β 1994-11-28 11.28.1994 β 1994-11-28 1994-11 β 1994-11 1994 β 1994 URL `http://xahlee.info/emacs/emacs/elisp_datetime_parser.html' Created: 2020-09-08 Version: 2025-04-01" (interactive) (require 'parse-time) (let (xbeg xend xinput xout) (if (and Begin End) (setq xbeg Begin xend End) (if (region-active-p) (setq xbeg (region-beginning) xend (region-end)) (setq xbeg (line-beginning-position) xend (line-end-position)))) (setq xinput (string-trim (buffer-substring-no-properties xbeg xend))) (when (not (string-match "[0-9][0-9]" xinput)) (error "input is probably not a date: %s" xinput)) (setq xout (cond ;; yyyy ((string-match "\\`\\([0-9][0-9][0-9][0-9]\\)\\'" xinput) xinput ) ;; yyyy-mm ((string-match "\\`\\([0-9][0-9][0-9][0-9]\\)-\\([0-9][0-9]\\)\\'" xinput) xinput ) ;; yyyymmdd ((string-match "\\([0-9][0-9][0-9][0-9]\\)\\([0-9][0-9]\\)\\([0-9][0-9]\\)" xinput) (concat (match-string 1 xinput) "-" (match-string 2 xinput) "-" (match-string 3 xinput))) ;; yyyy.mm.dd ((string-match "\\([0-9][0-9][0-9][0-9]\\)\\.\\([0-9][0-9]\\)\\.\\([0-9][0-9]\\)" xinput) (concat (match-string 1 xinput) "-" (match-string 2 xinput) "-" (match-string 3 xinput))) ;; mm.dd.yyyy ((string-match "\\([0-9][0-9]\\)\\.\\([0-9][0-9]\\)\\.\\([0-9][0-9][0-9][0-9]\\)" xinput) (format "%s-%s-%s" (match-string 3 xinput) (match-string 1 xinput) (match-string 2 xinput))) ;; yyyy/mm/dd ((string-match "\\([0-9][0-9][0-9][0-9]\\)/\\([0-9][0-9]\\)/\\([0-9][0-9]\\)" xinput) (concat (match-string 1 xinput) "-" (match-string 2 xinput) "-" (match-string 3 xinput))) ;; mm/dd/yyyy ((string-match "\\([0-9][0-9]\\)/\\([0-9][0-9]\\)/\\([0-9][0-9][0-9][0-9]\\)" xinput) (concat (match-string 3 xinput) "-" (match-string 1 xinput) "-" (match-string 2 xinput))) ;; m/dd/yyyy ((string-match "\\([0-9]\\)/\\([0-9][0-9]\\)/\\([0-9][0-9][0-9][0-9]\\)" xinput) (concat (match-string 3 xinput) "-0" (match-string 1 xinput) "-" (match-string 2 xinput))) ;; USA convention of mm/dd/yy ((string-match "\\([0-9][0-9]\\)/\\([0-9][0-9]\\)/\\([0-9][0-9]\\)" xinput) (concat (format-time-string "%C") (match-string 3 xinput) "-" (match-string 1 xinput) "-" (match-string 2 xinput))) ;; USA convention of m/dd/yy ((string-match "\\([0-9]\\)/\\([0-9][0-9]\\)/\\([0-9][0-9]\\)" xinput) (concat (format-time-string "%C") (match-string 3 xinput) "-0" (match-string 1 xinput) "-" (match-string 2 xinput))) ;; some ISO 8601. yyyy-mm-ddThh:mm ((string-match "\\([0-9][0-9][0-9][0-9]\\)-\\([0-9][0-9]\\)-\\([0-9][0-9]\\)T[0-9][0-9]:[0-9][0-9]" xinput) (concat (match-string 1 xinput) "-" (match-string 2 xinput) "-" (match-string 3 xinput))) ;; some ISO 8601. yyyy-mm-dd ((string-match "\\([0-9][0-9][0-9][0-9]\\)-\\([0-9][0-9]\\)-\\([0-9][0-9]\\)" xinput) (concat (match-string 1 xinput) "-" (match-string 2 xinput) "-" (match-string 3 xinput))) ;; some ISO 8601. yyyy-mm ((string-match "\\([0-9][0-9][0-9][0-9]\\)-\\([0-9][0-9]\\)" xinput) (concat (match-string 1 xinput) "-" (match-string 2 xinput))) ;; else (t (progn (setq xout (let ((xmonthAbbr [["January " "Jan. "] ["February " "Feb. "] ["March " "Mar. "] ["April " "Apr. "] ["May " "May. "] ["June " "Jun. "] ["July " "Jul. "] ["August " "Aug. "] ["September " "Sep. "] ["October " "Oct. "] ["November " "Nov. "] ["December " "Dec. "]] )) (with-temp-buffer (insert xinput) (mapc (lambda (x) (goto-char (point-min)) (while (search-forward (aref x 0) nil t) (replace-match (aref x 1) t t))) xmonthAbbr) (goto-char (point-min)) (while (search-forward "1st" nil t) (replace-match "1" t t)) (goto-char (point-min)) (while (search-forward "2nd" nil t) (replace-match "2" t t)) (goto-char (point-min)) (while (search-forward "3rd" nil t) (replace-match "3" t t)) (goto-char (point-min)) (while (search-forward "\\([0-9]\\)th" nil t) (replace-match "\\1" xinput)) (buffer-string)))) (let (xdateList xyear xmonth xdate xyyyy xmm xdd) (setq xdateList (parse-time-string xout) xyear (nth 5 xdateList) xmonth (nth 4 xdateList) xdate (nth 3 xdateList) xyyyy (if xyear (number-to-string xyear) "") xmm (if xmonth (format "%02d" xmonth) "") xdd (if xdate (format "%02d" xdate) "")) (concat xyyyy "-" xmm "-" xdd)))))) (delete-region xbeg xend) (insert xout)))
(defun xah-fix-datetime-string (Datetime) "Return a new string of Datetime in yyyy-mm-dd format. Other datetime info such as hours, minutes, time zone, are discarded. This function calls `xah-fix-datetime' to do work. URL `http://xahlee.info/emacs/emacs/elisp_datetime_parser.html' Version: 2020-09-08" (with-temp-buffer (insert Datetime) (xah-fix-datetime (point-min) (point-max)) (buffer-substring-no-properties (point-min) (point-max))))