Kuruluş: Saat Saatini saat başı göster

İşyerinde yeni bir müdürümüz var ve o zaman çizelgemizi istiyor. Sorun değil, org-modum var. Bunun dışında, zamanın şu şekilde bildirilmesini ister:

0900-1000 Customer  Project  xMinutes
0900-1000 Customer2 Project2 yMinutes
1000-1100 Customer  Project3 zMinutes

Yani, bir başka deyişle, bir saat içinde üç şey üzerinde zaman geçirirsem, o saat için, harcadığım üç dakika süreyi gösteren üç sıra göstermek ister. Doğal olarak Org dosyamın, farklı müşteriler için bu müşterilere göre alt başlıklar olarak görevleri vardır, bu nedenle teoride bu iki sütun kolay olmalıdır.

Org hacklemede çok deneyimli değilim ve bu şekilde zamanı nasıl kırabileceğimi bilemiyorum. Bu yüzden benim için başkasının yapmasını istediğimi düşündüm :)

Umarım cevap, Org el kitabındaki yüzüme bakmıyor.

** Greenwich Consultancy
   :LOGBOOK:
   CLOCK: [2016-02-18 Thu 10:40]--[2016-02-18 Thu 11:10] =>  0:30
   CLOCK: [2016-01-13 Wed 14:48]--[2016-01-13 Wed 15:29] =>  0:41
   CLOCK: [2016-01-12 Tue 11:00]--[2016-01-12 Tue 16:53] =>  5:53
   :END:
** PU [2/2]
*** DONE Identify PU Open equella block
    CLOSED: [2015-10-26 Mon 09:09]
    :LOGBOOK:
    CLOCK: [2015-10-09 Fri 14:10]--[2015-10-09 Fri 16:06] =>  1:56
    :END:
*** Update UAT 
    :LOGBOOK:
    CLOCK: [2016-02-17 Wed 10:03]--[2016-02-17 Wed 10:16] =>  0:13
    CLOCK: [2015-11-17 Tue 09:12]--[2015-11-17 Tue 09:18] =>  0:06
    CLOCK: [2015-11-16 Mon 14:49]--[2015-11-16 Mon 15:00] =>  0:11
    :END:
*** PSMD Block
    :LOGBOOK:
    CLOCK: [2016-02-26 Fri 16:26]--[2016-02-26 Fri 16:53] =>  0:27
    CLOCK: [2016-02-11 Thu 14:27]--[2016-02-11 Thu 14:47] =>  0:20
    CLOCK: [2016-02-09 Tue 16:17]--[2016-02-09 Tue 16:31] =>  0:14
    CLOCK: [2016-02-09 Tue 14:24]--[2016-02-09 Tue 15:02] =>  0:38
    CLOCK: [2016-02-09 Tue 12:13]--[2016-02-09 Tue 13:01] =>  0:48
    CLOCK: [2016-02-09 Tue 10:15]--[2016-02-09 Tue 10:58] =>  0:43
    CLOCK: [2016-02-05 Fri 14:27]--[2016-02-05 Fri 16:36] =>  2:09
    CLOCK: [2016-02-05 Fri 11:11]--[2016-02-05 Fri 12:02] =>  0:51
    CLOCK: [2016-02-05 Fri 10:36]--[2016-02-05 Fri 10:53] =>  0:17
    CLOCK: [2016-02-03 Wed 09:39]--[2016-02-03 Wed 10:24] =>  0:45
    CLOCK: [2016-02-02 Tue 16:39]--[2016-02-02 Tue 17:00] =>  0:21
    CLOCK: [2016-01-29 Fri 12:27]--[2016-01-29 Fri 12:33] =>  0:06
    :END:       
*** Server tidy
**** STARTED Check TII code on UAT
     :LOGBOOK:
     CLOCK: [2016-02-25 Thu 16:59]--[2016-02-26 Fri 09:22] => 16:23
     :END:
**** DONE Update Coursework M26 branch
     CLOSED: [2016-02-25 Thu 16:59]
     - State "DONE"       from "STARTED"    [2016-02-25 Thu 16:59]
     :LOGBOOK:
     CLOCK: [2016-02-25 Thu 16:56]--[2016-02-25 Thu 16:59] =>  0:03
     :END:   
*** UAT PSMD Roamers problem
    :LOGBOOK:
    CLOCK: [2016-02-25 Thu 11:19]--[2016-02-25 Thu 11:33] =>  0:14
    :END:
*** Gradebook problem
    :LOGBOOK:
    CLOCK: [2016-02-26 Fri 15:35]--[2016-02-26 Fri 16:26] =>  0:51
    :END:

Yani örneğin, çizgi

CLOCK: [2016-02-05 Fri 11:11]--[2016-02-05 Fri 12:02] =>  0:51

İki çıkış satırı üretmelidir (sekmeler veya virgül ayırıcılar ile):

