From daff9c93f2e44eeb31989e3b5f753ad9a1648e44 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Sun, 11 Jun 2017 23:44:51 +0200 Subject: [PATCH] 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. --- doc/org.texi | 23 +++++++++++------- lisp/org-table.el | 43 ++++++++++++++++++++++++---------- testing/lisp/test-org-table.el | 7 ++++++ 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index 83016282c..c47e81f14 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -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. diff --git a/lisp/org-table.el b/lisp/org-table.el index f105e7ef3..817b2096d 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -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) diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table.el index 7059364f8..cf0f05688 100644 --- a/testing/lisp/test-org-table.el +++ b/testing/lisp/test-org-table.el @@ -1809,6 +1809,13 @@ is t, then new columns should be added as needed" #+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 | | + #+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 "