From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Eric Schulte" Subject: Re: org table calc and lisp for hh:mm timetable Date: Sun, 20 Mar 2011 11:50:23 -0600 Message-ID: <87r5a1lm00.fsf@gmail.com> References: <9999237C-1FBD-481E-AF8D-D68DB85080CE@gmail.com> <87lj0gqjd3.fsf@ucl.ac.uk> <0DDD90AF-9B9A-4FE3-8080-74EF01E6E292@gmail.com> <4D7FDE8C.1030103@christianmoe.com> <00BD91C6-C610-4CDD-B3E0-E9FECDAA372C@gmail.com> <87k4fynog3.fsf@altern.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from [140.186.70.92] (port=35454 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q1Mlv-0008C1-7D for emacs-orgmode@gnu.org; Sun, 20 Mar 2011 13:50:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q1Mlt-0000SD-8M for emacs-orgmode@gnu.org; Sun, 20 Mar 2011 13:50:35 -0400 Received: from mail-iy0-f169.google.com ([209.85.210.169]:34450) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q1Mlt-0000Rw-28 for emacs-orgmode@gnu.org; Sun, 20 Mar 2011 13:50:33 -0400 Received: by iyf13 with SMTP id 13so7155213iyf.0 for ; Sun, 20 Mar 2011 10:50:32 -0700 (PDT) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Bastien Cc: emacs-orgmode@gnu.org, Martin Halder , mail@christianmoe.com --=-=-= Content-Type: text/plain 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 in the attached org file (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 (possibly nested) expressions. If this looks to be generally useful I'd be happy to post it to worg. Best -- Eric --=-=-= Content-Type: text/org Content-Disposition: inline; filename=time.org | 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 :results silent (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 (lambda (el) (if (listp el) (list 'with-time nil el) (org-time-string-to-seconds el))) (cdr expr)))) `,@exprs)))) #+end_src --=-=-= Content-Type: text/plain Bastien writes: > Hi Martin, > > Martin Halder 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, --=-=-=--