diff options
-rw-r--r-- | etc/NEWS | 13 | ||||
-rw-r--r-- | lisp/time-stamp.el | 43 | ||||
-rw-r--r-- | test/lisp/time-stamp-tests.el | 25 |
3 files changed, 58 insertions, 23 deletions
@@ -2248,7 +2248,18 @@ and 'gravatar-force-default'. *** The built-in ada-mode is now deleted. The GNU ELPA package is a good replacement, even in very large source files. -** Some conversions recommended for 'time-stamp-format' have changed. +** time-stamp + +*** New '%5z' conversion for 'time-stamp-format' gives time zone offset. +Specifying '%5z' in 'time-stamp-format' or 'time-stamp-pattern' +expands to the time zone offset, e.g., '+0100'. The time zone used is +specified by 'time-stamp-time-zone'. + +Because this feature is new in Emacs 27.1, do not use it in the local +variables section of any file that might be edited by an older version +of Emacs. + +*** Some conversions recommended for 'time-stamp-format' have changed. The new documented/recommended %-conversions are closer to those used by 'format-time-string' and are compatible at least as far back as Emacs 22.1 (released in 2007). diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el index 55892cdb83c..4a6b203ccc5 100644 --- a/lisp/time-stamp.el +++ b/lisp/time-stamp.el @@ -62,7 +62,8 @@ on the locale setting recorded in `system-time-locale' and %02S seconds %w day number of week, Sunday is 0 %02y 2-digit year: `03' %Y 4-digit year: `2003' -%#Z lowercase time zone name: `est' %Z gives uppercase: `EST' +%Z time zone name: `EST' %#Z gives lowercase: `est' +%5z time zone offset: `-0500' (since Emacs 27; see note below) Non-date items: %% a literal percent character: `%' @@ -81,7 +82,10 @@ use \"%3a %3b %2d %02H:%02M:%02S %Z %Y\". The default padding of some formats has changed to be more compatible with format-time-string. To be compatible with older versions of Emacs, specify a padding width (as shown) or use the : modifier to request the -transitional behavior (again, as shown)." +transitional behavior (again, as shown). + +The behavior of `%5z' is new in Emacs 27. If your files might be +edited by older versions of Emacs also, do not use this format yet." :type 'string :group 'time-stamp :version "27.1") @@ -469,7 +473,7 @@ and all `time-stamp-format' compatibility." (cond ((eq cur-char ?%) ;; eat any additional args to allow for future expansion - (setq alt-form nil change-case nil upcase nil field-width "") + (setq alt-form 0 change-case nil upcase nil field-width "") (while (progn (setq ind (1+ ind)) (setq cur-char (if (< ind fmt-len) @@ -503,7 +507,7 @@ and all `time-stamp-format' compatibility." (setq prev-char cur-char) ;; some characters we actually use (cond ((eq cur-char ?:) - (setq alt-form t)) + (setq alt-form (1+ alt-form))) ((eq cur-char ?#) (setq change-case t)) ((eq cur-char ?^) @@ -517,7 +521,7 @@ and all `time-stamp-format' compatibility." ((eq cur-char ?%) "%") ((eq cur-char ?a) ;day of week - (if alt-form + (if (> alt-form 0) (if (string-equal field-width "") (time-stamp--format "%A" time) "") ;discourage "%:3a" @@ -529,7 +533,7 @@ and all `time-stamp-format' compatibility." (time-stamp--format "%#A" time) (time-stamp--format "%A" time))) ((eq cur-char ?b) ;month name - (if alt-form + (if (> alt-form 0) (if (string-equal field-width "") (time-stamp--format "%B" time) "") ;discourage "%:3b" @@ -561,7 +565,7 @@ and all `time-stamp-format' compatibility." ((eq cur-char ?w) ;weekday number, Sunday is 0 (time-stamp--format "%w" time)) ((eq cur-char ?y) ;year - (if alt-form + (if (> alt-form 0) (string-to-number (time-stamp--format "%Y" time)) (if (or (string-equal field-width "") (<= (string-to-number field-width) 2)) @@ -573,9 +577,24 @@ and all `time-stamp-format' compatibility." ((eq cur-char ?z) ;time zone offset (if change-case "" ;discourage %z variations - (if alt-form - (time-stamp--format "%z" time) - (time-stamp--format "%#Z" time)))) ;backward compat, will change + (cond ((= alt-form 0) + (if (string-equal field-width "") + (progn + (time-stamp-conv-warn "%z" "%#Z") + (time-stamp--format "%#Z" time)) + (cond ((string-equal field-width "1") + (setq field-width "3")) ;%-z -> "+00" + ((string-equal field-width "2") + (setq field-width "5")) ;%_z -> "+0000" + ((string-equal field-width "4") + (setq field-width "0"))) ;discourage %4z + (time-stamp--format "%z" time))) + ((= alt-form 1) + (time-stamp--format "%:z" time)) + ((= alt-form 2) + (time-stamp--format "%::z" time)) + ((= alt-form 3) + (time-stamp--format "%:::z" time))))) ((eq cur-char ?Z) ;time zone name (if change-case (time-stamp--format "%#Z" time) @@ -608,7 +627,7 @@ and all `time-stamp-format' compatibility." (system-name)) )) (and (numberp field-result) - (not alt-form) + (= alt-form 0) (string-equal field-width "") ;; no width provided; set width for default (setq field-width "02")) @@ -637,7 +656,7 @@ and all `time-stamp-format' compatibility." ALT-FORM is whether `#' specified. FIELD-WIDTH is the string width specification or \"\". TIME is the time to convert." (let ((format-string (concat "%" (char-to-string format-char)))) - (if (and alt-form (not (string-equal field-width ""))) + (if (and (> alt-form 0) (not (string-equal field-width ""))) "" ;discourage "%:2d" and the like (string-to-number (time-stamp--format format-string time))))) diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el index 77cd6c5b945..ae8eaf467d9 100644 --- a/test/lisp/time-stamp-tests.el +++ b/test/lisp/time-stamp-tests.el @@ -312,19 +312,24 @@ (ert-deftest time-stamp-test-format-time-zone-offset () "Test time-stamp format %z." (with-time-stamp-test-env - ;; documented 1995-2019, will change - (should (equal (time-stamp-string "%z" ref-time1) - (format-time-string "%#Z" ref-time1 t))) - ;; undocumented, changed in 2019 - (should (equal (time-stamp-string "%:z" ref-time1) "+0000")) - (should (equal (time-stamp-string "%:7z" ref-time1) " +0000")) - (should (equal (time-stamp-string "%:07z" ref-time1) " +0000")) + (let ((utc-abbr (format-time-string "%#Z" ref-time1 t))) + ;; documented 1995-2019, warned since 2019, will change + (time-stamp-should-warn + (equal (time-stamp-string "%z" ref-time1) utc-abbr))) + ;; implemented and documented (with compat caveat) since 2019 + (should (equal (time-stamp-string "%5z" ref-time1) "+0000")) (let ((time-stamp-time-zone "PST8")) - (should (equal (time-stamp-string "%:z" ref-time1) "-0800"))) + (should (equal (time-stamp-string "%5z" ref-time1) "-0800"))) (let ((time-stamp-time-zone "HST10")) - (should (equal (time-stamp-string "%:z" ref-time1) "-1000"))) + (should (equal (time-stamp-string "%5z" ref-time1) "-1000"))) (let ((time-stamp-time-zone "CET-1")) - (should (equal (time-stamp-string "%:z" ref-time1) "+0100"))))) + (should (equal (time-stamp-string "%5z" ref-time1) "+0100"))) + ;; implemented since 2019, verify that these don't warn + (should (equal (time-stamp-string "%-z" ref-time1) "+00")) + (should (equal (time-stamp-string "%_z" ref-time1) "+0000")) + (should (equal (time-stamp-string "%:z" ref-time1) "+00:00")) + (should (equal (time-stamp-string "%::z" ref-time1) "+00:00:00")) + (should (equal (time-stamp-string "%:::z" ref-time1) "+00")))) (ert-deftest time-stamp-test-format-non-date-conversions () "Test time-stamp formats for non-date items." |