diff options
| author | Paul Eggert | 2019-08-16 22:09:04 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-08-16 23:25:07 -0700 |
| commit | 37257d6acadff17bd1e52cfa460950bcb684c5c3 (patch) | |
| tree | ab7088cfa725561c8456f388cff79466948b3532 /src | |
| parent | d7c9ed8445d13de7350be3360d68717362f89929 (diff) | |
| download | emacs-37257d6acadff17bd1e52cfa460950bcb684c5c3.tar.gz emacs-37257d6acadff17bd1e52cfa460950bcb684c5c3.zip | |
More-compatible subsecond calendrical timestamps
Instead of appending a subseconds member to the result of
‘decode-time’, this keeps the format unchanged unless you give
a new optional argument to ‘decode-time’. Also, the augmented
format now puts the subsecond info in the SECONDS element, so
the total number of elements is unchanged; this is more
compatible with code that expects the traditional 9 elements,
such as ‘(pcase decoded-time (`(,SEC ,MIN ,HOUR ,DAY ,MON
,YEAR ,DOW ,DST ,ZONE) ...) ...)’.
* doc/lispref/os.texi, doc/misc/emacs-mime.texi, etc/NEWS:
* lisp/net/soap-client.el (soap-decode-date-time):
* lisp/simple.el (decoded-time):
Document the new behavior.
* lisp/calendar/icalendar.el (icalendar--decode-isodatetime):
* lisp/calendar/iso8601.el (iso8601-parse)
(iso8601-parse-time, iso8601-parse-duration)
(iso8601--decoded-time):
* lisp/calendar/parse-time.el (parse-time-string):
* lisp/calendar/time-date.el (decoded-time-add)
(decoded-time--alter-second):
* lisp/org/org.el (org-parse-time-string):
* lisp/simple.el (decoded-time):
* src/timefns.c (Fdecode_time, Fencode_time):
* test/lisp/calendar/icalendar-tests.el:
(icalendar--decode-isodatetime):
* test/lisp/calendar/iso8601-tests.el (test-iso8601-date-years)
(test-iso8601-date-dates, test-iso8601-date-obsolete)
(test-iso8601-date-weeks, test-iso8601-date-ordinals)
(test-iso8601-time, test-iso8601-combined)
(test-iso8601-duration, test-iso8601-intervals)
(standard-test-dates, standard-test-time-of-day-fractions)
(standard-test-time-of-day-beginning-of-day)
(standard-test-time-of-day-utc)
(standard-test-time-of-day-zone)
(standard-test-date-and-time-of-day, standard-test-interval):
* test/lisp/calendar/parse-time-tests.el (parse-time-tests):
* test/src/timefns-tests.el (format-time-string-with-zone)
(encode-time-dst-numeric-zone):
Revert recent changes that added a SUBSECS member to
calendrical timestamps, since that component is no longer
present (the info, if any, is now in the SECONDS member).
* lisp/calendar/time-date.el (decoded-time-add)
(decoded-time--alter-second):
Support fractional seconds in the new form. Simplify.
* src/timefns.c (Fdecode_time): Support new arg FORM.
(Fencode_time): Support subsecond resolution.
* test/src/timefns-tests.el (format-time-string-with-zone)
(decode-then-encode-time): Test subsecond calendrical timestamps.
Diffstat (limited to 'src')
| -rw-r--r-- | src/timefns.c | 178 |
1 files changed, 105 insertions, 73 deletions
diff --git a/src/timefns.c b/src/timefns.c index 979550c8431..16c39c83493 100644 --- a/src/timefns.c +++ b/src/timefns.c | |||
| @@ -1374,8 +1374,8 @@ usage: (format-time-string FORMAT-STRING &optional TIME ZONE) */) | |||
| 1374 | t, zone, &tm); | 1374 | t, zone, &tm); |
| 1375 | } | 1375 | } |
| 1376 | 1376 | ||
| 1377 | DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0, | 1377 | DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 3, 0, |
| 1378 | doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF SUBSEC). | 1378 | doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF). |
| 1379 | The optional TIME is the time value to convert. See | 1379 | The optional TIME is the time value to convert. See |
| 1380 | `format-time-string' for the various forms of a time value. | 1380 | `format-time-string' for the various forms of a time value. |
| 1381 | 1381 | ||
| @@ -1385,29 +1385,33 @@ the TZ environment variable. It can also be a list (as from | |||
| 1385 | `current-time-zone') or an integer (the UTC offset in seconds) applied | 1385 | `current-time-zone') or an integer (the UTC offset in seconds) applied |
| 1386 | without consideration for daylight saving time. | 1386 | without consideration for daylight saving time. |
| 1387 | 1387 | ||
| 1388 | The optional FORM specifies the form of the SEC member. If `integer', | ||
| 1389 | SEC is an integer; if t, SEC uses the same resolution as TIME. An | ||
| 1390 | omitted or nil FORM is currently treated like `integer', but this may | ||
| 1391 | change in future Emacs versions. | ||
| 1392 | |||
| 1388 | To access (or alter) the elements in the time value, the | 1393 | To access (or alter) the elements in the time value, the |
| 1389 | `decoded-time-second', `decoded-time-minute', `decoded-time-hour', | 1394 | `decoded-time-second', `decoded-time-minute', `decoded-time-hour', |
| 1390 | `decoded-time-day', `decoded-time-month', `decoded-time-year', | 1395 | `decoded-time-day', `decoded-time-month', `decoded-time-year', |
| 1391 | `decoded-time-weekday', `decoded-time-dst', `decoded-time-zone' and | 1396 | `decoded-time-weekday', `decoded-time-dst' and `decoded-time-zone' |
| 1392 | `decoded-time-subsec' accessors can be used. | 1397 | accessors can be used. |
| 1393 | 1398 | ||
| 1394 | The list has the following ten members: SEC is an integer between 0 | 1399 | The list has the following nine members: SEC is an integer or |
| 1395 | and 60; SEC is 60 for a leap second, which only some operating systems | 1400 | Lisp timestamp representing a nonnegative value less than 60 |
| 1396 | support. MINUTE is an integer between 0 and 59. HOUR is an integer | 1401 | \(or less than 61 if the operating system supports leap seconds). |
| 1402 | MINUTE is an integer between 0 and 59. HOUR is an integer | ||
| 1397 | between 0 and 23. DAY is an integer between 1 and 31. MONTH is an | 1403 | between 0 and 23. DAY is an integer between 1 and 31. MONTH is an |
| 1398 | integer between 1 and 12. YEAR is an integer indicating the | 1404 | integer between 1 and 12. YEAR is an integer indicating the |
| 1399 | four-digit year. DOW is the day of week, an integer between 0 and 6, | 1405 | four-digit year. DOW is the day of week, an integer between 0 and 6, |
| 1400 | where 0 is Sunday. DST is t if daylight saving time is in effect, | 1406 | where 0 is Sunday. DST is t if daylight saving time is in effect, |
| 1401 | nil if it is not in effect, and -1 if daylight saving information is | 1407 | nil if it is not in effect, and -1 if daylight saving information is |
| 1402 | not available. UTCOFF is an integer indicating the UTC offset in | 1408 | not available. UTCOFF is an integer indicating the UTC offset in |
| 1403 | seconds, i.e., the number of seconds east of Greenwich. SUBSEC is | 1409 | seconds, i.e., the number of seconds east of Greenwich. (Note that |
| 1404 | is either 0 or (TICKS . HZ) where HZ is a positive integer clock | 1410 | Common Lisp has different meanings for DOW and UTCOFF, and its |
| 1405 | resolution and TICKS is a nonnegative integer less than HZ. (Note | 1411 | SEC is always an integer between 0 and 59.) |
| 1406 | that Common Lisp has different meanings for DOW and UTCOFF, and lacks | ||
| 1407 | SUBSEC.) | ||
| 1408 | 1412 | ||
| 1409 | usage: (decode-time &optional TIME ZONE) */) | 1413 | usage: (decode-time &optional TIME ZONE FORM) */) |
| 1410 | (Lisp_Object specified_time, Lisp_Object zone) | 1414 | (Lisp_Object specified_time, Lisp_Object zone, Lisp_Object form) |
| 1411 | { | 1415 | { |
| 1412 | struct lisp_time lt = lisp_time_struct (specified_time, 0); | 1416 | struct lisp_time lt = lisp_time_struct (specified_time, 0); |
| 1413 | struct timespec ts = lisp_to_timespec (lt); | 1417 | struct timespec ts = lisp_to_timespec (lt); |
| @@ -1439,8 +1443,35 @@ usage: (decode-time &optional TIME ZONE) */) | |||
| 1439 | year = make_integer_mpz (); | 1443 | year = make_integer_mpz (); |
| 1440 | } | 1444 | } |
| 1441 | 1445 | ||
| 1446 | Lisp_Object hz = lt.hz, sec; | ||
| 1447 | if (EQ (hz, make_fixnum (1)) || !EQ (form, Qt)) | ||
| 1448 | sec = make_fixnum (local_tm.tm_sec); | ||
| 1449 | else | ||
| 1450 | { | ||
| 1451 | Lisp_Object ticks; /* hz * tm_sec + mod (lt.ticks, hz) */ | ||
| 1452 | intmax_t n; | ||
| 1453 | if (FASTER_TIMEFNS && FIXNUMP (lt.ticks) && FIXNUMP (hz) | ||
| 1454 | && !INT_MULTIPLY_WRAPV (XFIXNUM (hz), local_tm.tm_sec, &n) | ||
| 1455 | && ! (INT_ADD_WRAPV | ||
| 1456 | (n, (XFIXNUM (lt.ticks) % XFIXNUM (hz) | ||
| 1457 | + (XFIXNUM (lt.ticks) % XFIXNUM (hz) < 0 | ||
| 1458 | ? XFIXNUM (hz) : 0)), | ||
| 1459 | &n))) | ||
| 1460 | ticks = make_int (n); | ||
| 1461 | else | ||
| 1462 | { | ||
| 1463 | mpz_fdiv_r (mpz[0], | ||
| 1464 | *bignum_integer (&mpz[0], lt.ticks), | ||
| 1465 | *bignum_integer (&mpz[1], hz)); | ||
| 1466 | mpz_addmul_ui (mpz[0], *bignum_integer (&mpz[1], hz), | ||
| 1467 | local_tm.tm_sec); | ||
| 1468 | ticks = make_integer_mpz (); | ||
| 1469 | } | ||
| 1470 | sec = Fcons (ticks, hz); | ||
| 1471 | } | ||
| 1472 | |||
| 1442 | return CALLN (Flist, | 1473 | return CALLN (Flist, |
| 1443 | make_fixnum (local_tm.tm_sec), | 1474 | sec, |
| 1444 | make_fixnum (local_tm.tm_min), | 1475 | make_fixnum (local_tm.tm_min), |
| 1445 | make_fixnum (local_tm.tm_hour), | 1476 | make_fixnum (local_tm.tm_hour), |
| 1446 | make_fixnum (local_tm.tm_mday), | 1477 | make_fixnum (local_tm.tm_mday), |
| @@ -1453,10 +1484,7 @@ usage: (decode-time &optional TIME ZONE) */) | |||
| 1453 | ? make_fixnum (tm_gmtoff (&local_tm)) | 1484 | ? make_fixnum (tm_gmtoff (&local_tm)) |
| 1454 | : gmtime_r (&time_spec, &gmt_tm) | 1485 | : gmtime_r (&time_spec, &gmt_tm) |
| 1455 | ? make_fixnum (tm_diff (&local_tm, &gmt_tm)) | 1486 | ? make_fixnum (tm_diff (&local_tm, &gmt_tm)) |
| 1456 | : Qnil), | 1487 | : Qnil)); |
| 1457 | (EQ (lt.hz, make_fixnum (1)) | ||
| 1458 | ? make_fixnum (0) | ||
| 1459 | : Fcons (integer_mod (lt.ticks, lt.hz), lt.hz))); | ||
| 1460 | } | 1488 | } |
| 1461 | 1489 | ||
| 1462 | /* Return OBJ - OFFSET, checking that OBJ is a valid integer and that | 1490 | /* Return OBJ - OFFSET, checking that OBJ is a valid integer and that |
| @@ -1487,7 +1515,7 @@ check_tm_member (Lisp_Object obj, int offset) | |||
| 1487 | DEFUN ("encode-time", Fencode_time, Sencode_time, 1, MANY, 0, | 1515 | DEFUN ("encode-time", Fencode_time, Sencode_time, 1, MANY, 0, |
| 1488 | doc: /* Convert TIME to a timestamp. | 1516 | doc: /* Convert TIME to a timestamp. |
| 1489 | 1517 | ||
| 1490 | TIME is a list (SECOND MINUTE HOUR DAY MONTH YEAR IGNORED DST ZONE SUBSEC). | 1518 | TIME is a list (SECOND MINUTE HOUR DAY MONTH YEAR IGNORED DST ZONE). |
| 1491 | in the style of `decode-time', so that (encode-time (decode-time ...)) works. | 1519 | in the style of `decode-time', so that (encode-time (decode-time ...)) works. |
| 1492 | In this list, ZONE can be nil for Emacs local time, t for Universal | 1520 | In this list, ZONE can be nil for Emacs local time, t for Universal |
| 1493 | Time, `wall' for system wall clock time, or a string as in the TZ | 1521 | Time, `wall' for system wall clock time, or a string as in the TZ |
| @@ -1496,23 +1524,16 @@ environment variable. It can also be a list (as from | |||
| 1496 | without consideration for daylight saving time. If ZONE specifies a | 1524 | without consideration for daylight saving time. If ZONE specifies a |
| 1497 | time zone with daylight-saving transitions, DST is t for daylight | 1525 | time zone with daylight-saving transitions, DST is t for daylight |
| 1498 | saving time, nil for standard time, and -1 to cause the daylight | 1526 | saving time, nil for standard time, and -1 to cause the daylight |
| 1499 | saving flag to be guessed. SUBSEC is either 0 or a Lisp timestamp | 1527 | saving flag to be guessed. |
| 1500 | in (TICKS . HZ) form. | ||
| 1501 | 1528 | ||
| 1502 | As an obsolescent calling convention, if this function is called with | 1529 | As an obsolescent calling convention, if this function is called with |
| 1503 | 6 through 10 arguments, the first 6 arguments are SECOND, MINUTE, | 1530 | 6 or more arguments, the first 6 arguments are SECOND, MINUTE, HOUR, |
| 1504 | HOUR, DAY, MONTH, and YEAR, and specify the components of a decoded | 1531 | DAY, MONTH, and YEAR, and specify the components of a decoded time, |
| 1505 | time. If there are 7 through 9 arguments the *last* argument | 1532 | where DST assumed to be -1 and FORM is omitted. If there are more |
| 1506 | specifies ZONE, and if there are 10 arguments the 9th specifies ZONE | 1533 | than 6 arguments the *last* argument is used as ZONE and any other |
| 1507 | and the 10th specifies SUBSEC; in either case any other extra | 1534 | extra arguments are ignored, so that (apply #\\='encode-time |
| 1508 | arguments are ignored, so that (apply #\\='encode-time (decode-time | 1535 | (decode-time ...)) works. In this obsolescent convention, DST and |
| 1509 | ...)) works. In this obsolescent convention, DST, ZONE, and SUBSEC | 1536 | ZONE default to -1 and nil respectively. |
| 1510 | default to -1, nil and 0 respectively. | ||
| 1511 | |||
| 1512 | Out-of-range values for SECOND, MINUTE, HOUR, DAY, or MONTH are allowed; | ||
| 1513 | for example, a DAY of 0 means the day preceding the given month. | ||
| 1514 | Year numbers less than 100 are treated just like other year numbers. | ||
| 1515 | If you want them to stand for years in this century, you must do that yourself. | ||
| 1516 | 1537 | ||
| 1517 | Years before 1970 are not guaranteed to work. On some systems, | 1538 | Years before 1970 are not guaranteed to work. On some systems, |
| 1518 | year values as low as 1901 do work. | 1539 | year values as low as 1901 do work. |
| @@ -1521,27 +1542,27 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */) | |||
| 1521 | (ptrdiff_t nargs, Lisp_Object *args) | 1542 | (ptrdiff_t nargs, Lisp_Object *args) |
| 1522 | { | 1543 | { |
| 1523 | struct tm tm; | 1544 | struct tm tm; |
| 1524 | Lisp_Object zone = Qnil, subsec = make_fixnum (0); | 1545 | Lisp_Object zone = Qnil; |
| 1525 | Lisp_Object a = args[0]; | 1546 | Lisp_Object a = args[0]; |
| 1547 | Lisp_Object secarg, minarg, hourarg, mdayarg, monarg, yeararg; | ||
| 1526 | tm.tm_isdst = -1; | 1548 | tm.tm_isdst = -1; |
| 1527 | 1549 | ||
| 1528 | if (nargs == 1) | 1550 | if (nargs == 1) |
| 1529 | { | 1551 | { |
| 1530 | Lisp_Object tail = a; | 1552 | Lisp_Object tail = a; |
| 1531 | for (int i = 0; i < 10; i++, tail = XCDR (tail)) | 1553 | for (int i = 0; i < 9; i++, tail = XCDR (tail)) |
| 1532 | CHECK_CONS (tail); | 1554 | CHECK_CONS (tail); |
| 1533 | tm.tm_sec = check_tm_member (XCAR (a), 0); a = XCDR (a); | 1555 | secarg = XCAR (a); a = XCDR (a); |
| 1534 | tm.tm_min = check_tm_member (XCAR (a), 0); a = XCDR (a); | 1556 | minarg = XCAR (a); a = XCDR (a); |
| 1535 | tm.tm_hour = check_tm_member (XCAR (a), 0); a = XCDR (a); | 1557 | hourarg = XCAR (a); a = XCDR (a); |
| 1536 | tm.tm_mday = check_tm_member (XCAR (a), 0); a = XCDR (a); | 1558 | mdayarg = XCAR (a); a = XCDR (a); |
| 1537 | tm.tm_mon = check_tm_member (XCAR (a), 1); a = XCDR (a); | 1559 | monarg = XCAR (a); a = XCDR (a); |
| 1538 | tm.tm_year = check_tm_member (XCAR (a), TM_YEAR_BASE); a = XCDR (a); | 1560 | yeararg = XCAR (a); a = XCDR (a); |
| 1539 | a = XCDR (a); | 1561 | a = XCDR (a); |
| 1540 | Lisp_Object dstflag = XCAR (a); a = XCDR (a); | 1562 | Lisp_Object dstflag = XCAR (a); a = XCDR (a); |
| 1541 | zone = XCAR (a); a = XCDR (a); | 1563 | zone = XCAR (a); |
| 1542 | if (SYMBOLP (dstflag) && !FIXNUMP (zone) && !CONSP (zone)) | 1564 | if (SYMBOLP (dstflag) && !FIXNUMP (zone) && !CONSP (zone)) |
| 1543 | tm.tm_isdst = !NILP (dstflag); | 1565 | tm.tm_isdst = !NILP (dstflag); |
| 1544 | subsec = XCAR (a); | ||
| 1545 | } | 1566 | } |
| 1546 | else if (nargs < 6) | 1567 | else if (nargs < 6) |
| 1547 | xsignal2 (Qwrong_number_of_arguments, Qencode_time, make_fixnum (nargs)); | 1568 | xsignal2 (Qwrong_number_of_arguments, Qencode_time, make_fixnum (nargs)); |
| @@ -1549,18 +1570,37 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */) | |||
| 1549 | { | 1570 | { |
| 1550 | if (6 < nargs) | 1571 | if (6 < nargs) |
| 1551 | zone = args[nargs - 1]; | 1572 | zone = args[nargs - 1]; |
| 1552 | if (9 < nargs) | 1573 | secarg = a; |
| 1553 | { | 1574 | minarg = args[1]; |
| 1554 | zone = args[8]; | 1575 | hourarg = args[2]; |
| 1555 | subsec = args[9]; | 1576 | mdayarg = args[3]; |
| 1556 | } | 1577 | monarg = args[4]; |
| 1557 | tm.tm_sec = check_tm_member (a, 0); | 1578 | yeararg = args[5]; |
| 1558 | tm.tm_min = check_tm_member (args[1], 0); | 1579 | } |
| 1559 | tm.tm_hour = check_tm_member (args[2], 0); | 1580 | |
| 1560 | tm.tm_mday = check_tm_member (args[3], 0); | 1581 | struct lisp_time lt; |
| 1561 | tm.tm_mon = check_tm_member (args[4], 1); | 1582 | decode_lisp_time (secarg, 0, <, 0); |
| 1562 | tm.tm_year = check_tm_member (args[5], TM_YEAR_BASE); | 1583 | Lisp_Object hz = lt.hz, sec, subsecticks; |
| 1584 | if (FASTER_TIMEFNS && EQ (hz, make_fixnum (1))) | ||
| 1585 | { | ||
| 1586 | sec = lt.ticks; | ||
| 1587 | subsecticks = make_fixnum (0); | ||
| 1588 | } | ||
| 1589 | else | ||
| 1590 | { | ||
| 1591 | mpz_fdiv_qr (mpz[0], mpz[1], | ||
| 1592 | *bignum_integer (&mpz[0], lt.ticks), | ||
| 1593 | *bignum_integer (&mpz[1], hz)); | ||
| 1594 | sec = make_integer_mpz (); | ||
| 1595 | mpz_swap (mpz[0], mpz[1]); | ||
| 1596 | subsecticks = make_integer_mpz (); | ||
| 1563 | } | 1597 | } |
| 1598 | tm.tm_sec = check_tm_member (sec, 0); | ||
| 1599 | tm.tm_min = check_tm_member (minarg, 0); | ||
| 1600 | tm.tm_hour = check_tm_member (hourarg, 0); | ||
| 1601 | tm.tm_mday = check_tm_member (mdayarg, 0); | ||
| 1602 | tm.tm_mon = check_tm_member (monarg, 1); | ||
| 1603 | tm.tm_year = check_tm_member (yeararg, TM_YEAR_BASE); | ||
| 1564 | 1604 | ||
| 1565 | timezone_t tz = tzlookup (zone, false); | 1605 | timezone_t tz = tzlookup (zone, false); |
| 1566 | tm.tm_wday = -1; | 1606 | tm.tm_wday = -1; |
| @@ -1571,25 +1611,17 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */) | |||
| 1571 | if (tm.tm_wday < 0) | 1611 | if (tm.tm_wday < 0) |
| 1572 | time_error (mktime_errno); | 1612 | time_error (mktime_errno); |
| 1573 | 1613 | ||
| 1574 | if (CONSP (subsec)) | 1614 | if (EQ (hz, make_fixnum (1))) |
| 1615 | return (CURRENT_TIME_LIST | ||
| 1616 | ? list2 (hi_time (value), lo_time (value)) | ||
| 1617 | : INT_TO_INTEGER (value)); | ||
| 1618 | else | ||
| 1575 | { | 1619 | { |
| 1576 | Lisp_Object subsecticks = XCAR (subsec); | 1620 | struct lisp_time val1 = { INT_TO_INTEGER (value), make_fixnum (1) }; |
| 1577 | if (INTEGERP (subsecticks)) | 1621 | Lisp_Object secticks = lisp_time_hz_ticks (val1, hz); |
| 1578 | { | 1622 | Lisp_Object ticks = lispint_arith (secticks, subsecticks, false); |
| 1579 | struct lisp_time val1 = { INT_TO_INTEGER (value), make_fixnum (1) }; | 1623 | return Fcons (ticks, hz); |
| 1580 | Lisp_Object | ||
| 1581 | hz = XCDR (subsec), | ||
| 1582 | secticks = lisp_time_hz_ticks (val1, hz), | ||
| 1583 | ticks = lispint_arith (secticks, subsecticks, false); | ||
| 1584 | return Fcons (ticks, hz); | ||
| 1585 | } | ||
| 1586 | } | 1624 | } |
| 1587 | else if (INTEGERP (subsec)) | ||
| 1588 | return (CURRENT_TIME_LIST && EQ (subsec, make_fixnum (0)) | ||
| 1589 | ? list2 (hi_time (value), lo_time (value)) | ||
| 1590 | : lispint_arith (INT_TO_INTEGER (value), subsec, false)); | ||
| 1591 | |||
| 1592 | xsignal2 (Qerror, build_string ("Invalid subsec"), subsec); | ||
| 1593 | } | 1625 | } |
| 1594 | 1626 | ||
| 1595 | DEFUN ("time-convert", Ftime_convert, Stime_convert, 1, 2, 0, | 1627 | DEFUN ("time-convert", Ftime_convert, Stime_convert, 1, 2, 0, |