diff options
| author | Stephen Gildea | 2019-11-13 20:21:42 -0800 |
|---|---|---|
| committer | Stephen Gildea | 2019-11-13 21:11:28 -0800 |
| commit | 1d189843bb2a4f23dc269314d5e6dfb4f9fe801e (patch) | |
| tree | 8d501f048c8739cd442e827324d947adbe941136 | |
| parent | 3ecbfefa7239bd071262db25dfc9c97a01ec9ca1 (diff) | |
| download | emacs-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/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'. | |||
| 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 |
| 2249 | good replacement, even in very large source files. | 2249 | good 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. | ||
| 2254 | Specifying '%5z' in 'time-stamp-format' or 'time-stamp-pattern' | ||
| 2255 | expands to the time zone offset, e.g., '+0100'. The time zone used is | ||
| 2256 | specified by 'time-stamp-time-zone'. | ||
| 2257 | |||
| 2258 | Because this feature is new in Emacs 27.1, do not use it in the local | ||
| 2259 | variables section of any file that might be edited by an older version | ||
| 2260 | of Emacs. | ||
| 2261 | |||
| 2262 | *** Some conversions recommended for 'time-stamp-format' have changed. | ||
| 2252 | The new documented/recommended %-conversions are closer to those | 2263 | The new documented/recommended %-conversions are closer to those |
| 2253 | used by 'format-time-string' and are compatible at least as far back | 2264 | used by 'format-time-string' and are compatible at least as far back |
| 2254 | as Emacs 22.1 (released in 2007). | 2265 | 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 | |||
| 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 | ||
| 67 | Non-date items: | 68 | Non-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\". | |||
| 81 | The default padding of some formats has changed to be more compatible | 82 | The default padding of some formats has changed to be more compatible |
| 82 | with format-time-string. To be compatible with older versions of Emacs, | 83 | with format-time-string. To be compatible with older versions of Emacs, |
| 83 | specify a padding width (as shown) or use the : modifier to request the | 84 | specify a padding width (as shown) or use the : modifier to request the |
| 84 | transitional behavior (again, as shown)." | 85 | transitional behavior (again, as shown). |
| 86 | |||
| 87 | The behavior of `%5z' is new in Emacs 27. If your files might be | ||
| 88 | edited 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." | |||
| 637 | ALT-FORM is whether `#' specified. FIELD-WIDTH is the string | 656 | ALT-FORM is whether `#' specified. FIELD-WIDTH is the string |
| 638 | width specification or \"\". TIME is the time to convert." | 657 | width 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." |