diff options
| author | Paul Eggert | 2018-10-03 09:10:01 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-10-06 23:31:04 -0700 |
| commit | 3cc452327eff056f17637566aaf05a877e61d69a (patch) | |
| tree | e702e883dab66b2a63cf1b728c3bd7ca0faabd70 | |
| parent | 93fe420942c08111a6048af7c4d7807c61d80a09 (diff) | |
| download | emacs-3cc452327eff056f17637566aaf05a877e61d69a.tar.gz emacs-3cc452327eff056f17637566aaf05a877e61d69a.zip | |
Improvements on (TICKS . HZ)
This patch is in response to Eli's review (Bug#32902#10).
* src/systime.c: Doc strings of affected functions now refer
to format-time-string instead of to Lisp manual, and
format-time-string's doc string covers time values.
* test/src/systime-tests.el (format-time-string-with-zone):
Check decode-time too.
(decode-then-encode-time, time-arith-tests): New tests.
| -rw-r--r-- | doc/lispref/buffers.texi | 2 | ||||
| -rw-r--r-- | doc/lispref/os.texi | 14 | ||||
| -rw-r--r-- | src/timefns.c | 79 | ||||
| -rw-r--r-- | test/src/timefns-tests.el | 116 |
4 files changed, 140 insertions, 71 deletions
diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 8789a8d56f6..b2a4b0eab1a 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi | |||
| @@ -654,7 +654,7 @@ If the buffer has no recorded last modification time, this function | |||
| 654 | returns zero. This case occurs, for instance, if the buffer is not | 654 | returns zero. This case occurs, for instance, if the buffer is not |
| 655 | visiting a file or if the time has been explicitly cleared by | 655 | visiting a file or if the time has been explicitly cleared by |
| 656 | @code{clear-visited-file-modtime}. Note, however, that | 656 | @code{clear-visited-file-modtime}. Note, however, that |
| 657 | @code{visited-file-modtime} returns a list for some non-file buffers | 657 | @code{visited-file-modtime} returns a timestamp for some non-file buffers |
| 658 | too. For instance, in a Dired buffer listing a directory, it returns | 658 | too. For instance, in a Dired buffer listing a directory, it returns |
| 659 | the last modification time of that directory, as recorded by Dired. | 659 | the last modification time of that directory, as recorded by Dired. |
| 660 | 660 | ||
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index ea6915350e8..64c327c3809 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi | |||
| @@ -1457,14 +1457,14 @@ seconds east of Greenwich. | |||
| 1457 | @var{dow} and @var{utcoff}. | 1457 | @var{dow} and @var{utcoff}. |
| 1458 | @end defun | 1458 | @end defun |
| 1459 | 1459 | ||
| 1460 | @defun encode-time time &optional form | 1460 | @defun encode-time &optional time form &rest obsolescent-arguments |
| 1461 | This function converts @var{time} to a Lisp timestamp. | 1461 | This function converts @var{time} to a Lisp timestamp. |
| 1462 | It can act as the inverse of @code{decode-time}. | 1462 | It can act as the inverse of @code{decode-time}. |
| 1463 | 1463 | ||
| 1464 | The first argument can be a Lisp time value such as @code{nil} for the | 1464 | The first argument can be a time value such as a number of seconds, a |
| 1465 | current time, a number of seconds, a pair @code{(@var{ticks} | 1465 | pair @code{(@var{ticks} . @var{hz})}, a list @code{(@var{high} |
| 1466 | . @var{hz})}, or a list @code{(@var{high} @var{low} @var{micro} | 1466 | @var{low} @var{micro} @var{pico})}, or @code{nil} (the default) for |
| 1467 | @var{pico})} (@pxref{Time of Day}). It can also be a list | 1467 | the current time (@pxref{Time of Day}). It can also be a list |
| 1468 | @code{(@var{second} @var{minute} @var{hour} @var{day} @var{month} | 1468 | @code{(@var{second} @var{minute} @var{hour} @var{day} @var{month} |
| 1469 | @var{year} @var{ignored} @var{dst} @var{zone})} that specifies a | 1469 | @var{year} @var{ignored} @var{dst} @var{zone})} that specifies a |
| 1470 | decoded time in the style of @code{decode-time}, so that | 1470 | decoded time in the style of @code{decode-time}, so that |
| @@ -1494,10 +1494,10 @@ or more arguments. The first six arguments @var{second}, | |||
| 1494 | specify most of the components of a decoded time. If there are more | 1494 | specify most of the components of a decoded time. If there are more |
| 1495 | than six arguments the @emph{last} argument is used as @var{zone} and | 1495 | than six arguments the @emph{last} argument is used as @var{zone} and |
| 1496 | any other extra arguments are ignored, so that @code{(apply | 1496 | any other extra arguments are ignored, so that @code{(apply |
| 1497 | 'encode-time (decode-time ...))} works; otherwise @var{zone} defaults | 1497 | #\\='encode-time (decode-time ...))} works; otherwise @var{zone} defaults |
| 1498 | to the current time zone rule (@pxref{Time Zone Rules}). The decoded | 1498 | to the current time zone rule (@pxref{Time Zone Rules}). The decoded |
| 1499 | time's @var{dst} component is treated as if it was @minus{}1, and | 1499 | time's @var{dst} component is treated as if it was @minus{}1, and |
| 1500 | @var{form} so it takes its default value. | 1500 | @var{form} takes its default value. |
| 1501 | 1501 | ||
| 1502 | Year numbers less than 100 are not treated specially. If you want them | 1502 | Year numbers less than 100 are not treated specially. If you want them |
| 1503 | to stand for years above 1900, or years above 2000, you must alter them | 1503 | to stand for years above 1900, or years above 2000, you must alter them |
diff --git a/src/timefns.c b/src/timefns.c index 72cb54d3a0c..7bce3b1e500 100644 --- a/src/timefns.c +++ b/src/timefns.c | |||
| @@ -1035,8 +1035,8 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract) | |||
| 1035 | } | 1035 | } |
| 1036 | 1036 | ||
| 1037 | DEFUN ("time-add", Ftime_add, Stime_add, 2, 2, 0, | 1037 | DEFUN ("time-add", Ftime_add, Stime_add, 2, 2, 0, |
| 1038 | doc: /* Return the sum of two time values A and B, as a timestamp. | 1038 | doc: /* Return the sum of two time values A and B, as a time value. |
| 1039 | See Info node `(elisp)Time of Day' for time value formats. | 1039 | See `format-time-string' for the various forms of a time value. |
| 1040 | For example, nil stands for the current time. */) | 1040 | For example, nil stands for the current time. */) |
| 1041 | (Lisp_Object a, Lisp_Object b) | 1041 | (Lisp_Object a, Lisp_Object b) |
| 1042 | { | 1042 | { |
| @@ -1044,9 +1044,9 @@ For example, nil stands for the current time. */) | |||
| 1044 | } | 1044 | } |
| 1045 | 1045 | ||
| 1046 | DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0, | 1046 | DEFUN ("time-subtract", Ftime_subtract, Stime_subtract, 2, 2, 0, |
| 1047 | doc: /* Return the difference between two time values A and B, as a timestamp. | 1047 | doc: /* Return the difference between two time values A and B, as a time value. |
| 1048 | You can use `float-time' to convert the difference into elapsed seconds. | 1048 | You can use `float-time' to convert the difference into elapsed seconds. |
| 1049 | See Info node `(elisp)Time of Day' for time value formats. | 1049 | See `format-time-string' for the various forms of a time value. |
| 1050 | For example, nil stands for the current time. */) | 1050 | For example, nil stands for the current time. */) |
| 1051 | (Lisp_Object a, Lisp_Object b) | 1051 | (Lisp_Object a, Lisp_Object b) |
| 1052 | { | 1052 | { |
| @@ -1092,7 +1092,7 @@ time_cmp (Lisp_Object a, Lisp_Object b) | |||
| 1092 | 1092 | ||
| 1093 | DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0, | 1093 | DEFUN ("time-less-p", Ftime_less_p, Stime_less_p, 2, 2, 0, |
| 1094 | doc: /* Return non-nil if time value A is less than time value B. | 1094 | doc: /* Return non-nil if time value A is less than time value B. |
| 1095 | See Info node `(elisp)Time of Day' for time value formats. | 1095 | See `format-time-string' for the various forms of a time value. |
| 1096 | For example, nil stands for the current time. */) | 1096 | For example, nil stands for the current time. */) |
| 1097 | (Lisp_Object a, Lisp_Object b) | 1097 | (Lisp_Object a, Lisp_Object b) |
| 1098 | { | 1098 | { |
| @@ -1101,7 +1101,7 @@ For example, nil stands for the current time. */) | |||
| 1101 | 1101 | ||
| 1102 | DEFUN ("time-equal-p", Ftime_equal_p, Stime_equal_p, 2, 2, 0, | 1102 | DEFUN ("time-equal-p", Ftime_equal_p, Stime_equal_p, 2, 2, 0, |
| 1103 | doc: /* Return non-nil if A and B are equal time values. | 1103 | doc: /* Return non-nil if A and B are equal time values. |
| 1104 | See Info node `(elisp)Time of Day' for time value formats. */) | 1104 | See `format-time-string' for the various forms of a time value. */) |
| 1105 | (Lisp_Object a, Lisp_Object b) | 1105 | (Lisp_Object a, Lisp_Object b) |
| 1106 | { | 1106 | { |
| 1107 | return time_cmp (a, b) == 0 ? Qt : Qnil; | 1107 | return time_cmp (a, b) == 0 ? Qt : Qnil; |
| @@ -1110,12 +1110,12 @@ See Info node `(elisp)Time of Day' for time value formats. */) | |||
| 1110 | 1110 | ||
| 1111 | DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0, | 1111 | DEFUN ("float-time", Ffloat_time, Sfloat_time, 0, 1, 0, |
| 1112 | doc: /* Return the current time, as a float number of seconds since the epoch. | 1112 | doc: /* Return the current time, as a float number of seconds since the epoch. |
| 1113 | If SPECIFIED-TIME is given, it is a Lisp time value to convert to | 1113 | If SPECIFIED-TIME is given, it is a time value to convert to float |
| 1114 | float instead of the current time. See Info node `(elisp)Time of Day' | 1114 | instead of the current time. See `format-time-string' for the various |
| 1115 | for time value formats. | 1115 | forms of a time value. |
| 1116 | 1116 | ||
| 1117 | WARNING: Since the result is floating point, it may not be exact. | 1117 | WARNING: Since the result is floating point, it may not be exact. |
| 1118 | If precise time stamps are required, use either `current-time', | 1118 | If precise time stamps are required, use either `encode-time', |
| 1119 | or (if you need time as a string) `format-time-string'. */) | 1119 | or (if you need time as a string) `format-time-string'. */) |
| 1120 | (Lisp_Object specified_time) | 1120 | (Lisp_Object specified_time) |
| 1121 | { | 1121 | { |
| @@ -1226,8 +1226,12 @@ format_time_string (char const *format, ptrdiff_t formatlen, | |||
| 1226 | } | 1226 | } |
| 1227 | 1227 | ||
| 1228 | DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0, | 1228 | DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0, |
| 1229 | doc: /* Use FORMAT-STRING to format the time TIME, or now if omitted or nil. | 1229 | doc: /* Use FORMAT-STRING to format the time value TIME. |
| 1230 | TIME is a Lisp time value; see Info node `(elisp)Time of Day'. | 1230 | A time value that is omitted or nil stands for the current time, |
| 1231 | a number stands for that many seconds, an integer pair (TICKS . HZ) | ||
| 1232 | stands for TICKS/HZ seconds, and an integer list (HI LO US PS) stands | ||
| 1233 | for HI*2**16 + LO + US/10**6 + PS/10**12 seconds. This function | ||
| 1234 | treats seconds as time since the epoch of 1970-01-01 00:00:00 UTC. | ||
| 1231 | 1235 | ||
| 1232 | The optional ZONE is omitted or nil for Emacs local time, t for | 1236 | The optional ZONE is omitted or nil for Emacs local time, t for |
| 1233 | Universal Time, `wall' for system wall clock time, or a string as in | 1237 | Universal Time, `wall' for system wall clock time, or a string as in |
| @@ -1300,8 +1304,8 @@ usage: (format-time-string FORMAT-STRING &optional TIME ZONE) */) | |||
| 1300 | 1304 | ||
| 1301 | DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0, | 1305 | DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0, |
| 1302 | doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF). | 1306 | doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF). |
| 1303 | The optional TIME is the Lisp time value to convert. See Info node | 1307 | The optional TIME is the time value to convert. See |
| 1304 | `(elisp)Time of Day' for time value formats. | 1308 | `format-time-string' for the various forms of a time value. |
| 1305 | 1309 | ||
| 1306 | The optional ZONE is omitted or nil for Emacs local time, t for | 1310 | The optional ZONE is omitted or nil for Emacs local time, t for |
| 1307 | Universal Time, `wall' for system wall clock time, or a string as in | 1311 | Universal Time, `wall' for system wall clock time, or a string as in |
| @@ -1381,22 +1385,23 @@ check_tm_member (Lisp_Object obj, int offset) | |||
| 1381 | } | 1385 | } |
| 1382 | 1386 | ||
| 1383 | DEFUN ("encode-time", Fencode_time, Sencode_time, 1, MANY, 0, | 1387 | DEFUN ("encode-time", Fencode_time, Sencode_time, 1, MANY, 0, |
| 1384 | doc: /* Convert TIME to a timestamp. | 1388 | doc: /* Convert optional TIME to a timestamp. |
| 1385 | Optional FORM specifies how the returned value should be encoded. | 1389 | Optional FORM specifies how the returned value should be encoded. |
| 1386 | This can act as the reverse operation of `decode-time', which see. | 1390 | This can act as the reverse operation of `decode-time', which see. |
| 1387 | 1391 | ||
| 1388 | If TIME is a list (SECOND MINUTE HOUR DAY MONTH YEAR IGNORED DST ZONE) | 1392 | If TIME is a list (SECOND MINUTE HOUR DAY MONTH YEAR IGNORED DST ZONE) |
| 1389 | it a decoded time in the style of `decode-time', so that (encode-time | 1393 | it is a decoded time in the style of `decode-time', so that (encode-time |
| 1390 | (decode-time ...)) works. TIME can also be a Lisp time value; see | 1394 | (decode-time ...)) works. TIME can also be a time value. |
| 1391 | Info node `(elisp)Time of Day'. | 1395 | See `format-time-string' for the various forms of a time value. |
| 1396 | For example, an omitted TIME stands for the current time. | ||
| 1392 | 1397 | ||
| 1393 | If FORM is a positive integer, the time is returned as a pair of | 1398 | If FORM is a positive integer, the time is returned as a pair of |
| 1394 | integers (TICKS . FORM), where TICKS is the number of clock ticks and FORM | 1399 | integers (TICKS . FORM), where TICKS is the number of clock ticks and FORM |
| 1395 | is the clock frequency in ticks per second. (Currently the positive | 1400 | is the clock frequency in ticks per second. (Currently the positive |
| 1396 | integer should be at least 65536 if the returned value is expected to | 1401 | integer should be at least 65536 if the returned value is expected to |
| 1397 | be given to standard functions expecting Lisp timestamps.) If FORM is | 1402 | be given to standard functions expecting Lisp timestamps.) If FORM is |
| 1398 | t, the time is returned as (TICKS . PHZ), where PHZ is a | 1403 | t, the time is returned as (TICKS . PHZ), where PHZ is a platform dependent |
| 1399 | platform-dependent clock frequency. If FORM is `integer', the time is | 1404 | clock frequency in ticks per second. If FORM is `integer', the time is |
| 1400 | returned as an integer count of seconds. If FORM is `list', the time is | 1405 | returned as an integer count of seconds. If FORM is `list', the time is |
| 1401 | returned as an integer list (HIGH LOW USEC PSEC), where HIGH has the | 1406 | returned as an integer list (HIGH LOW USEC PSEC), where HIGH has the |
| 1402 | most significant bits of the seconds, LOW has the least significant 16 | 1407 | most significant bits of the seconds, LOW has the least significant 16 |
| @@ -1405,11 +1410,12 @@ Returned values are rounded toward minus infinity. Although an | |||
| 1405 | omitted or nil FORM currently acts like `list', this is planned to | 1410 | omitted or nil FORM currently acts like `list', this is planned to |
| 1406 | change, so callers requiring list timestamps should specify `list'. | 1411 | change, so callers requiring list timestamps should specify `list'. |
| 1407 | 1412 | ||
| 1408 | As an obsolescent calling convention, the first 6 arguments SECOND, | 1413 | As an obsolescent calling convention, if this function is called with |
| 1409 | MINUTE, HOUR, DAY, MONTH, and YEAR specify the components of a decoded | 1414 | 6 or more arguments, the first 6 arguments are SECOND, MINUTE, HOUR, |
| 1410 | time, where DST assumed to be -1 and FORM is omitted. If there are more | 1415 | DAY, MONTH, and YEAR, and specify the components of a decoded time, |
| 1416 | where DST assumed to be -1 and FORM is omitted. If there are more | ||
| 1411 | than 6 arguments the *last* argument is used as ZONE and any other | 1417 | than 6 arguments the *last* argument is used as ZONE and any other |
| 1412 | extra arguments are ignored, so that (apply \\='encode-time | 1418 | extra arguments are ignored, so that (apply #\\='encode-time |
| 1413 | (decode-time ...)) works; otherwise ZONE is assumed to be nil. | 1419 | (decode-time ...)) works; otherwise ZONE is assumed to be nil. |
| 1414 | 1420 | ||
| 1415 | If the input is a decoded time, ZONE is nil for Emacs local time, t | 1421 | If the input is a decoded time, ZONE is nil for Emacs local time, t |
| @@ -1430,7 +1436,7 @@ If you want them to stand for years in this century, you must do that yourself. | |||
| 1430 | Years before 1970 are not guaranteed to work. On some systems, | 1436 | Years before 1970 are not guaranteed to work. On some systems, |
| 1431 | year values as low as 1901 do work. | 1437 | year values as low as 1901 do work. |
| 1432 | 1438 | ||
| 1433 | usage: (encode-time TIME &optional FORM) */) | 1439 | usage: (encode-time &optional TIME FORM &rest OBSOLESCENT-ARGUMENTS) */) |
| 1434 | (ptrdiff_t nargs, Lisp_Object *args) | 1440 | (ptrdiff_t nargs, Lisp_Object *args) |
| 1435 | { | 1441 | { |
| 1436 | time_t value; | 1442 | time_t value; |
| @@ -1490,13 +1496,13 @@ usage: (encode-time TIME &optional FORM) */) | |||
| 1490 | } | 1496 | } |
| 1491 | 1497 | ||
| 1492 | DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0, | 1498 | DEFUN ("current-time", Fcurrent_time, Scurrent_time, 0, 0, 0, |
| 1493 | doc: /* Return the current time, counting the number of seconds since the epoch. | 1499 | doc: /* Return the current time, as the number of seconds since 1970-01-01 00:00:00. |
| 1494 | 1500 | The time is returned as a list of integers (HIGH LOW USEC PSEC). | |
| 1495 | See Info node `(elisp)Time of Day' for the format of the returned | 1501 | HIGH has the most significant bits of the seconds, while LOW has the |
| 1496 | timestamp. Although this is currently list format, it may change in | 1502 | least significant 16 bits. USEC and PSEC are the microsecond and |
| 1497 | future versions of Emacs. Use `encode-time' if you need a particular | 1503 | picosecond counts. Use `encode-time' if you need a particular |
| 1498 | form; for example, (encode-time nil \\='list) returns the current time | 1504 | timestamp form; for example, (encode-time nil \\='integer) returns the |
| 1499 | in list form. */) | 1505 | current time in seconds. */) |
| 1500 | (void) | 1506 | (void) |
| 1501 | { | 1507 | { |
| 1502 | return make_lisp_time (current_timespec ()); | 1508 | return make_lisp_time (current_timespec ()); |
| @@ -1512,9 +1518,9 @@ The format is `Sun Sep 16 01:03:52 1973'. | |||
| 1512 | However, see also the functions `decode-time' and `format-time-string' | 1518 | However, see also the functions `decode-time' and `format-time-string' |
| 1513 | which provide a much more powerful and general facility. | 1519 | which provide a much more powerful and general facility. |
| 1514 | 1520 | ||
| 1515 | If SPECIFIED-TIME is given, it is the Lisp time value to format | 1521 | If SPECIFIED-TIME is given, it is the time value to format instead of |
| 1516 | instead of the current time. See Info node `(elisp)Time of Day' for | 1522 | the current time. See `format-time-string' for the various forms of a |
| 1517 | time value formats. | 1523 | time value. |
| 1518 | 1524 | ||
| 1519 | The optional ZONE is omitted or nil for Emacs local time, t for | 1525 | The optional ZONE is omitted or nil for Emacs local time, t for |
| 1520 | Universal Time, `wall' for system wall clock time, or a string as in | 1526 | Universal Time, `wall' for system wall clock time, or a string as in |
| @@ -1559,7 +1565,8 @@ OFFSET is an integer number of seconds ahead of UTC (east of Greenwich). | |||
| 1559 | NAME is a string giving the name of the time zone. | 1565 | NAME is a string giving the name of the time zone. |
| 1560 | If SPECIFIED-TIME is given, the time zone offset is determined from it | 1566 | If SPECIFIED-TIME is given, the time zone offset is determined from it |
| 1561 | instead of using the current time. The argument should be a Lisp | 1567 | instead of using the current time. The argument should be a Lisp |
| 1562 | time value; see Info node `(elisp)Time of Day'. | 1568 | time value; see `format-time-string' for the various forms of a time |
| 1569 | value. | ||
| 1563 | 1570 | ||
| 1564 | The optional ZONE is omitted or nil for Emacs local time, t for | 1571 | The optional ZONE is omitted or nil for Emacs local time, t for |
| 1565 | Universal Time, `wall' for system wall clock time, or a string as in | 1572 | Universal Time, `wall' for system wall clock time, or a string as in |
diff --git a/test/src/timefns-tests.el b/test/src/timefns-tests.el index 435dcf7db70..ebeb43de163 100644 --- a/test/src/timefns-tests.el +++ b/test/src/timefns-tests.el | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | (require 'ert) | 20 | (require 'ert) |
| 21 | 21 | ||
| 22 | ;;; Check format-time-string with various TZ settings. | 22 | ;;; Check format-time-string and decode-time with various TZ settings. |
| 23 | ;;; Use only POSIX-compatible TZ values, since the tests should work | 23 | ;;; Use only POSIX-compatible TZ values, since the tests should work |
| 24 | ;;; even if tzdb is not in use. | 24 | ;;; even if tzdb is not in use. |
| 25 | (ert-deftest format-time-string-with-zone () | 25 | (ert-deftest format-time-string-with-zone () |
| @@ -35,32 +35,61 @@ | |||
| 35 | ;; Similarly, stick to the limited set of time zones that are | 35 | ;; Similarly, stick to the limited set of time zones that are |
| 36 | ;; supported by both POSIX and MS-Windows: exactly 3 ASCII letters | 36 | ;; supported by both POSIX and MS-Windows: exactly 3 ASCII letters |
| 37 | ;; in the abbreviation, and no DST. | 37 | ;; in the abbreviation, and no DST. |
| 38 | (let ((look '(1202 22527 999999 999999)) | 38 | (let ((format "%Y-%m-%d %H:%M:%S.%3N %z (%Z)")) |
| 39 | (format "%Y-%m-%d %H:%M:%S.%3N %z (%Z)")) | 39 | (dolist (look '((1202 22527 999999 999999) |
| 40 | ;; UTC. | 40 | (7879679999900 . 100000) |
| 41 | (should (string-equal | 41 | (78796799999999999999 . 1000000000000))) |
| 42 | (format-time-string "%Y-%m-%d %H:%M:%S.%3N %z" look t) | 42 | ;; UTC. |
| 43 | "1972-06-30 23:59:59.999 +0000")) | 43 | (should (string-equal |
| 44 | ;; "UTC0". | 44 | (format-time-string "%Y-%m-%d %H:%M:%S.%3N %z" look t) |
| 45 | (should (string-equal | 45 | "1972-06-30 23:59:59.999 +0000")) |
| 46 | (format-time-string format look "UTC0") | 46 | (should (equal (decode-time look t) |
| 47 | "1972-06-30 23:59:59.999 +0000 (UTC)")) | 47 | '(59 59 23 30 6 1972 5 nil 0))) |
| 48 | ;; Negative UTC offset, as a Lisp list. | 48 | ;; "UTC0". |
| 49 | (should (string-equal | 49 | (should (string-equal |
| 50 | (format-time-string format look '(-28800 "PST")) | 50 | (format-time-string format look "UTC0") |
| 51 | "1972-06-30 15:59:59.999 -0800 (PST)")) | 51 | "1972-06-30 23:59:59.999 +0000 (UTC)")) |
| 52 | ;; Negative UTC offset, as a Lisp integer. | 52 | (should (equal (decode-time look "UTC0") |
| 53 | (should (string-equal | 53 | '(59 59 23 30 6 1972 5 nil 0))) |
| 54 | (format-time-string format look -28800) | 54 | ;; Negative UTC offset, as a Lisp list. |
| 55 | ;; MS-Windows build replaces unrecognizable TZ values, | 55 | (should (string-equal |
| 56 | ;; such as "-08", with "ZZZ". | 56 | (format-time-string format look '(-28800 "PST")) |
| 57 | (if (eq system-type 'windows-nt) | 57 | "1972-06-30 15:59:59.999 -0800 (PST)")) |
| 58 | "1972-06-30 15:59:59.999 -0800 (ZZZ)" | 58 | (should (equal (decode-time look '(-28800 "PST")) |
| 59 | "1972-06-30 15:59:59.999 -0800 (-08)"))) | 59 | '(59 59 15 30 6 1972 5 nil -28800))) |
| 60 | ;; Positive UTC offset that is not an hour multiple, as a string. | 60 | ;; Negative UTC offset, as a Lisp integer. |
| 61 | (should (string-equal | 61 | (should (string-equal |
| 62 | (format-time-string format look "IST-5:30") | 62 | (format-time-string format look -28800) |
| 63 | "1972-07-01 05:29:59.999 +0530 (IST)")))) | 63 | ;; MS-Windows build replaces unrecognizable TZ values, |
| 64 | ;; such as "-08", with "ZZZ". | ||
| 65 | (if (eq system-type 'windows-nt) | ||
| 66 | "1972-06-30 15:59:59.999 -0800 (ZZZ)" | ||
| 67 | "1972-06-30 15:59:59.999 -0800 (-08)"))) | ||
| 68 | (should (equal (decode-time look -28800) | ||
| 69 | '(59 59 15 30 6 1972 5 nil -28800))) | ||
| 70 | ;; Positive UTC offset that is not an hour multiple, as a string. | ||
| 71 | (should (string-equal | ||
| 72 | (format-time-string format look "IST-5:30") | ||
| 73 | "1972-07-01 05:29:59.999 +0530 (IST)")) | ||
| 74 | (should (equal (decode-time look "IST-5:30") | ||
| 75 | '(59 29 5 1 7 1972 6 nil 19800)))))) | ||
| 76 | |||
| 77 | (ert-deftest decode-then-encode-time () | ||
| 78 | (let ((time-values (list 0 -2 1 0.0 -0.0 -2.0 1.0 | ||
| 79 | most-negative-fixnum most-positive-fixnum | ||
| 80 | (1- most-negative-fixnum) | ||
| 81 | (1+ most-positive-fixnum) | ||
| 82 | 1e+INF -1e+INF 1e+NaN -1e+NaN | ||
| 83 | '(0 1 0 0) '(1 0 0 0) '(-1 0 0 0) | ||
| 84 | '(123456789000000 . 1000000) | ||
| 85 | (cons (1+ most-positive-fixnum) 1000000000000) | ||
| 86 | (cons 1000000000000 (1+ most-positive-fixnum))))) | ||
| 87 | (dolist (a time-values) | ||
| 88 | (let* ((d (ignore-errors (decode-time a t))) | ||
| 89 | (e (encode-time d)) | ||
| 90 | (diff (float-time (time-subtract a e)))) | ||
| 91 | (should (or (not d) | ||
| 92 | (and (<= 0 diff) (< diff 1)))))))) | ||
| 64 | 93 | ||
| 65 | ;;; This should not dump core. | 94 | ;;; This should not dump core. |
| 66 | (ert-deftest format-time-string-with-outlandish-zone () | 95 | (ert-deftest format-time-string-with-outlandish-zone () |
| @@ -80,3 +109,36 @@ | |||
| 80 | 109 | ||
| 81 | (ert-deftest time-equal-p-nil-nil () | 110 | (ert-deftest time-equal-p-nil-nil () |
| 82 | (should (time-equal-p nil nil))) | 111 | (should (time-equal-p nil nil))) |
| 112 | |||
| 113 | (ert-deftest time-arith-tests () | ||
| 114 | (let ((time-values (list 0 -1 1 0.0 -0.0 -1.0 1.0 | ||
| 115 | most-negative-fixnum most-positive-fixnum | ||
| 116 | (1- most-negative-fixnum) | ||
| 117 | (1+ most-positive-fixnum) | ||
| 118 | 1e+INF -1e+INF 1e+NaN -1e+NaN | ||
| 119 | '(0 0 0 1) '(0 0 1 0) '(0 1 0 0) '(1 0 0 0) | ||
| 120 | '(-1 0 0 0) '(1 2 3 4) '(-1 2 3 4) | ||
| 121 | '(-123456789 . 100000) '(123456789 . 1000000) | ||
| 122 | (cons (1+ most-positive-fixnum) 1000000000000) | ||
| 123 | (cons 1000000000000 (1+ most-positive-fixnum))))) | ||
| 124 | (dolist (a time-values) | ||
| 125 | (dolist (b time-values) | ||
| 126 | (let ((aa (time-subtract (time-add a b) b))) | ||
| 127 | (should (or (time-equal-p a aa) (and (floatp aa) (isnan aa))))) | ||
| 128 | (should (= 1 (+ (if (time-less-p a b) 1 0) | ||
| 129 | (if (time-equal-p a b) 1 0) | ||
| 130 | (if (time-less-p b a) 1 0) | ||
| 131 | (if (or (and (floatp a) (isnan a)) | ||
| 132 | (and (floatp b) (isnan b))) | ||
| 133 | 1 0)))) | ||
| 134 | (should (or (not (time-less-p 0 b)) | ||
| 135 | (time-less-p a (time-add a b)) | ||
| 136 | (time-equal-p a (time-add a b)) | ||
| 137 | (and (floatp (time-add a b)) (isnan (time-add a b))))) | ||
| 138 | (let ((x (float-time (time-add a b))) | ||
| 139 | (y (+ (float-time a) (float-time b)))) | ||
| 140 | (should (or (and (isnan x) (isnan y)) | ||
| 141 | (= x y) | ||
| 142 | (< 0.99 (/ x y) 1.01) | ||
| 143 | (< 0.99 (/ (- (float-time a)) (float-time b)) | ||
| 144 | 1.01)))))))) | ||