aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gildea2019-11-13 20:21:42 -0800
committerStephen Gildea2019-11-13 21:11:28 -0800
commit1d189843bb2a4f23dc269314d5e6dfb4f9fe801e (patch)
tree8d501f048c8739cd442e827324d947adbe941136
parent3ecbfefa7239bd071262db25dfc9c97a01ec9ca1 (diff)
downloademacs-1d189843bb2a4f23dc269314d5e6dfb4f9fe801e.tar.gz
emacs-1d189843bb2a4f23dc269314d5e6dfb4f9fe801e.zip
time-stamp: update support for time zone numeric offset
* time-stamp.el (time-stamp-string-preprocess): Change new format for numeric time zone from %:z to %5z to match format-time-string better. (time-stamp-format): Document support for numeric time zone. See discussion in bug#32931. * NEWS: Mention time-stamp-format %5z.
-rw-r--r--etc/NEWS13
-rw-r--r--lisp/time-stamp.el43
-rw-r--r--test/lisp/time-stamp-tests.el25
3 files changed, 58 insertions, 23 deletions
diff --git a/etc/NEWS b/etc/NEWS
index ff334493298..485d2b1fdf4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2248,7 +2248,18 @@ and 'gravatar-force-default'.
2248*** The built-in ada-mode is now deleted. The GNU ELPA package is a 2248*** The built-in ada-mode is now deleted. The GNU ELPA package is a
2249good replacement, even in very large source files. 2249good replacement, even in very large source files.
2250 2250
2251** Some conversions recommended for 'time-stamp-format' have changed. 2251** time-stamp
2252
2253*** New '%5z' conversion for 'time-stamp-format' gives time zone offset.
2254Specifying '%5z' in 'time-stamp-format' or 'time-stamp-pattern'
2255expands to the time zone offset, e.g., '+0100'. The time zone used is
2256specified by 'time-stamp-time-zone'.
2257
2258Because this feature is new in Emacs 27.1, do not use it in the local
2259variables section of any file that might be edited by an older version
2260of Emacs.
2261
2262*** Some conversions recommended for 'time-stamp-format' have changed.
2252The new documented/recommended %-conversions are closer to those 2263The new documented/recommended %-conversions are closer to those
2253used by 'format-time-string' and are compatible at least as far back 2264used by 'format-time-string' and are compatible at least as far back
2254as Emacs 22.1 (released in 2007). 2265as 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
62%02S seconds 62%02S seconds
63%w day number of week, Sunday is 0 63%w day number of week, Sunday is 0
64%02y 2-digit year: `03' %Y 4-digit year: `2003' 64%02y 2-digit year: `03' %Y 4-digit year: `2003'
65%#Z lowercase time zone name: `est' %Z gives uppercase: `EST' 65%Z time zone name: `EST' %#Z gives lowercase: `est'
66%5z time zone offset: `-0500' (since Emacs 27; see note below)
66 67
67Non-date items: 68Non-date items:
68%% a literal percent character: `%' 69%% a literal percent character: `%'
@@ -81,7 +82,10 @@ use \"%3a %3b %2d %02H:%02M:%02S %Z %Y\".
81The default padding of some formats has changed to be more compatible 82The default padding of some formats has changed to be more compatible
82with format-time-string. To be compatible with older versions of Emacs, 83with format-time-string. To be compatible with older versions of Emacs,
83specify a padding width (as shown) or use the : modifier to request the 84specify a padding width (as shown) or use the : modifier to request the
84transitional behavior (again, as shown)." 85transitional behavior (again, as shown).
86
87The behavior of `%5z' is new in Emacs 27. If your files might be
88edited by older versions of Emacs also, do not use this format yet."
85 :type 'string 89 :type 'string
86 :group 'time-stamp 90 :group 'time-stamp
87 :version "27.1") 91 :version "27.1")
@@ -469,7 +473,7 @@ and all `time-stamp-format' compatibility."
469 (cond 473 (cond
470 ((eq cur-char ?%) 474 ((eq cur-char ?%)
471 ;; eat any additional args to allow for future expansion 475 ;; eat any additional args to allow for future expansion
472 (setq alt-form nil change-case nil upcase nil field-width "") 476 (setq alt-form 0 change-case nil upcase nil field-width "")
473 (while (progn 477 (while (progn
474 (setq ind (1+ ind)) 478 (setq ind (1+ ind))
475 (setq cur-char (if (< ind fmt-len) 479 (setq cur-char (if (< ind fmt-len)
@@ -503,7 +507,7 @@ and all `time-stamp-format' compatibility."
503 (setq prev-char cur-char) 507 (setq prev-char cur-char)
504 ;; some characters we actually use 508 ;; some characters we actually use
505 (cond ((eq cur-char ?:) 509 (cond ((eq cur-char ?:)
506 (setq alt-form t)) 510 (setq alt-form (1+ alt-form)))
507 ((eq cur-char ?#) 511 ((eq cur-char ?#)
508 (setq change-case t)) 512 (setq change-case t))
509 ((eq cur-char ?^) 513 ((eq cur-char ?^)
@@ -517,7 +521,7 @@ and all `time-stamp-format' compatibility."
517 ((eq cur-char ?%) 521 ((eq cur-char ?%)
518 "%") 522 "%")
519 ((eq cur-char ?a) ;day of week 523 ((eq cur-char ?a) ;day of week
520 (if alt-form 524 (if (> alt-form 0)
521 (if (string-equal field-width "") 525 (if (string-equal field-width "")
522 (time-stamp--format "%A" time) 526 (time-stamp--format "%A" time)
523 "") ;discourage "%:3a" 527 "") ;discourage "%:3a"
@@ -529,7 +533,7 @@ and all `time-stamp-format' compatibility."
529 (time-stamp--format "%#A" time) 533 (time-stamp--format "%#A" time)
530 (time-stamp--format "%A" time))) 534 (time-stamp--format "%A" time)))
531 ((eq cur-char ?b) ;month name 535 ((eq cur-char ?b) ;month name
532 (if alt-form 536 (if (> alt-form 0)
533 (if (string-equal field-width "") 537 (if (string-equal field-width "")
534 (time-stamp--format "%B" time) 538 (time-stamp--format "%B" time)
535 "") ;discourage "%:3b" 539 "") ;discourage "%:3b"
@@ -561,7 +565,7 @@ and all `time-stamp-format' compatibility."
561 ((eq cur-char ?w) ;weekday number, Sunday is 0 565 ((eq cur-char ?w) ;weekday number, Sunday is 0
562 (time-stamp--format "%w" time)) 566 (time-stamp--format "%w" time))
563 ((eq cur-char ?y) ;year 567 ((eq cur-char ?y) ;year
564 (if alt-form 568 (if (> alt-form 0)
565 (string-to-number (time-stamp--format "%Y" time)) 569 (string-to-number (time-stamp--format "%Y" time))
566 (if (or (string-equal field-width "") 570 (if (or (string-equal field-width "")
567 (<= (string-to-number field-width) 2)) 571 (<= (string-to-number field-width) 2))
@@ -573,9 +577,24 @@ and all `time-stamp-format' compatibility."
573 ((eq cur-char ?z) ;time zone offset 577 ((eq cur-char ?z) ;time zone offset
574 (if change-case 578 (if change-case
575 "" ;discourage %z variations 579 "" ;discourage %z variations
576 (if alt-form 580 (cond ((= alt-form 0)
577 (time-stamp--format "%z" time) 581 (if (string-equal field-width "")
578 (time-stamp--format "%#Z" time)))) ;backward compat, will change 582 (progn
583 (time-stamp-conv-warn "%z" "%#Z")
584 (time-stamp--format "%#Z" time))
585 (cond ((string-equal field-width "1")
586 (setq field-width "3")) ;%-z -> "+00"
587 ((string-equal field-width "2")
588 (setq field-width "5")) ;%_z -> "+0000"
589 ((string-equal field-width "4")
590 (setq field-width "0"))) ;discourage %4z
591 (time-stamp--format "%z" time)))
592 ((= alt-form 1)
593 (time-stamp--format "%:z" time))
594 ((= alt-form 2)
595 (time-stamp--format "%::z" time))
596 ((= alt-form 3)
597 (time-stamp--format "%:::z" time)))))
579 ((eq cur-char ?Z) ;time zone name 598 ((eq cur-char ?Z) ;time zone name
580 (if change-case 599 (if change-case
581 (time-stamp--format "%#Z" time) 600 (time-stamp--format "%#Z" time)
@@ -608,7 +627,7 @@ and all `time-stamp-format' compatibility."
608 (system-name)) 627 (system-name))
609 )) 628 ))
610 (and (numberp field-result) 629 (and (numberp field-result)
611 (not alt-form) 630 (= alt-form 0)
612 (string-equal field-width "") 631 (string-equal field-width "")
613 ;; no width provided; set width for default 632 ;; no width provided; set width for default
614 (setq field-width "02")) 633 (setq field-width "02"))
@@ -637,7 +656,7 @@ and all `time-stamp-format' compatibility."
637ALT-FORM is whether `#' specified. FIELD-WIDTH is the string 656ALT-FORM is whether `#' specified. FIELD-WIDTH is the string
638width specification or \"\". TIME is the time to convert." 657width specification or \"\". TIME is the time to convert."
639 (let ((format-string (concat "%" (char-to-string format-char)))) 658 (let ((format-string (concat "%" (char-to-string format-char))))
640 (if (and alt-form (not (string-equal field-width ""))) 659 (if (and (> alt-form 0) (not (string-equal field-width "")))
641 "" ;discourage "%:2d" and the like 660 "" ;discourage "%:2d" and the like
642 (string-to-number (time-stamp--format format-string time))))) 661 (string-to-number (time-stamp--format format-string time)))))
643 662
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 @@
312(ert-deftest time-stamp-test-format-time-zone-offset () 312(ert-deftest time-stamp-test-format-time-zone-offset ()
313 "Test time-stamp format %z." 313 "Test time-stamp format %z."
314 (with-time-stamp-test-env 314 (with-time-stamp-test-env
315 ;; documented 1995-2019, will change 315 (let ((utc-abbr (format-time-string "%#Z" ref-time1 t)))
316 (should (equal (time-stamp-string "%z" ref-time1) 316 ;; documented 1995-2019, warned since 2019, will change
317 (format-time-string "%#Z" ref-time1 t))) 317 (time-stamp-should-warn
318 ;; undocumented, changed in 2019 318 (equal (time-stamp-string "%z" ref-time1) utc-abbr)))
319 (should (equal (time-stamp-string "%:z" ref-time1) "+0000")) 319 ;; implemented and documented (with compat caveat) since 2019
320 (should (equal (time-stamp-string "%:7z" ref-time1) " +0000")) 320 (should (equal (time-stamp-string "%5z" ref-time1) "+0000"))
321 (should (equal (time-stamp-string "%:07z" ref-time1) " +0000"))
322 (let ((time-stamp-time-zone "PST8")) 321 (let ((time-stamp-time-zone "PST8"))
323 (should (equal (time-stamp-string "%:z" ref-time1) "-0800"))) 322 (should (equal (time-stamp-string "%5z" ref-time1) "-0800")))
324 (let ((time-stamp-time-zone "HST10")) 323 (let ((time-stamp-time-zone "HST10"))
325 (should (equal (time-stamp-string "%:z" ref-time1) "-1000"))) 324 (should (equal (time-stamp-string "%5z" ref-time1) "-1000")))
326 (let ((time-stamp-time-zone "CET-1")) 325 (let ((time-stamp-time-zone "CET-1"))
327 (should (equal (time-stamp-string "%:z" ref-time1) "+0100"))))) 326 (should (equal (time-stamp-string "%5z" ref-time1) "+0100")))
327 ;; implemented since 2019, verify that these don't warn
328 (should (equal (time-stamp-string "%-z" ref-time1) "+00"))
329 (should (equal (time-stamp-string "%_z" ref-time1) "+0000"))
330 (should (equal (time-stamp-string "%:z" ref-time1) "+00:00"))
331 (should (equal (time-stamp-string "%::z" ref-time1) "+00:00:00"))
332 (should (equal (time-stamp-string "%:::z" ref-time1) "+00"))))
328 333
329(ert-deftest time-stamp-test-format-non-date-conversions () 334(ert-deftest time-stamp-test-format-non-date-conversions ()
330 "Test time-stamp formats for non-date items." 335 "Test time-stamp formats for non-date items."