From: JD Smith <jdtsmith@gmail.com>
To: john muhl <jm@pub.pink>
Cc: Adam Porter <adam@alphapapa.net>,
71572@debbugs.gnu.org, Eli Zaretskii <eliz@gnu.org>,
Jonas Bernoulli <jonas@bernoul.li>,
Paul Eggert <eggert@cs.ucla.edu>
Subject: bug#71572: [PATCH] seconds-to-string-approximate
Date: Mon, 9 Dec 2024 04:52:56 +0900 [thread overview]
Message-ID: <CAACE323-4A0C-4170-962A-3E5284238F9F@gmail.com> (raw)
In-Reply-To: <874j3f2tga.fsf@pub.pink>
[-- Attachment #1: Type: text/plain, Size: 1153 bytes --]
> On Dec 8, 2024, at 4:17 AM, john muhl <jm@pub.pink> wrote:
>
> JD Smith <jdtsmith@gmail.com <mailto:jdtsmith@gmail.com>> writes:
>
>>> On Dec 7, 2024, at 8:02 AM, Eli Zaretskii <eliz@gnu.org> wrote:
>>>
>>>> From: JD Smith <jdtsmith@gmail.com>
>>>> Date: Sat, 30 Nov 2024 13:58:52 -0500
>>>> Cc: Eli Zaretskii <eliz@gnu.org>,
>>>> Adam Porter <adam@alphapapa.net>,
>>>> jonas@bernoul.li,
>>>> Paul Eggert <eggert@cs.ucla.edu>
>>>>
>>>> I was recently reminded of the need for a more capable seconds-to-string.
>>>>
>>>> Anyone have any additional comments on this proposed patch? If not,
>>>> I'd suggest someone with access
>>>> merges.
>>>
>>> A few minor nits below, and then we can install:
>>
>> Thanks. Updated patch below.
>
> Thanks for working on this. I gave a quick try and noticed some
> amounts aren’t pluralized how I expect; e.g.
>
> (seconds-to-string 36541462 'expanded nil 1)
> ;; "1 year 1.9 month"
...
> According to the Chicago Manual of Style all fractional values are
> plural, even 1.0, 2.0 &c.
Thanks for this, a case I hadn't tested. Corrected in the attached.

[-- Attachment #2.1: Type: text/html, Size: 6807 bytes --]
[-- Attachment #2.2: 0001-seconds-to-string-new-optional-arguments-for-readabl.patch --]
[-- Type: application/octet-stream, Size: 5860 bytes --]
From c1937c9969955cd040a6587cba9e4d91e79ec78c Mon Sep 17 00:00:00 2001
From: JD Smith <93749+jdtsmith@users.noreply.github.com>
Date: Thu, 11 Jul 2024 16:24:17 -0400
Subject: [PATCH] seconds-to-string: new optional arguments for readable
strings
---
doc/lispref/os.texi | 6 +++
etc/NEWS | 7 ++++
lisp/calendar/time-date.el | 82 ++++++++++++++++++++++++++++++++++++--
3 files changed, 91 insertions(+), 4 deletions(-)
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 3ba3da459bf..ac9d5acdf3d 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -2155,6 +2155,12 @@ Time Calculations
structure. For instance, the 120th day in 2004 is April 29th.
@end defun
+@defun seconds-to-string delay &optional readable abbrev precision
+Return a string describing a given @var{delay} (in seconds). Optional
+arguments can be used to configure a human readable delay using various
+formats. For example, a delay of 9861.5 seconds with @var{readable} set
+to the symbol @code{expanded} returns @samp{2 hours 44 minutes}.
+
@node Timers
@section Timers for Delayed Execution
@cindex timers
diff --git a/etc/NEWS b/etc/NEWS
index f10f9ae4d65..1fd2a9404bb 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -30,6 +30,13 @@ applies, and please also update docstrings as needed.
\f
* Changes in Emacs 31.1
+** Time & Date
+
++++
+*** 'seconds-to-string' includes new formatting options.
+Options are provided to produce human-readable delay strings in a
+variety of formats, for example "6 months 3 weeks" or "5m 52.5s".
+
\f
* Editing Changes in Emacs 31.1
diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el
index eca80f1e8b6..5d53052a65c 100644
--- a/lisp/calendar/time-date.el
+++ b/lisp/calendar/time-date.el
@@ -409,11 +409,85 @@ seconds-to-string
(list (* 3600 24 400) "d" (* 3600.0 24.0))
(list nil "y" (* 365.25 24 3600)))
"Formatting used by the function `seconds-to-string'.")
+
+(defvar seconds-to-string-readable
+ `(("Y" "year" "years" ,(round (* 60 60 24 365.2425)))
+ ("M" "month" "months" ,(round (* 60 60 24 30.436875)))
+ ("w" "week" "weeks" ,(* 60 60 24 7))
+ ("d" "day" "days" ,(* 60 60 24))
+ ("h" "hour" "hours" ,(* 60 60))
+ ("m" "minute" "minutes" 60)
+ ("s" "second" "seconds" 1))
+ "Formatting used by the function `seconds-to-string' with READABLE set.
+The format is an alist, with string keys ABBREV-UNIT, and elements like:
+
+ (ABBREV-UNIT UNIT UNIT-PLURAL SECS)
+
+where UNIT is a unit of time, ABBREV-UNIT is the abreviated form of
+UNIT, UNIT-PLURAL is the plural form of UNIT, and SECS is the number of
+seconds per UNIT.")
+
;;;###autoload
-(defun seconds-to-string (delay)
- ;; FIXME: There's a similar (tho fancier) function in mastodon.el!
- "Convert the time interval in seconds to a short string."
- (cond ((> 0 delay) (concat "-" (seconds-to-string (- delay))))
+(defun seconds-to-string (delay &optional readable abbrev precision)
+ "Convert time interval DELAY (in seconds) to a string.
+By default, the returned string is formatted as a float in the smallest
+unit from the variable `seconds-to-string' that is longer than DELAY,
+and a precision of two. If READABLE is non-nil, convert DELAY into a
+readable string, using the information provided in the variable
+`seconds-to-string-readable'. If it is the symbol `expanded', use two
+units to describe DELAY, if appropriate. E.g. \"1 hour 32 minutes\".
+If ABBREV is non-nil, abbreviate the readable units. If PRECISION is a
+whole number, round the value associated with the smallest displayed
+unit to that many digits after the decimal. If it is a non-negative
+float less than 1.0, round to that value."
+ (cond ((< delay 0)
+ (concat "-" (seconds-to-string (- delay) readable precision)))
+ (readable
+ (let* ((stsa seconds-to-string-readable)
+ (expanded (eq readable 'expanded))
+ digits
+ (round-to (cond ((wholenump precision)
+ (setq digits precision)
+ (expt 10 (- precision)))
+ ((and (floatp precision) (< precision 1.))
+ (setq digits (- (floor (log precision 10))))
+ precision)
+ (t (setq digits 0) 1)))
+ (dformat (if (> digits 0) (format "%%0.%df" digits)))
+ (padding (if abbrev "" " "))
+ here cnt cnt-pre here-pre cnt-val isfloatp)
+ (if (= (round delay round-to) 0)
+ (format "0%s" (if abbrev "s" " seconds"))
+ (while (and (setq here (pop stsa)) stsa
+ (< (/ delay (nth 3 here)) 1)))
+ (or (and
+ expanded stsa ; smaller unit remains
+ (progn
+ (setq
+ here-pre here here (car stsa)
+ cnt-pre (floor (/ (float delay) (nth 3 here-pre)))
+ cnt (round
+ (/ (- (float delay) (* cnt-pre (nth 3 here-pre)))
+ (nth 3 here))
+ round-to))
+ (if (> cnt 0) t (setq cnt cnt-pre here here-pre here-pre nil))))
+ (setq cnt (round (/ (float delay) (nth 3 here)) round-to)))
+ (setq cnt-val (* cnt round-to)
+ isfloatp (and (> digits 0)
+ (> (- cnt-val (floor cnt-val)) 0.)))
+ (cl-labels
+ ((unit (val here &optional plural)
+ (cond (abbrev (car here))
+ ((and (not plural) (<= (floor val) 1)) (nth 1 here))
+ (t (nth 2 here)))))
+ (concat
+ (when here-pre
+ (concat (number-to-string cnt-pre) padding
+ (unit (* cnt-pre round-to) here-pre) " "))
+ (if isfloatp (format dformat cnt-val)
+ (number-to-string (floor cnt-val)))
+ padding
+ (unit cnt-val here isfloatp)))))) ; floats are always plural
((= 0 delay) "0s")
(t (let ((sts seconds-to-string) here)
(while (and (car (setq here (pop sts)))
--
2.45.2
[-- Attachment #2.3: Type: text/html, Size: 216 bytes --]
next prev parent reply other threads:[~2024-12-08 19:52 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-15 17:24 bug#71573: [PATCH] seconds-to-string-approximate JD Smith
2024-06-15 17:36 ` Eli Zaretskii
2024-06-17 6:20 ` bug#71573: Related functions from ts.el Adam Porter
2024-06-22 10:55 ` Stefan Kangas
2024-06-22 21:54 ` Adam Porter
2024-06-22 8:45 ` bug#71572: [PATCH] seconds-to-string-approximate Eli Zaretskii
2024-06-22 21:56 ` Adam Porter
2024-06-22 23:42 ` Paul Eggert
2024-06-23 2:16 ` JD Smith
2024-07-04 5:29 ` Eli Zaretskii
2024-07-04 6:04 ` Eli Zaretskii
2024-07-04 7:09 ` Paul Eggert
2024-07-06 19:29 ` JD Smith
2024-07-06 21:09 ` Paul Eggert
2024-07-11 21:01 ` JD Smith
2024-11-30 18:58 ` JD Smith
2024-12-07 13:02 ` Eli Zaretskii
2024-12-07 17:52 ` JD Smith
2024-12-07 19:17 ` john muhl
2024-12-08 19:52 ` JD Smith [this message]
2024-12-08 22:51 ` john muhl
2024-12-15 18:07 ` JD Smith
2024-12-15 23:26 ` john muhl
2024-07-04 15:27 ` JD Smith
2024-07-04 15:59 ` Eli Zaretskii
2024-07-04 17:16 ` JD Smith
2024-07-04 18:06 ` Eli Zaretskii
2024-07-04 16:36 ` Ihor Radchenko
2024-07-04 17:23 ` JD Smith
2024-07-04 17:57 ` Ihor Radchenko
2024-06-23 5:13 ` Eli Zaretskii
2024-07-03 20:32 ` JD Smith
2024-07-04 5:29 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAACE323-4A0C-4170-962A-3E5284238F9F@gmail.com \
--to=jdtsmith@gmail.com \
--cc=71572@debbugs.gnu.org \
--cc=adam@alphapapa.net \
--cc=eggert@cs.ucla.edu \
--cc=eliz@gnu.org \
--cc=jm@pub.pink \
--cc=jonas@bernoul.li \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).