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 17:43:53 -0600 Message-ID: <87fwqhl5mu.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> <87lj09llzd.fsf@gmail.com> <4D866AD7.4020701@christianmoe.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from [140.186.70.92] (port=42645 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Q1SI1-0005Fx-GH for emacs-orgmode@gnu.org; Sun, 20 Mar 2011 19:44:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Q1SHx-0000ad-2m for emacs-orgmode@gnu.org; Sun, 20 Mar 2011 19:44:05 -0400 Received: from mail-iw0-f169.google.com ([209.85.214.169]:43024) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Q1SHw-0000aJ-U8 for emacs-orgmode@gnu.org; Sun, 20 Mar 2011 19:44:01 -0400 Received: by iwl42 with SMTP id 42so7412111iwl.0 for ; Sun, 20 Mar 2011 16:44:00 -0700 (PDT) In-Reply-To: <4D866AD7.4020701@christianmoe.com> (Christian Moe's message of "Sun, 20 Mar 2011 22:00:07 +0100") 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: mail@christianmoe.com Cc: Bastien , emacs-orgmode@gnu.org, Martin Halder Christian Moe writes: > Hi, > > Returning to this thread: > > 1. I love Eric's macro wrapper idea -- now time arithmetic in tables > gets truly manageable. If it's not included into Org-mode, it's a must > for Worg! > Great, if no Org-mode changes result, then I will certainly post this code up to Worg. > > 2. There's duplication with org-timer-hms-to-secs and > org-timer-secs-to-hms. (Cf. my > http://permalink.gmane.org/gmane.emacs.orgmode/39501.) > I believe these new functions are slightly more forgiving of alternate time format strings, than the strict format expected by the org-timer-* functions, however maybe it makes sense to consolidate these and the org-timer-* functions around a set of core org-time functions. > > Do Martin's/Bastien's/Eric's hms/seconds conversion functions add > value that should be patched into org-timer? > I think of these as separate from org-timer given that they mainly deal with table formulas, however maybe both these and org-timer-* could benefit from a centralized org-time-* functionality. > > 3. One thing Eric's converters do and org-timer doesn't is to handle a > string with only two two-digit groups (e.g. 12:45). > > Eric's converters interpret it as 12m 45s -- good for running > times. The functions I posted (see link above) interpreted such > strings as 12h 45m -- good for time of day. > > I suggest the latter is more convenient for most use cases: When I'm > working with seconds (running times, audio track durations) it's sort > of a technical use, so I'm prepared to add 0 hours in front. When a > time of day like 12:45 is good enough, I don't want to have to add 00 > seconds in back. (And am/pm is not used in my locale.) > I think the best would be for these functions (at least the table formula functions) to remain agnostic as to the actual denomination of the time, but rather just parse *:* as base sixty digits. That way a string like "1:20" could mean 80 minutes or 80 seconds, the parser needs not know which, and the formula writer would /hopefully/ get back what's expected. While this topic is raised, would it make sense for Org-mode table formula to automatically parse any time-like string into time units (i.e., base sixty). That would be the easiest for most users, and (I imagine) would rarely result in surprising and unexpected behavior. Best -- Eric > > Yours, > Christian > > On 3/20/11 6:50 PM, Eric Schulte wrote: >> 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 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, >> >>