all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* How to get time difference with Elisp?
@ 2016-07-12 10:46 Karl Voit
  2016-07-12 11:14 ` tomas
  2016-07-12 13:34 ` Karl Voit
  0 siblings, 2 replies; 6+ messages in thread
From: Karl Voit @ 2016-07-12 10:46 UTC (permalink / raw
  To: help-gnu-emacs

Hi!

I need to determine total office hours of a day without the time
spent in lunch break. The source data is officebegin, officeend,
lunchbreakbegin, lunchbreakend - all in string format "HH:MM" like
"14:58".

So far, I failed miserably to find the right combination of
parse-time-string, encode-time, time-substract.

Even determining the difference between only two times resulted in
errors to me:

(setq difference (time-subtract (encode-time (parse-time-string "12:24"))
                                (encode-time (parse-time-string "11:45"))))

... results in: time-subtract: Wrong number of arguments: encode-time, 1

Can you help me? Thanks!

-- 
All in all, one of the most disturbing things today is the definitive
fact that the NSA, GCHQ, and many more government organizations are
massively terrorizing the freedom of us and the next generations.
                                                  http://Karl-Voit.at




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: How to get time difference with Elisp?
  2016-07-12 10:46 Karl Voit
@ 2016-07-12 11:14 ` tomas
  2016-07-12 11:48   ` Karl Voit
  2016-07-12 13:34 ` Karl Voit
  1 sibling, 1 reply; 6+ messages in thread
From: tomas @ 2016-07-12 11:14 UTC (permalink / raw
  To: help-gnu-emacs

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, Jul 12, 2016 at 12:46:37PM +0200, Karl Voit wrote:
> Hi!
> 
> I need to determine total office hours of a day without the time
> spent in lunch break. The source data is officebegin, officeend,
> lunchbreakbegin, lunchbreakend - all in string format "HH:MM" like
> "14:58".
> 
> So far, I failed miserably to find the right combination of
> parse-time-string, encode-time, time-substract.
> 
> Even determining the difference between only two times resulted in
> errors to me:
> 
> (setq difference (time-subtract (encode-time (parse-time-string "12:24"))
>                                 (encode-time (parse-time-string "11:45"))))
> 
> ... results in: time-subtract: Wrong number of arguments: encode-time, 1

The immediate problem is that parse-time-string returns a list of values,
but encode-time expects separate arguments. Apply takes care of that:

      (apply #'encode-time (parse-time-string "12:24"))

etc.

Now the problem is that for your time string day, month, year turn up
as nil, something encode-time doesn't like at all. I guess you'd have
to fill in missing stuff with the values from current-time. Here's
a rough sketch to start with:

  (let ((time-default (decode-time (current-time))))
    (setq difference
      (time-subtract
        (encode-time
          (mapcar* (lambda (x y) (or x y))
            (apply #'encode-time (parse-time-string "12:24"))
            time-default))
        (encode-time
          (mapcar* (lambda (x y) (or x y))
            (apply #'encode-time (parse-time-string "11:45"))
            time-default))

Of course, there might be functions around which make this much simpler.
If not, I think abstracting away some part as a function might enhance
readability a lot.

Note that I used mapcar* which I think is part of cl.

regards
- -- tomás
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iEYEARECAAYFAleE0QEACgkQBcgs9XrR2ka3eQCfYdyZO6g6E0UKND1RgcOkPItV
qPoAn0iFvEQ5ioJphRIA0BbNYHIXgKVA
=71DO
-----END PGP SIGNATURE-----



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: How to get time difference with Elisp?
       [not found] <mailman.1166.1468320413.26859.help-gnu-emacs@gnu.org>
@ 2016-07-12 11:48 ` Emanuel Berg
  0 siblings, 0 replies; 6+ messages in thread
From: Emanuel Berg @ 2016-07-12 11:48 UTC (permalink / raw
  To: help-gnu-emacs

Karl Voit <devnull@Karl-Voit.at> writes:

> I need to determine total office hours of
> a day without the time spent in lunch break.
> The source data is officebegin, officeend,
> lunchbreakbegin, lunchbreakend - all in
> string format "HH:MM" like "14:58".

I have two functions to that end only I think
bigger than in hours and minutes :)

But I think it can be modified to do what you
want by modifying the input arguments, the
output format, and possibly some other things
as well.

Keet it up :)

