emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [O] org table calc and lisp for hh:mm timetable


From: Eric Schulte
Subject: Re: [O] org table calc and lisp for hh:mm timetable
Date: Sun, 20 Mar 2011 11:50:23 -0600
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

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

|  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
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,

reply via email to

[Prev in Thread] Current Thread [Next in Thread]