0

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
1430   
.5 
  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 '15 at 17:27
  • So far I just have made a ruby/pseudocode of what I would like to achieve – Charley Ramm May 14 '15 at 20:08
  • I haven't written a lisp function before – Charley Ramm May 14 '15 at 20:09
  • adding pseudo code to the question now. how should I approach this with Emacs? – Charley Ramm May 14 '15 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 – Charley Ramm May 16 '15 at 20:48
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 ()
  (interactive)
  (let (begin-hh begin-mm end-hh end-mm diff)
    (save-excursion
      ;; $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]\\)"
                                      "\\(?:.*\n\\)"
                                      "\\([0-2][0-9]\\)\\([0-5][0-9]\\)"
                                      "\\(.*\n\\)"
                                      ) nil :noerror)
          (progn
            ;; $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)))
                          60.0)))
        (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. – lunaryorn May 15 '15 at 7:28
  • @lunaryorn You're correct. Fixed. – Kaushal Modi May 15 '15 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. – Charley Ramm May 16 '15 at 20:28
  • This has been a very helpful, functional starting point with Emacs Lisp, and solves a problem I have every day. – Charley Ramm May 16 '15 at 20:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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