Skip to content

Instantly share code, notes, and snippets.

@ssaavedra
Last active October 1, 2018 11:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssaavedra/8668cc3b713bec339a29 to your computer and use it in GitHub Desktop.
Save ssaavedra/8668cc3b713bec339a29 to your computer and use it in GitHub Desktop.
Convert orgmode clocktable time to numbers
;; Receive time as a string like "9d 11:28"
;; Outputs the number of minutes in that
;; The regex works with and without days.
;; MIT License
(defun my-minutes-in-org-time (time)
(let ((re "\\(\\([0-9]+\\)d \\)?\\([0-9]+\\):\\([0-9]+\\)")
(values '(2 3 4)))
(save-match-data
(catch 'exit
(if (not (string-match re time))
(throw 'exit 0.)))
(let ((values (mapcar (lambda (num)
(string-to-number ;; convert to number
(or (match-string num time) ;; the part of the regex that matches
"0"))) ;; or zero in case no days exist, then match-string is nil
values)))
(let ((days (nth 0 values))
(hours (nth 1 values))
(minutes (nth 2 values)))
(+ (* 60
(+ (* 24 days)
hours))
minutes))))))
;; Then use in a clocktable line such as:
;; #+BEGIN: clocktable :maxlevel 6 :scope tree :link nil :level t :tcolumns 1 :formula "$5='(/ (my-minutes-in-org-time $4) 60.0);%.1f"
(defun org-sum-hours (list-of-cells &optional subtract-this-elements)
"Sum elements typed as hh:mm into another cell with the same format. Does not take into account days.
LIST-OF-CELLS is the list of cells to be summed.
If specified, SUBTRACT-THIS-ELEMENTS can be used to filter out an
element or various elements that you would not wish in the
computation.
Example usage:
#+TBLFM: @10$3='(org-sum-hours '(@I..@II) @I)"
(flet ((cell-to-cons
(cell)
(save-match-data
(if (string-match "\\(.*\\):\\(.*\\)" cell)
(let ((h (replace-match "\\1" nil nil cell))
(m (replace-match "\\2" nil nil cell)))
(message "Got time %s:%s" h m)
(setq h (string-to-number h))
(setq m (string-to-number m))
(list h m))
(list 0 0))))
(as-minutes
(cell)
(let* ((ascons (cell-to-cons cell))
(h (car ascons))
(m (cadr ascons)))
(+ (* 60 h)
m)))
(format-number (number)
(let ((nas (number-to-string number)))
(if (> 10 number)
(concat "0" nas)
nas)))
(format-time
(minutes)
(let ((hours (format-number (/ minutes 60)))
(the-minutes (format-number (% minutes 60))))
(format "%s:%s" hours the-minutes))))
(format-time (- (apply
#'+
(mapcar
#'as-minutes
list-of-cells))
(if subtract-this-elements
(if (consp subtract-this-elements)
(apply #'+ (mapcar #'as-minutes subtract-this-elements))
(as-minutes subtract-this-elements))
0)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment