I wrapped Bastien's functions below in a simple macro, which IMO results
in a very nice way to handle time values in Org-mode tables as shown
below.
Note, the first argument to the `with-time' macro controls whether
results are returned as a time string or a numerical value. That
argument may be followed by any number of expressions.
| time | miles | minutes/mile |
|-------+-------+--------------|
| 34:43 | 2.9 | 11:58 |
| 56:00 | 5.5 | 10:10 |
| 31:00 | 3.04 | 10:11 |
| 32:15 | 2.77 | 11:38 |
| 33:56 | 3.0 | 11:18 |
| 72:00 | 6.74 | 10:40 |
| 52:22 | 4.62 | 11:20 |
#+TBLFM: $3='(with-time t (/ $1 $2))
#+begin_src emacs-lisp
(defun org-time-string-to-seconds (s)
"Convert a string HH:MM:SS to a number of seconds."
(cond
((and (stringp s)
(string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)" s))
(let ((hour (string-to-number (match-string 1 s)))
(min (string-to-number (match-string 2 s)))
(sec (string-to-number (match-string 3 s))))
(+ (* hour 3600) (* min 60) sec)))
((and (stringp s)
(string-match "\\([0-9]+\\):\\([0-9]+\\)" s))
(let ((min (string-to-number (match-string 1 s)))
(sec (string-to-number (match-string 2 s))))
(+ (* min 60) sec)))
((stringp s) (string-to-number s))
(t s)))
(defun org-time-seconds-to-string (secs)
"Convert a number of seconds to a time string."
(cond ((>= secs 3600) (format-seconds "%h:%.2m:%.2s" secs))
((>= secs 60) (format-seconds "%m:%.2s" secs))
(t (format-seconds "%s" secs))))
(defmacro with-time (time-output-p&rest exprs)
"Evaluate an org-table formula, converting all fields that look
like time data to integer seconds. If TIME-OUTPUT-P then return
the result as a time value."
(list
(if time-output-p 'org-time-seconds-to-string 'identity)
(cons 'progn
(mapcar
(lambda (expr)
`,(cons (car expr) (mapcar #'org-time-string-to-seconds (cdr
expr))))
`,@exprs))))
#+end_src
Bastien<address@hidden> writes:
Hi Martin,
Martin Halder<address@hidden> writes:
this is fantastic, already love lisp, thanks a lot.. now I have exactly
what I wanted.. additionally I needed the time format in industrial mode
(1h = 100m = 100s), implemented in ihms.
thanks for these functions -- I allowed myself to add them to
Worg/org-hacks.html, in a new "Times computation" section:
http://orgmode.org/worg/org-hacks.html
I added these functions I myself wrote for a particular purpose:
#+begin_src emacs-lisp
(defun org-hh:mm:ss-string-to-seconds (s)
"Convert a string HH:MM:SS to a number of seconds."
(when (string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)" s)
(let ((hour (string-to-number (match-string 1 s)))
(min (string-to-number (match-string 2 s)))
(sec (string-to-number (match-string 3 s))))
(+ (* hour 3600) (* min 60) sec))))
(defun org-subtract-hh:mm:ss-time (t1 t2)
"Substract two hh:mm:ss time values."
(let* ((sec (- (org-hh:mm:ss-string-to-seconds t2)
(org-hh:mm:ss-string-to-seconds t1)))
(hour (floor (/ sec 3600)))
(min (floor (/ (- sec (* 3600 hour)) 60)))
(secs (round (- sec (* 3600 hour) (* 60 min)))))
(format "%.2d:%.2d:%.2d" hour min secs)))
#+end_src
With these function, you can subtract durations in a table like this:
| Part | Begin | End | Duration |
|-------+----------+----------+----------|
| One | 00:00:00 | 00:01:11 | 00:01:11 |
| Two | 00:01:12 | 00:02:00 | 00:00:48 |
| Three | 00:02:05 | 00:16:06 | 00:14:01 |
#+TBLFM: $4='(org-subtract-hh:mm:ss-time $2 $3)
Which was useful for me when I had to derush video files.
HTH,