(defun time-between-times (year1 month1 day1
                           year2 month2 day2)
  (let*((seconds-then  (float-time (encode-time 0 0 0 day1 month1 year1)))
        (seconds-now   (float-time (encode-time 0 0 0 day2 month2 year2)))
        (seconds-diff  (- seconds-now seconds-then)) )
    (format-seconds "%Y, %D" seconds-diff)))

(defun get-time-since (year month day)
  (interactive "nyear: \nnmonth: \nnday: ")
  (message "%s" (format-seconds
                 "%Y, %D"
                 (float-time
                  (time-since (encode-time 0 0 0 day month year)) ))))

Source: http://user.it.uu.se/~embe8573/conf/emacs-init/time-my.el

-- 
underground experts united .... http://user.it.uu.se/~embe8573
Emacs Gnus Blogomatic ......... http://user.it.uu.se/~embe8573/blogomatic
                   - so far: 56 Blogomatic articles -                   


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: How to get time difference with Elisp?
  2016-07-12 11:14 ` tomas
@ 2016-07-12 11:48   ` Karl Voit
  2016-07-12 12:25     ` tomas
  0 siblings, 1 reply; 6+ messages in thread
From: Karl Voit @ 2016-07-12 11:48 UTC (permalink / raw
  To: help-gnu-emacs

Hi Thomas,

* <tomas@tuxteam.de> <tomas@tuxteam.de> wrote:
>
> On Tue, Jul 12, 2016 at 12:46:37PM +0200, Karl Voit wrote:
>> 
>> I need to determine total office hours of a day without the time
>> spent in lunch break. The source data is officebegin, officeend,
>> lunchbreakbegin, lunchbreakend - all in string format "HH:MM" like
>> "14:58".
>> 
>> So far, I failed miserably to find the right combination of
>> parse-time-string, encode-time, time-substract.
>> 
>> Even determining the difference between only two times resulted in
>> errors to me:
>> 
>> (setq difference (time-subtract (encode-time (parse-time-string "12:24"))
>>                                 (encode-time (parse-time-string "11:45"))))
>> 
>> ... results in: time-subtract: Wrong number of arguments: encode-time, 1
>
> The immediate problem is that parse-time-string returns a list of values,
> but encode-time expects separate arguments. 

Ah, I see. How unfortunate.

> Apply takes care of that:
>       (apply #'encode-time (parse-time-string "12:24"))
> etc.
>
> Now the problem is that for your time string day, month, year turn up
> as nil, something encode-time doesn't like at all. 

Grrr. No wonder I could not come up with a solution myself.

> I guess you'd have
> to fill in missing stuff with the values from current-time. Here's
> a rough sketch to start with:
>
>   (let ((time-default (decode-time (current-time))))
>     (setq difference
>       (time-subtract
>         (encode-time
>           (mapcar* (lambda (x y) (or x y))
>             (apply #'encode-time (parse-time-string "12:24"))
>             time-default))
>         (encode-time
>           (mapcar* (lambda (x y) (or x y))
>             (apply #'encode-time (parse-time-string "11:45"))
>             time-default))
>
> Of course, there might be functions around which make this much simpler.
> If not, I think abstracting away some part as a function might enhance
> readability a lot.

I was also thinking of converting "13:49" into UNIX epoch seconds,
calculate arithmetically, and re-convert the result to string.

With your explanation of the issues with the original approach
above, I tend to think that this seems to be the much simpler way to
go.

> Note that I used mapcar* which I think is part of cl.

Is it just me or is this really just a matter of minutes to
implement in *any* other language?

-- 
All in all, one of the most disturbing things today is the definitive
fact that the NSA, GCHQ, and many more government organizations are
massively terrorizing the freedom of us and the next generations.
                                                  http://Karl-Voit.at




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: How to get time difference with Elisp?
  2016-07-12 11:48   ` Karl Voit