1000-1100 PU PSMD Block 49
1100-1200 PU PSMD Block  2
7
Bu, normal bir zaman çizelgesi üretenler gibi, Org dinamik blok kullanılarak gerçekleştirilir. Nasıl yazılacağını manuel olarak tanımlar . Her ay için iş paketi saatlerini bildirmek için excel uyumlu CSV vermemi sağlayacak bir fonksiyonum var. Sizin durumunuzda, bunlar sadece gerekli olan günlük raporlar mı? Biçim biraz garip ve hantal görünüyor, ancak yapılabilir ... Org dosyanızın müşteri, proje, görev, alt görev açısından nasıl yapılandırıldığına dair küçük bir örnek verebilir misiniz?
katma yazar Ross, kaynak
Dakikaları org-clock-sum ile çıkarmak mümkün olmalıdır. Bir başlık filtresi, başlangıç ​​zamanı ve isteğe bağlı argümanlar olarak durma süresi verilebilir. Doğru hatırladığımda, bu fonksiyonda org 8.2'de sorunlar var ama 8.3.3'te çalışıyor. Bundan emin değilim. Genel sonuç, emacs-version ve org-version kodunuzu da bildirmenizdir.
katma yazar Mike Spivey, kaynak
@Tobias Org 8.3.3 ve Emacs 24.5.1.
katma yazar Shreemay Panhalkar, kaynak
@dfeich Verilerimin küçük bir bölümünü ekledim. Üst düzey başlıklar (yani, tek * seviye) "sprint # 13" veya "Support Work" gibi şeylerdir. İkinci seviye, istemci ve üçüncü + düzeydeki belirli görevlerdir.
katma yazar Shreemay Panhalkar, kaynak

2 cevap

Benim çözümüm Tobias'ınkinden daha kısa değil ve muhtemelen yazmam gerekmiyordu, yan ürünlerden biriyle ilgilenmemiştim: Tüm saat aralıklarını belirli bir zamanda tam başlık bilgileriyle toplayan bir işlev Daha fazla işlemenin temeli olan aralık. Bu fonksiyona ve diğer bazı yardımcılara dayanarak, normal org clocktable bloğu gibi kullanabileceğiniz dinamik bir blok uygularım. Yani, sadece aşağıdakileri yazınız ve BEGIN satırında C-c C-c üzerine basarsanız, tabloya genişleyecektir:

  #+BEGIN: nagora-report :buffer "nagora-example.org" :day 2016-02-05
  #+END:

  #+BEGIN: nagora-report :buffer "nagora-example.org" :day 2016-02-25
  #+END:

Bu iki blok aşağıdakilere genişler:

  #+BEGIN: nagora-report :buffer "nagora-example.org" :day 2016-02-05
  #+CAPTION: timesheet for day 2016-02-05
  |        Time | Customer | Task       | Minutes |
  |-------------+----------+------------+---------|
  | 10:00-11:00 | PU [2/2] | PSMD Block |      17 |
  | 11:00-12:00 | PU [2/2] | PSMD Block |      49 |
  | 12:00-13:00 | PU [2/2] | PSMD Block |       2 |
  | 14:00-15:00 | PU [2/2] | PSMD Block |      33 |
  | 15:00-16:00 | PU [2/2] | PSMD Block |      60 |
  | 16:00-17:00 | PU [2/2] | PSMD Block |      36 |
  |-------------+----------+------------+---------|
  |       TOTAL |          |            |     197 |
  #+TBLFM: @>$>=vsum(@[email protected])
  #+END:

  #+BEGIN: nagora-report :buffer "nagora-example.org" :day 2016-02-25
  #+CAPTION: timesheet for day 2016-02-25
  |        Time | Customer | Task                          | Minutes |
  |-------------+----------+-------------------------------+---------|
  | 11:00-12:00 | PU [2/2] | UAT PSMD Roamers problem      |      14 |
  | 16:00-17:00 | PU [2/2] | STARTED Check TII code on UAT |       1 |
  | 16:00-17:00 | PU [2/2] | Update Coursework M26 branch  |       3 |
  | 17:00-18:00 | PU [2/2] | STARTED Check TII code on UAT |      60 |
  | 18:00-19:00 | PU [2/2] | STARTED Check TII code on UAT |      60 |
  | 19:00-20:00 | PU [2/2] | STARTED Check TII code on UAT |      60 |
  | 20:00-21:00 | PU [2/2] | STARTED Check TII code on UAT |      60 |
  | 21:00-22:00 | PU [2/2] | STARTED Check TII code on UAT |      60 |
  | 22:00-23:00 | PU [2/2] | STARTED Check TII code on UAT |      60 |
  |-------------+----------+-------------------------------+---------|
  |       TOTAL |          |                               |     378 |
  #+TBLFM: @>$>=vsum(@[email protected])
  #+END:

Parantez içindeki sayaçlar istenirse kolayca temizlenebilir. Şu anda dinamik blok bir açık arabellek istiyor (: buffer argümanı) fakat bunu bir dosya yoluna değiştirmek önemsizdir.

Hala bu özel zaman çizelgesi raporlama biçiminde merak ediyorum, çünkü çeviri değişkeni de değil, bu nedenle aynı miktarda iş, bir saatin başında ya da bir süre sonra başlarsanız farklı görünecektir. Ancak bazen yönetim ile tartışmak yerine böyle bir işlevi uygulamak daha kısadır ;-)

