I would like to write an Emacs lisp function, that I can bind to a key shortcut. It will read in the two previous time entries in the format HHMM from the buffer and spit out the difference between them in the format 0.75, that is 45 minutes.

This is the format it should operate with.

1400 Enable ftp access for Sarah
  1. find the previous instance of HHMM in this buffer, occurs at the beginning of a line, and then find the one before that

  2. determine the difference between the two times

  3. output in hours with decimal fractions instead of minutes

Pseudo code

$end-time      = (search back from pointer for previous instance of HHMM)
$begin-time    = (search for second previous instance of HHMM)

$end-hour      = $end-time[0,1]
$end-minute    = $end-time[2,3]

$begin-hour    = $begin-time[0,1]
$begin-minute  = $begin-time[2,3]

$total-hours   = $end-hour - $begin-hour
$total-minutes = $end-minutes - $begin-minutes

return $total-hours + ($total-minutes * 0.01666666667)
  • See (elisp)Time of Day, (elisp)Time Conversion, and (elisp)Time Parsing.
    – Drew
    May 14, 2015 at 17:27
  • So far I just have made a ruby/pseudocode of what I would like to achieve May 14, 2015 at 20:08
  • I haven't written a lisp function before May 14, 2015 at 20:09
  • adding pseudo code to the question now. how should I approach this with Emacs? May 14, 2015 at 20:34
  • 1
    @kaushalmodi I cannot find any statement on the site to the effect that ‘elisp snippets are not catered to’. ‘How to do X in Emacs’ and ‘Programming in Emacs-lisp’ are defined as On Topic in the help centre. emacs.stackexchange.com/help/on-topic May 16, 2015 at 20:48

1 Answer 1


Below should work. It does not strictly follow your pseudo-code but I have put in your pseudo code as comments in-between so that you can get a rough idea of how elisp correlates to that.

(defun my/return-time-diff-frac-hours ()
  (let (begin-hh begin-mm end-hh end-mm diff)
      ;; $end-time      = (search back from pointer for previous instance of HHMM)
      ;; $begin-time    = (search for second previous instance of HHMM)
      (if (re-search-backward (concat "^\\([0-2][0-9]\\)\\([0-5][0-9]\\)"
                                      ) nil :noerror)
            ;; $begin-hour    = $begin-time[0,1]
            ;; $begin-minute  = $begin-time[2,3]
            (setq begin-hh (string-to-number (match-string 1))) 
            (setq begin-mm (string-to-number (match-string 2))) 
            ;; $end-hour      = $end-time[0,1]
            ;; $end-minute    = $end-time[2,3]
            (setq end-hh (string-to-number (match-string 3))) 
            (setq end-mm (string-to-number (match-string 4)))
            ;; $total-hours   = $end-hour - $begin-hour
            ;; $total-minutes = $end-minutes - $begin-minutes
            ;; return $total-hours + ($total-minutes * 0.01666666667)
            (setq diff (/ (- (+ end-mm  ; end minutes
                                (* 60 end-hh))
                             (+ begin-mm ; begin minutes
                                (* 60 begin-hh)))
        (message "Unable to find time strings on consecutive lines.")))
    (when diff
      (insert (number-to-string diff)))))
  1. Paste the above code in the *scratch* buffer and do M-x eval-buffer.
  2. Place the cursor at the beginning of 3rd line as in your example and call M-x my/return-time-diff-frac-hours.
  • -1: I don't think that an answer is the right place to lecture people about what this is supposed to be for or not. We have flags, close votes and comments for that.
    – user227
    May 15, 2015 at 7:28
  • @lunaryorn You're correct. Fixed. May 15, 2015 at 10:55
  • This is wonderful. I had to look up progn, save-excursion and match-string. It also took me a while to understand the structure of the math at the end converting minutes to hours. May 16, 2015 at 20:28
  • This has been a very helpful, functional starting point with Emacs Lisp, and solves a problem I have every day. May 16, 2015 at 20:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.