@ 2016-07-12 12:25     ` tomas
  0 siblings, 0 replies; 6+ messages in thread
From: tomas @ 2016-07-12 12:25 UTC (permalink / raw
  To: help-gnu-emacs

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Tue, Jul 12, 2016 at 01:48:39PM +0200, Karl Voit wrote:

[...]

> Is it just me or is this really just a matter of minutes to
> implement in *any* other language?

:-)

Only if you are really at home in that language (and if you are
willing to take some shortcuts: what time, exactly, is 14:49?
Today? Yesterday?).

Note that my sketch above would work with fully-specified times
too.

And I'm sure someone knowing her ways with elisp's time functions
will find a much nicer solution that the one I proposed.

regards
- -- t
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iEYEARECAAYFAleE4dMACgkQBcgs9XrR2kY6qgCfcN/NaPAsrHO/ZJFUSxY52Wqu
qDUAn2nGb7ePE+IpCTEFrB4S3opbFTn1
=fUeq
-----END PGP SIGNATURE-----



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: How to get time difference with Elisp?
  2016-07-12 10:46 Karl Voit
  2016-07-12 11:14 ` tomas
@ 2016-07-12 13:34 ` Karl Voit
  1 sibling, 0 replies; 6+ messages in thread
From: Karl Voit @ 2016-07-12 13:34 UTC (permalink / raw
  To: help-gnu-emacs

* Karl Voit <devnull@Karl-Voit.at> wrote:
>
> I need to determine total office hours of a day without the time
> spent in lunch break. The source data is officebegin, officeend,
> lunchbreakbegin, lunchbreakend - all in string format "HH:MM" like
> "14:58".
>
> So far, I failed miserably to find the right combination of
> parse-time-string, encode-time, time-substract.

I chose the path I understood and which tends to be the easiest one:
manually converting everything to seconds, do the calculations, and
re-convert the results to HH:MM format.

Yes, I did not spend effort in error-proning, edge-cases and other
cases than same-day scenarios.

(defun my-extract-minutes-of-hm-string(hm-string)
  "returns the minutes of a string like 9:42 -> 42 (and 0 if there are no minutes)"
  (let (
    ;; minutes is the second element after splitting with ":"
    (minutes (nth 1 (split-string hm-string ":")))
    )
    ;; if there is no second element, return "0" (instead of nil)
    (if (eq minutes 'nil)
    0
      (string-to-number minutes)
      )
    )
  )

(defun my-extract-hours-of-hm-string(hm-string)
  "returns the hours of a string like 9:42 -> 9"
  (string-to-number
   (car
    (split-string hm-string ":")
    )
   )
)

(defun my-hm-string-to-minutes(hm-string)
  "returns the minutes of a string like 2:42 -> 162"
  (let (
    ;; minutes is the second element after splitting with ":"
    (minutes (my-extract-minutes-of-hm-string hm-string))
    (hours (my-extract-hours-of-hm-string hm-string))
    )
    (+ minutes (* hours 60))
    )
  )

(defun my-calculate-office-hour-total(officestart officeend lunchstart lunchend)
  "calculates the total hours:minutes of a work-day depending on time of arrival/leave and lunch break in HH:MM"
  (let (
    (officestartminutes (my-hm-string-to-minutes officestart));; integer of minutes
    (officeendminutes (my-hm-string-to-minutes officeend));; integer of minutes
    (lunchstartminutes (my-hm-string-to-minutes lunchstart));; integer of minutes
    (lunchendminutes (my-hm-string-to-minutes lunchend));; integer of minutes
    )
    (let* (
          (officeminutes (- (- officeendminutes officestartminutes) (- lunchendminutes lunchstartminutes)))
          (officeminutesstring (format-time-string "%H:%M" (seconds-to-time (* 60 officeminutes)) t))
          )
      ;;(message (concat "Minutes epoch: " (number-to-string officeminutes)))
      ;;(message (concat "Minutes string: " officeminutesstring))
      (symbol-value 'officeminutesstring)
      )
    )
  )
;; (my-calculate-office-hour-total "09:57" "17:22" "11:35" "12:08") -> Minutes epoch: 412 | Minutes string: 06:52


Thanks for all the other approaches and snippets - I copied them to
my personal knowledge-collection to learn from them!

-- 
All in all, one of the most disturbing things today is the definitive
fact that the NSA, GCHQ, and many more government organizations are
massively terrorizing the freedom of us and the next generations.
                                                  http://Karl-Voit.at




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-07-12 13:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.1166.1468320413.26859.help-gnu-emacs@gnu.org>
2016-07-12 11:48 ` How to get time difference with Elisp? Emanuel Berg
2016-07-12 10:46 Karl Voit
2016-07-12 11:14 ` tomas
2016-07-12 11:48   ` Karl Voit
2016-07-12 12:25     ` tomas
2016-07-12 13:34 ` Karl Voit

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.