Ben bunun yararlı olucağını umuyorum. Kesinlikle biraz temizlenebilir ve daha tutarlı hale getirilebilir.

(defun dfeich/org-clock-get-tr-for-ivl (buffer tstart-str tend-str &optional limit)
  "Return clocking information touching a given time interval."
  (cl-assert (and buffer (get-buffer buffer)) nil "Error: :buffer must be defined")
  (with-current-buffer buffer
    (save-excursion
      (let ((re (concat "^\\(\\*+[ \t]*.*\\)\\|^[ \t]*"
            org-clock-string
            "[ \t]*\\(?:\\(\\[.*?\\]\\)-+\\(\\[.*?\\]\\)\\|=>[ \t]+\\([0-9]+\\):\\([0-9]+\\)\\)"))
        (counter 0)
        (tmphd "BEFORE FIRST HEADING")
        (tstart (org-time-string-to-seconds tstart-str))
        (tend (org-time-string-to-seconds tend-str))
        (limit (or limit (point-max)))
        headings timelst
        lvl title result ts te)
    (goto-char (point-min))
    (cl-block myblock
      (while (re-search-forward re nil t)
        (cond
         ;; found a org heading
         ((match-end 1)
          (if (> (length timelst) 0)
          (setq result (nconc result (list (list
                            (copy-sequence headings)
                            timelst)))))
          (setq tmphd (org-heading-components)
            lvl (car tmphd)
            title (nth 4 tmphd)
            timelst nil)
          ;; maintain a list of the current heading hierarchy
          (cond
           ((> lvl (length headings))
        (setq headings  (nconc headings `(,title))))
           ((= lvl (length headings))
        (setf (nth (1- lvl) headings) title))
           ((< lvl (length headings))
        (setq headings (cl-subseq headings 0 lvl))
        (setf (nth (1- lvl) headings) title))))
         ;; found a clock line with 2 timestamps
         ((match-end 3)
          (setq ts (save-match-data (org-time-string-to-seconds
                     (match-string-no-properties 2)))
            te (save-match-data (org-time-string-to-seconds
                     (match-string-no-properties 3))))
          ;; the clock lines progress from newest to oldest. This
          ;; enables skipping the rest if this condition is true
          (if (> tstart te)
          (if (re-search-forward "^\\(\\*+[ \t]*.*\\)" nil t)
              (beginning-of-line)
            (goto-char (point-max)))
        (when (> tend ts)
          (setq timelst (nconc timelst (list
                        (list (match-string-no-properties 2)
                              (match-string-no-properties 3)))))))))
        (when (>= (point) limit)
          (cl-return-from myblock))))
    (if (> (length timelst) 0)
        (setq result (nconc result (list (list (copy-sequence headings)
                           timelst)))))
    result))))

(defun dfeich/org-slice-tr (tstart-str tend-str cutstart-str cutend-str)
  "Return time slice of a time range in minutes."
  (let ((tstart (org-time-string-to-seconds tstart-str))
    (tend (org-time-string-to-seconds tend-str))
    (cutstart (if (stringp cutstart-str)
              (org-time-string-to-seconds cutstart-str)
            cutstart-str))
    (cutend (if (stringp cutend-str)
            (org-time-string-to-seconds cutend-str)
          cutend-str))
    result)
    (setq result (max 0
              (/  (- (min tend cutend) (max tstart cutstart))
              60)))))

(defun dfeich/org-clock-hourly-report (struct tstart-str tend-str)
  "Return a structure containing a per hour report within an interval."
  (let* ((tstart (org-time-string-to-seconds tstart-str))
     (tend (org-time-string-to-seconds tend-str))
     (delta 3600)
     (intvls (cl-loop for tm from tstart to (- tend delta) by delta
              collect `(,tm ,(+ tm delta))))
     result)
    ;; iterate over the intervals for the final table
    (cl-loop for iv in intvls
         collect (list
              iv
              (let* ((cutstart (car iv))
                 (cutend (cadr iv))
                 (tmsum 0.0)
                 headings trlst)
            ;; iterate over the task structure
            (cl-loop
             for item in struct
             do (progn
                  (setq headings (car item)
                    trlst (cadr item)
                    ;; sum up the parts of the time
                    ;; ranges falling into this
                    ;; interval
                    tmsum (apply
                       #'+
                       (mapcar
                        (lambda (tr)
                          (dfeich/org-slice-tr (car tr)
                                   (cadr tr)
                                   cutstart
                                   cutend))
                        trlst))))
             if (> tmsum 0) collect `(,headings ,tmsum) into lst
             finally return lst))))))

(defun org-dblock-write:nagora-report (params)
 "Fill in a dynamic timesheet reporting block."
  (let* ((buffer (plist-get params :buffer))
     (day (symbol-name (plist-get params :day)))
     (tstart (if (string-match-p "^[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}$" day)
             day
           (error "Error: day format must be in YYYY-mm-dd format")))
     (tend (concat day " 23:59"))
     (table (dfeich/org-clock-hourly-report
         (dfeich/org-clock-get-tr-for-ivl buffer tstart tend)
         tstart tend)))
    (insert (format "#+CAPTION: timesheet for day %s\n" day))
    (insert "|Time|Customer| Task |Minutes|\n|------\n")
    (cl-loop
     for item in table
     do (let ((ivl (car item))
          (entries (cadr item)))
      (cl-loop for e in entries
           do (let ((headings (car e))
                (minutes (cadr e)))
            (insert (concat
                 "|"
                 (format-time-string "%H:%M" (seconds-to-time
                                  (car ivl)))
                 "-"
                 (format-time-string "%H:%M" (seconds-to-time
                                  (cadr ivl)))
                 "|" (nth 1 headings)
                 "|" (car (last headings))
                 "|" (format "%d" minutes)
                 "|\n"))))))
    (insert "|----\n|TOTAL||||\n#+TBLFM: @>$>=vsum(@[email protected])")
    (search-backward "Time")
    (org-table-align)
    (org-table-recalculate '(16))))

Not: Çözüm, org-clock-sum kodundan esinlenerek ve tam org ayrıştırıcılarını çağırmamayı tercih ettiğim işleve benzer, fakat ben muhtemelen daha verimli bir doğrudan ayrıştırma kullanmak istiyorum çünkü sadece başlıkları ve saat çizgilerini ilgilendirir.

Regexp arama işlevi, bir başlık veya saat zaman aralığıyla eşleşen bir "veya" -ed regexp'i içeren org-clock-sum 'dan kopyalanmış ilginç bir kavram kullanır. Bu fikir çok hoş, çünkü bu şekilde tek bir regexp ile basit bir durum makinesinin uygulanmasına izin veriyor.

5
katma
@Tobias: Profil vermedim ve normal dosyalar için performans açısından büyük bir şey olmadığı da iyi olabilir. İlginç görünen önbellek mekanizmasına bakmam lazım. Fonksiyonu, kendi kullanımım için kısmen, 1-2 yıl boyunca saat bilgisi biriktiren dokümanlar içeren dokümanları hazırladığım şekilde yazdım. Saatli zamanlar en yeni saat aralığından en eskiye doğru ilerlediğinden, bütünü ayrıştırmak yerine hedef zaman aralığınızda artık bir saate ulaştığınızda ayrışmayı durdurabilirsiniz.
katma yazar Ross, kaynak
@ tobias ve nagora: Teşekkürler ve hoş geldiniz. Tobias'ın bir dizi güzel ekleme yaptığını belirttim. Aynı görevin bir saat içinde toplanması. Ayrıca, elisp kodunun StackExchange'de doğru bir şekilde nasıl işaretlendiğini yazımın düzenlemesinden öğrendim. Teşekkürler!
katma yazar Ross, kaynak
Kuruluş ayrıştırıcı önbellekleme ile çalışır ve çok büyük performans kayıpları getirmemelidir. Önbelleğe alma işleminin ne kadar uzandığını kontrol etmedim. Örneğin: Org'ın cedet/wisent gibi kısmi ayrıştırıcı olup olmadığını bilmiyorum. Böyle bir kısmi ayrıştırıcıyla, bir bölümünün düzenlenmiş olması durumunda belgenin tamamını yeniden dağıtmak gerekli değildir.
katma yazar Mike Spivey, kaynak
Aynı projenin dakikalarını aynı saatte topladığınızı kaydettim ve bunu benimki haline getirdim. Teşekkürler. Farklı projeler için saat öğeleri birbirine göre sıralanmaz. Bu nedenle, önce her şeyi topladım ve daha sonra w.r.t. saat aralıklarının başlangıcı. Sıralama n * log (n), diğer tüm şeylerin n sipariş maliyetine (hatta ayrıştırma) sahip olma maliyetine sahiptir. Sıralı listede çalışıyorum. Saatte bitecek iş öğelerini reddediyorum. Sadece gerçekten iş kalemleri var ise, sadece bir sonraki saat olarak (kalan) listedeki ilk öğenin saatini alırsam, saati artırırım.
katma yazar Mike Spivey, kaynak
Teşekkürler. Zengin bir utanç. Perşembe günü yönetim ekibiyle bir toplantı yaptık, bütün gelişim ekibi formattan şikayet etti, ancak bütçeye katlanmayacaklardı.
katma yazar Shreemay Panhalkar, kaynak
@dfeich size kene veriyorum çünkü bu kodu, Tobias’ın göreceli olarak küçük olan diğer ihtiyaçlara uyacak şekilde değiştirmesinden daha kolay buldum. Bana çok anlamsız bir çaba harcadı. Teşekkürler.
katma yazar Shreemay Panhalkar, kaynak

Aşağıdaki kodda tanımlanan org-time-sheet komutu, belirttiğiniz neredeyse . M-x org-time-sheet ile etkileşimli olarak çağırırsanız, başlangıç ​​ve bitiş zamanını da ayarlayabilirsiniz. Bu zaman aralığından başlayan sadece saat girişleri zaman çizelgesine dahil edilir.

" Hemen hemen " ile ilgili bazı kelimeler:

  1. You did not specify how you differentiate between efforts on different days. org-time-sheet writes the date in the first column when it starts a new day.
  2. It is better to write out an org-table instead of inserting commas or tabs as separators. You can then put point into the table and call the menu-point Tbl -> Export to export to whatever format is supported (e.g., csv-format).
  3. Currently, I also insert a start and a end timestamp into the first two columns of the table. This makes easier for you to check whether you get what you want. When you believe that you get what you want you can customize the function org-time-sheet-time-formatter. Just remove the formatted minutes-start and minutes-end.

DÜZENLEME:

  1. Aynı saatteki aynı proje için zaman açıklıkları artık varsayılan olarak toplanıyor. Önek argümanıyla org-time-sheet 'i çağırırsanız, bu zaman dilimleri ayrı olarak listelenir.
  2. Org-time-sheet öğesini etkileşimli olarak çağırırsanız zaman çizelgesi, noktaya eklenir. Önceden, bir sonraki kod bloğundan sonra zaman çizelgesi yerleştirildi.
(defcustom org-time-sheet-date-formatter
  (lambda (day month year) (format "%4d-%02d-%02d" year month day))
  "Function to format date in time sheets.
It takes three numbers as arguments: day month year."
  :type 'function
  :group 'org-clock)

(defcustom org-time-sheet-time-formatter
  (lambda (start end hour minutes headings)
    (list (format-time-string "%F %R" (apply 'encode-time minutes-start))
          (format-time-string "%F %R" (apply 'encode-time minutes-end))
          (format "%2d00--%2d00" hour (1+ hour)) (or (nth 1 headings) "") (or (nth 2 headings) "") minutes))
  "Callback function returning one table line in a time sheet (as list).
The arguments of the function are:
START:    start time with format as in `decode-time'
END:     end time with format as in `decode-time'
MINUTES:  number of minutes between start time and end time
HEADINGS: the heading titles of the current entry and all its parents as a list starting with the top-parent."
  :type 'function
  :group 'org-clock)

(eval-when-compile
  (require 'cl-lib))
(require 'org-element)
(require 'ob-core)

(defun org-element-parent (element &optional type)
  "Get parent of ELEMENT or nil if there is none.
If TYPE is non-nil get next parent of that type."
  (let* ((props (cadr element))
         (parent (plist-get props :parent)))
    (if type
        (when parent
          (if (eq (car parent) type)
              parent
            (org-element-parent parent type)))
      parent)))

(defun org-element-timestamp-less-p (ts1 ts2 &optional end)
  "Non-nil if timestamp TS1 is less than timestamp TS2.
TS1 and TS2 is timestamp data as returned by `org-element-timestamp-parser'.
If end is non-nil the end-time of TS1 and TS2 is compared else the start time."
  (cl-assert (eq (car ts1) 'timestamp) "TS1 is not a timestamp")
  (cl-assert (eq (car ts2) 'timestamp) "TS2 is not a timestamp")
  (let ((p1 (cadr ts1))
    (p2 (cadr ts2))
    (tests '("year" "month" "day" "hour" "minute"))
    ret)
    (while (and (let* ((what (intern-soft (concat ":" (car tests) (if end "-end" "-start"))))
               (t1 (plist-get p1 what))
               (t2 (plist-get p2 what)))
          (cond
           ((< t1 t2)
            (setq ret t)
            nil)
           ((= t1 t2) t)))
        (setq tests (cdr tests))))
    ret))

(defun time-day-month-year (time)
  "Return the list (day month year) from TIME.
TIME may be the time as returned by `current-time' or by `decode-time'."
  (if (<= (length time) 4)
      (setq time (decode-time time)))
  (mapcar (lambda (el) (nth el time)) '(3 4 5)))

(defun org-element-timestamp-to-time (timestamp &optional start/end encode)
  "Convert start or end of TIMESTAMP returned by `org-element-timestamp-parser'
to time format as defined in the documentation of `decode-time'.
START/END is either the symbol 'start or 'end or nil which is equivalent to 'start.
If ENCODE is non-nil the return value is encoded as described in the documentation for `current-time'."
  (cl-assert (eq (car timestamp) 'timestamp) "Argument is not a timestamp")
  (unless start/end (setq start/end 'start))
  (let* ((p (cadr timestamp))
     (ret (append
           '(0)
           (mapcar (lambda (what) (plist-get p (intern-soft (concat ":" what "-" (symbol-name start/end))))) '("minute" "hour" "day" "month" "year"))
           (list 0 nil (car (current-time-zone))))))
    (if encode
    (apply #'encode-time ret)
      ret)))

(defmacro decoded-time-complete-timezone (t1 t2)
  "If only one of the time specifications T1 and T2 has time-zone information
append that to the other one."
  `(let ((n1 (length ,t1))
         (n2 (length ,t2)))
     (cond
      ((> n1 n2)
       (setq ,t2 (copy-sequence ,t2))
       (setf (nthcdr n2 ,t2) (nthcdr n2 ,t1)))
      ((< n1 n2)
       (setq ,t1 (copy-sequence ,t1))
       (setf (nthcdr n1 ,t1) (nthcdr n1 ,t2))))))

(defun decoded-time-less-p (t1 t2)
  "Like `time-less-p' but for decoded time values as `decode-time' returns."
  (decoded-time-complete-timezone t1 t2)
  (time-less-p (apply 'encode-time t1) (apply 'encode-time t2)))

(defun decoded-time-advance (time dt)
  "Return TIME advanced by DT but for decoded time values as `decode-time' returns.
The time zone information of time is used for the result."
  (decode-time (apply 'encode-time (append (cl-mapcar #'+ (butlast time (- (length time) 6)) (butlast dt (- (length dt) 6))) (nthcdr 6 time)))))

(defun org-time-sheet (&optional tStart tEnd dont-sum)
  "Create time sheet for time span from tStart to tEnd from current org buffer.
When called non-interactively each of the parameters tStart and tEnd may be nil
or must be decoded time (see `decode-time').
Do not sum up minutest of a project within an hour if dont-sum is non-nil.
Interactively do not sum if called with prefix arg."
   (interactive (list
                 (decode-time (org-read-date t t nil "Start time:" '(0 0)))
                 (decode-time (org-read-date t t nil "End time:"))
         current-prefix-arg))
   (org-time-sheet-shedule (org-time-sheet-collect tStart tEnd) (called-interactively-p 'any) dont-sum))

(defun org-time-sheet-collect (tStart tEnd)
  "Returns ordered time sheet collection of current buffer
for clocked items with start time within the range from tStart to tEnd."
  (if (> (length tStart) 4)
      (setq tStart (apply 'encode-time tStart)))
  (if (> (length tEnd) 4)
      (setq tEnd (apply 'encode-time tEnd)))
   (let ((tree (org-element-parse-buffer)))
     (cl-stable-sort 
      (org-element-map tree 'clock
        (lambda (clock)
          ;; get the relevant data of the clocks
          (let* ((timestamp (plist-get (cadr clock) :value))
                 (parent clock)
                 (headers (nreverse (cl-loop while (setq parent (org-element-parent parent 'headline)) collect (car (plist-get (cadr parent) :title))))))
            (cl-assert timestamp nil "Clock line without timestamp")
            (when (and (or (null tStart) (null (time-less-p (org-element-timestamp-to-time timestamp 'start t) tStart)))
                       (or (null tEnd) (time-less-p (org-element-timestamp-to-time timestamp 'end t) tEnd)))
              (list (org-element-timestamp-to-time timestamp 'start)
                    (org-element-timestamp-to-time timestamp 'end)
                    headers))
            )))
      #'time-less-p
      :key (lambda (clock) (apply 'encode-time (car clock))))))

(defun org-time-sheet-shedule (clocks &optional interactive dont-sum)
  "Creates time sheet shedule from ordered time sheet clock collection (see `org-time-sheet-collect')."
     ;; sheduling
     (when clocks
       (setq clocks (cons nil clocks))
       (let* ((start (copy-sequence (caadr clocks)))
              (day-month-year (time-day-month-year start))
              (shedule (list (list (apply org-time-sheet-date-formatter day-month-year)))))
         (setf (nth 1 start) 0) ;; clear minutes
         (while (cdr clocks)
           (let ((end (decoded-time-advance start '(0 0 1 0 0 0)))
         project-alist
                 (iter clocks))
             (while (decoded-time-less-p (cl-caadr iter) end) ;; collect clocks starting before the end of current hour
               (let* ((start-time (cl-caadr iter))
                      (end-time (cl-cadadr iter))
                      (minutes-start (if (decoded-time-less-p start-time start) start start-time))
                      (minutes-end (if (decoded-time-less-p end end-time) end end-time))
              (minutes (/ (nth 1 (time-subtract (apply 'encode-time minutes-end) (apply 'encode-time minutes-start))) 60))
                      (headlines (nth 2 (cadr iter)))
              (project (assoc headlines project-alist)))
         (if (and project (null dont-sum))
             (setcdr project (list (+ (cadr project) minutes) minutes-start minutes-end))
           (setq project-alist (cons (list headlines minutes minutes-start minutes-end) project-alist)))
                 (if (decoded-time-less-p end end-time)
                     (setq iter (cdr iter))
                   ;; delete clock that also finishes in this hour:
                   (setcdr iter (cddr iter))) ;; delete clock entry
                 ))
         (setq project-alist (nreverse project-alist))
         ;; Compose shedule for hour:
         (while project-alist
           (let ((headlines (caar project-alist))
             (minutes (nth 1 (car project-alist)))
             (minutes-start (nth 2 (car project-alist)))
             (minutes-end (nth 3 (car project-alist))))
         (setq shedule (cons (funcall org-time-sheet-time-formatter minutes-start minutes-end (nth 2 start) minutes headlines) shedule)))
           (setq project-alist (cdr project-alist)))
             ;; calculate new time:
             (when (cdr clocks)
               (let ((next-hour-start-time (decoded-time-advance start '(0 0 1 0 0 0)))
                     (next-hour-end-time (decoded-time-advance start '(0 0 2 0 0 0))))
                 (setq start (copy-sequence (caadr clocks)))
                 (setf (nth 1 start) 0) ;; minutes
                 (when (decoded-time-less-p start next-hour-end-time)
                   (setq start next-hour-start-time))
                 (let ((new-day-month-year (time-day-month-year start)))
                   (unless (equal day-month-year new-day-month-year)
                     (setq shedule (cons (list (apply org-time-sheet-date-formatter new-day-month-year)) shedule)
                           day-month-year new-day-month-year)))))))
         (setq shedule (nreverse shedule))
         (when interactive
       (insert (with-temp-buffer
             (insert "#+begin_src emacs-lisp\n#+end_src\n")
             (let ((pt (point)))
               (org-babel-insert-result shedule)
               (delete-region (point-min) pt))
             (buffer-string))))
         shedule)))

Örneğiniz için aşağıdaki çıktıyı alırsınız:

| 2015-10-09       |                  |            |                       |                                |    |
| 2015-10-09 15:10 | 2015-10-09 16:00 | 1400--1500 | PU                    | Identify PU Open equella block | 50 |
| 2015-10-09 16:00 | 2015-10-09 17:00 | 1600--1700 | PU                    | Identify PU Open equella block | 60 |
| 2015-10-09 17:00 | 2015-10-09 17:06 | 1700--1800 | PU                    | Identify PU Open equella block |  6 |
| 2015-11-16       |                  |            |                       |                                |    |
| 2015-11-16 14:49 | 2015-11-16 15:00 | 1400--1500 | PU                    | Update UAT                     | 11 |
| 2015-11-17       |                  |            |                       |                                |    |
| 2015-11-17 09:12 | 2015-11-17 09:18 |  900--1000 | PU                    | Update UAT                     |  6 |
| 2016-01-12       |                  |            |                       |                                |    |
| 2016-01-12 11:00 | 2016-01-12 12:00 | 1100--1200 | Greenwich Consultancy |                                | 60 |
| 2016-01-12 12:00 | 2016-01-12 13:00 | 1200--1300 | Greenwich Consultancy |                                | 60 |
| 2016-01-12 13:00 | 2016-01-12 14:00 | 1300--1400 | Greenwich Consultancy |                                | 60 |
| 2016-01-12 14:00 | 2016-01-12 15:00 | 1400--1500 | Greenwich Consultancy |                                | 60 |
| 2016-01-12 15:00 | 2016-01-12 16:00 | 1500--1600 | Greenwich Consultancy |                                | 60 |
| 2016-01-12 16:00 | 2016-01-12 16:53 | 1600--1700 | Greenwich Consultancy |                                | 53 |
| 2016-01-13       |                  |            |                       |                                |    |
| 2016-01-13 14:48 | 2016-01-13 15:00 | 1400--1500 | Greenwich Consultancy |                                | 12 |
| 2016-01-13 15:00 | 2016-01-13 15:29 | 1500--1600 | Greenwich Consultancy |                                | 29 |
| 2016-01-29       |                  |            |                       |                                |    |
| 2016-01-29 12:27 | 2016-01-29 12:33 | 1200--1300 | PU                    | PSMD Block                     |  6 |
| 2016-02-02       |                  |            |                       |                                |    |
| 2016-02-02 16:39 | 2016-02-02 17:00 | 1600--1700 | PU                    | PSMD Block                     | 21 |
| 2016-02-03       |                  |            |                       |                                |    |
| 2016-02-03 09:39 | 2016-02-03 10:00 |  900--1000 | PU                    | PSMD Block                     | 21 |
| 2016-02-03 10:00 | 2016-02-03 10:24 | 1000--1100 | PU                    | PSMD Block                     | 24 |
| 2016-02-05       |                  |            |                       |                                |    |
| 2016-02-05 10:36 | 2016-02-05 10:53 | 1000--1100 | PU                    | PSMD Block                     | 17 |
| 2016-02-05 11:11 | 2016-02-05 12:00 | 1100--1200 | PU                    | PSMD Block                     | 49 |
| 2016-02-05 12:00 | 2016-02-05 12:02 | 1200--1300 | PU                    | PSMD Block                     |  2 |
| 2016-02-05 14:27 | 2016-02-05 15:00 | 1400--1500 | PU                    | PSMD Block                     | 33 |
| 2016-02-05 15:00 | 2016-02-05 16:00 | 1500--1600 | PU                    | PSMD Block                     | 60 |
| 2016-02-05 16:00 | 2016-02-05 16:36 | 1600--1700 | PU                    | PSMD Block                     | 36 |
| 2016-02-09       |                  |            |                       |                                |    |
| 2016-02-09 10:15 | 2016-02-09 10:58 | 1000--1100 | PU                    | PSMD Block                     | 43 |
| 2016-02-09 12:13 | 2016-02-09 13:00 | 1200--1300 | PU                    | PSMD Block                     | 47 |
| 2016-02-09 13:00 | 2016-02-09 13:01 | 1300--1400 | PU                    | PSMD Block                     |  1 |
| 2016-02-09 14:24 | 2016-02-09 15:00 | 1400--1500 | PU                    | PSMD Block                     | 36 |
| 2016-02-09 15:00 | 2016-02-09 15:02 | 1500--1600 | PU                    | PSMD Block                     |  2 |
| 2016-02-09 16:17 | 2016-02-09 16:31 | 1600--1700 | PU                    | PSMD Block                     | 14 |
| 2016-02-11       |                  |            |                       |                                |    |
| 2016-02-11 14:27 | 2016-02-11 14:47 | 1400--1500 | PU                    | PSMD Block                     | 20 |
| 2016-02-17       |                  |            |                       |                                |    |
| 2016-02-17 10:03 | 2016-02-17 10:16 | 1000--1100 | PU                    | Update UAT                     | 13 |
| 2016-02-18       |                  |            |                       |                                |    |
| 2016-02-18 10:40 | 2016-02-18 11:00 | 1000--1100 | Greenwich Consultancy |                                | 20 |
| 2016-02-18 11:00 | 2016-02-18 11:10 | 1100--1200 | Greenwich Consultancy |                                | 10 |
| 2016-02-25       |                  |            |                       |                                |    |
| 2016-02-25 11:19 | 2016-02-25 11:33 | 1100--1200 | PU                    | UAT PSMD Roamers problem       | 14 |
| 2016-02-25 16:56 | 2016-02-25 16:59 | 1600--1700 | PU                    | Server tidy                    |  3 |
| 2016-02-25 16:59 | 2016-02-25 17:00 | 1600--1700 | PU                    | Server tidy                    |  1 |
| 2016-02-25 17:00 | 2016-02-25 18:00 | 1700--1800 | PU                    | Server tidy                    | 60 |
| 2016-02-25 18:00 | 2016-02-25 19:00 | 1800--1900 | PU                    | Server tidy                    | 60 |
| 2016-02-25 19:00 | 2016-02-25 20:00 | 1900--2000 | PU                    | Server tidy                    | 60 |
| 2016-02-25 20:00 | 2016-02-25 21:00 | 2000--2100 | PU                    | Server tidy                    | 60 |
| 2016-02-25 21:00 | 2016-02-25 22:00 | 2100--2200 | PU                    | Server tidy                    | 60 |
| 2016-02-25 22:00 | 2016-02-25 23:00 | 2200--2300 | PU                    | Server tidy                    | 60 |
| 2016-02-25 23:00 | 2016-02-26 00:00 | 2300--2400 | PU                    | Server tidy                    | 60 |
| 2016-02-26       |                  |            |                       |                                |    |
| 2016-02-26 00:00 | 2016-02-26 01:00 |  000-- 100 | PU                    | Server tidy                    | 60 |
| 2016-02-26 01:00 | 2016-02-26 02:00 |  100-- 200 | PU                    | Server tidy                    | 60 |
| 2016-02-26 02:00 | 2016-02-26 03:00 |  200-- 300 | PU                    | Server tidy                    | 60 |
| 2016-02-26 03:00 | 2016-02-26 04:00 |  300-- 400 | PU                    | Server tidy                    | 60 |
| 2016-02-26 04:00 | 2016-02-26 05:00 |  400-- 500 | PU                    | Server tidy                    | 60 |
| 2016-02-26 05:00 | 2016-02-26 06:00 |  500-- 600 | PU                    | Server tidy                    | 60 |
| 2016-02-26 06:00 | 2016-02-26 07:00 |  600-- 700 | PU                    | Server tidy                    | 60 |
| 2016-02-26 07:00 | 2016-02-26 08:00 |  700-- 800 | PU                    | Server tidy                    | 60 |
| 2016-02-26 08:00 | 2016-02-26 09:00 |  800-- 900 | PU                    | Server tidy                    | 60 |
| 2016-02-26 09:00 | 2016-02-26 09:22 |  900--1000 | PU                    | Server tidy                    | 22 |
| 2016-02-26 15:35 | 2016-02-26 16:00 | 1500--1600 | PU                    | Gradebook problem              | 25 |
| 2016-02-26 16:00 | 2016-02-26 16:26 | 1600--1700 | PU                    | Gradebook problem              | 26 |
| 2016-02-26 16:26 | 2016-02-26 16:53 | 1600--1700 | PU                    | PSMD Block                     | 27 |
5
katma
@Nagora Bu soruyu, bundan daha şık bir çözüm olup olmadığını görmek için mümkün olduğu kadar açık tutmayı öneririm. Çözüm olarak kabul edebileceğiniz ve çözümüm bana biraz iş çıkarsa bile 'den öğrenebileceğim zarif bir üçlü elde ederseniz çok sevinirim. Yine de, kimse daha iyi bir şeyle karşılaşmazsa, en azından bu canavarlığa sahip olmalısınız ;-).
katma yazar Mike Spivey, kaynak
Hmm, "Sunucu Düzenli" yi düzgün bir şekilde kapatmamış gibi görünüyor. Her neyse, bu harika bir şey. Kodun miktarına şaşırdım, ama en azından kendim için çalışmadığı için kendimi aptal gibi hissetmiyorum. Birkaç test çalışması yapacağım ve bir tane nasıl aldığımı göreceğim. Çok teşekkürler.
katma yazar Shreemay Panhalkar, kaynak
Teşekkürler, ama diğer cevabı aldım kod çalışmayı daha kolay buldum. Zaten çaba için çok teşekkürler.
katma yazar Shreemay Panhalkar, kaynak