diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 110ef8549..3495e6eed 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -196,6 +196,8 @@ a #+BEGIN_FOO/#+END_FOO block. Bound to C-c C-x w by default. See docstring for details. +*** ~org-timestamp-from-string~ +*** ~org-timestamp-from-time~ *** ~org-attach-dired-to-subtree~ See docstring for details. diff --git a/lisp/org.el b/lisp/org.el index bbdc619d9..1207eea59 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -22515,12 +22515,40 @@ Call `org-toggle-comment' if on a heading, otherwise call ;;; Timestamps API -;; This section contains tools to operate on timestamp objects, as -;; returned by, e.g. `org-element-context'. +;; This section contains tools to operate on, or create, timestamp +;; objects, as returned by, e.g. `org-element-context'. + +(defun org-timestamp-from-string (s) + "Convert Org timestamp S, as a string, into a timestamp object. +Return nil if S is not a valid timestamp string." + (when (org-string-nw-p s) + (with-temp-buffer + (save-excursion (insert s)) + (org-element-timestamp-parser)))) + +(defun org-timestamp-from-time (time &optional with-time inactive) + "Convert a time value into a timestamp object. + +TIME is an Emacs internal time representation, as returned, e.g., +by `current-time'. + +When optional argument WITH-TIME is non-nil, return a + +Return an inactive timestamp if INACTIVE is non-nil. Otherwise, +return an active timestamp." + (pcase-let ((`(,_ ,minute ,hour ,day ,month ,year . ,_) (decode-time time))) + (org-element-create 'timestamp + (list :type (if inactive 'inactive 'active) + :year-start year + :month-start month + :day-start day + :hour-start (and with-time hour) + :minute-start (and with-time minute))))) (defun org-timestamp--to-internal-time (timestamp &optional end) "Encode TIMESTAMP object into Emacs internal time. -Use end of date range or time range when END is non-nil." +Use end of date range or time range when END is non-nil. +Otherwise, use its start." (apply #'encode-time (cons 0 (mapcar diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 86828d7c5..ab618f012 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -6469,6 +6469,47 @@ CLOCK: [2012-03-29 Thu 10:00]--[2012-03-29 Thu 16:40] => 6:40" (org-time-stamp-custom-formats '("<%d>" . "<%d>"))) (org-timestamp-translate (org-element-context))))))) +(ert-deftest test-org/timestamp-from-string () + "Test `org-timestamp-from-string' specifications." + ;; Return nil if argument is not a valid Org timestamp. + (should-not (org-timestamp-from-string "")) + (should-not (org-timestamp-from-string nil)) + (should-not (org-timestamp-from-string "<2012-03-29")) + ;; Otherwise, return a valid Org timestamp object. + (should + (equal "<2012-03-29 Thu>" + (let ((system-time-locale "en_US")) + (org-element-interpret-data + (org-timestamp-from-string "<2012-03-29 Thu>"))))) + (should + (equal "[2014-03-04 Tue]" + (let ((system-time-locale "en_US")) + (org-element-interpret-data + (org-timestamp-from-string "[2014-03-04 Tue]")))))) + +(ert-deftest test-org/timestamp-from-time () + "Test `org-timestamp-from-time' specifications." + ;; Standard test. + (should + (equal "<2012-03-29 Thu>" + (let ((system-time-locale "en_US")) + (org-element-interpret-data + (org-timestamp-from-time '(20339 35296)))))) + ;; When optional argument WITH-TIME is non-nil, provide time + ;; information. + (should + (equal "<2012-03-29 Thu 16:40>" + (let ((system-time-locale "en_US")) + (org-element-interpret-data + (org-timestamp-from-time '(20340 29760) t))))) + ;; When optional argument INACTIVE is non-nil, return an inactive + ;; timestamp. + (should + (equal "[2012-03-29 Thu]" + (let ((system-time-locale "en_US")) + (org-element-interpret-data + (org-timestamp-from-time '(20339 35296) nil t)))))) + ;;; Visibility