Implement new `U' mode switch for table formulas to omit seconds in durations

* lisp/org-table.el (org-table-duration-custom-format): Add new
	HH:MM format.
	(org-table-duration-hour-zero-padding): New option.
	(org-table-eval-formula): Select second-less format if
	requested.
	(org-table-time-seconds-to-string): Implement formats without
	seconds and without zero-padding for hours.

	* testing/lisp/test-org-table.el (test-org-table/duration):
	New test for second-less durations.

	* doc/org.texi (Formula syntax for Calc)
	(Durations and time values): Document the U mode switch.
This commit is contained in:
Carsten Dominik 2017-06-11 23:44:51 +02:00
parent 5e35bc1807
commit daff9c93f2
3 changed files with 52 additions and 21 deletions

View File

@ -2664,7 +2664,7 @@ calculation precision is greater.
Degree and radian angle modes of Calc.
@item @code{F}, @code{S}
Fraction and symbolic modes of Calc.
@item @code{T}, @code{t}
@item @code{T}, @code{t}, @code{U}
Duration computations in Calc or Lisp, @pxref{Durations and time values}.
@item @code{E}
If and how to consider empty fields. Without @samp{E} empty fields in range
@ -2781,26 +2781,31 @@ Compute the sum of columns 1 to 4, like Calc's @code{vsum($1..$4)}.
@cindex Time, computing
@vindex org-table-duration-custom-format
If you want to compute time values use the @code{T} flag, either in Calc
formulas or Elisp formulas:
If you want to compute time values use the @code{T}, @code{t}, or @code{U}
flag, either in Calc formulas or Elisp formulas:
@example
@group
| Task 1 | Task 2 | Total |
|---------+----------+----------|
| 2:12 | 1:47 | 03:59:00 |
| 2:12 | 1:47 | 03:59 |
| 3:02:20 | -2:07:00 | 0.92 |
#+TBLFM: @@2$3=$1+$2;T::@@3$3=$1+$2;t
#+TBLFM: @@2$3=$1+$2;T::@@3$3=$1+$2;U::@@4$3=$1+$2;t
@end group
@end example
Input duration values must be of the form @code{HH:MM[:SS]}, where seconds
are optional. With the @code{T} flag, computed durations will be displayed
as @code{HH:MM:SS} (see the first formula above). With the @code{t} flag,
computed durations will be displayed according to the value of the option
@code{org-table-duration-custom-format}, which defaults to @code{'hours} and
will display the result as a fraction of hours (see the second formula in the
example above).
as @code{HH:MM:SS} (see the first formula above). With the @code{U} flag,
seconds will be omitted so that the result will be only @code{HH:MM} (see
second formula above). Zero-padding of the hours field will depend upon the
value of the variable @code{org-table-duration-hour-zero-padding}.
With the @code{t} flag, computed durations will be displayed according to the
value of the option @code{org-table-duration-custom-format}, which defaults
to @code{'hours} and will display the result as a fraction of hours (see the
third formula in the example above).
Negative duration values can be manipulated as well, and integers will be
considered as seconds in addition and subtraction.

View File

@ -294,13 +294,23 @@ relies on the variables to be present in the list."
The default value is `hours', and will output the results as a
number of hours. Other allowed values are `seconds', `minutes' and
`days', and the output will be a fraction of seconds, minutes or
days."
days. `hh:mm' selects to use hours and minutes, ignoring seconds.
The `U' flag in a table formula will select this specific format for
a single formula."
:group 'org-table-calculation
:version "24.1"
:type '(choice (symbol :tag "Seconds" 'seconds)
(symbol :tag "Minutes" 'minutes)
(symbol :tag "Hours " 'hours)
(symbol :tag "Days " 'days)))
(symbol :tag "Days " 'days)
(symbol :tag "HH:MM " 'hh:mm)))
(defcustom org-table-duration-hour-zero-padding t
"Non-nil means, hours in table duration computations should be zero-padded.
So this is about 08:32:34 versus 8:33:34."
:group 'org-table-calculation
:version "24.1"
:type 'boolean)
(defcustom org-table-formula-field-format "%s"
"Format for fields which contain the result of a formula.
@ -2723,15 +2733,14 @@ location of point."
(?s . sci) (?e . eng))))
n))))
(setq fmt (replace-match "" t t fmt)))
(if (string-match "T" fmt)
(setq duration t numbers t
duration-output-format nil
fmt (replace-match "" t t fmt)))
(if (string-match "t" fmt)
(setq duration t
duration-output-format org-table-duration-custom-format
numbers t
fmt (replace-match "" t t fmt)))
(if (string-match "[tTU]" fmt)
(let ((ff (match-string 0 fmt)))
(setq duration t numbers t
duration-output-format
(cond ((equal ff "T") nil)
((equal ff "t") org-table-duration-custom-format)
((equal ff "U") 'hh:mm))
fmt (replace-match "" t t fmt))))
(if (string-match "N" fmt)
(setq numbers t
fmt (replace-match "" t t fmt)))
@ -3759,7 +3768,17 @@ minutes or seconds."
(format "%.1f" (/ (float secs0) 60)))
((eq output-format 'seconds)
(format "%d" secs0))
(t (format-seconds "%.2h:%.2m:%.2s" secs0)))))
((eq output-format 'hh:mm)
;; Ignore seconds
(substring (format-seconds
(if org-table-duration-hour-zero-padding
"%.2h:%.2m:%.2s" "%h:%.2m:%.2s")
secs0)
0 -3))
(t (format-seconds
(if org-table-duration-hour-zero-padding
"%.2h:%.2m:%.2s" "%h:%.2m:%.2s")
secs0)))))
(if (< secs 0) (concat "-" res) res)))
(defun org-table-fedit-convert-buffer (function)

View File

@ -1809,6 +1809,13 @@ is t, then new columns should be added as needed"
<point>#+TBLFM: @1$3=$1+$2;T"
(org-table-calc-current-TBLFM)
(buffer-string))))
(should
(string-match "| 2:12 | 1:47 | 03:59 |"
(org-test-with-temp-text "
| 2:12 | 1:47 | |
<point>#+TBLFM: @1$3=$1+$2;U"
(org-table-calc-current-TBLFM)
(buffer-string))))
(should
(string-match "| 3:02:20 | -2:07:00 | 0.92 |"
(org-test-with-temp-text "