emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Some useful timestamp s-expressions
@ 2010-08-18 20:22 Paul Sexton
  2010-08-18 22:47 ` Noorul Islam K M
  2010-08-21 17:26 ` Manish
  0 siblings, 2 replies; 4+ messages in thread
From: Paul Sexton @ 2010-08-18 20:22 UTC (permalink / raw)
  To: emacs-orgmode

In org, timestamps can be in the usual angle-bracket format,
eg <2010-08-19 +2w>, or you can use lisp s-expressions. These are in the same
format as the s-expressions used in the 'diary'/'calendar' emacs packages. I
only discovered these recently but have been able to use them to schedule some
complex recurring items. I thought I would share the code here.

1. Recurring items with a limited number of occurrences

For example, say you are taking night classes in Spanish. The class is every
Wednesday evening at 7pm, starting on 18 August, and runs for 8 weeks. AFAIK
Org's timestamps do not support limited occurrences of recurrent items -- you
have to schedule the item with infinite recurrences, then delete it when it
finishes.

To schedule the Spanish classes, put the following in your .emacs:

(defun diary-limited-cyclic (recurrences interval m d y)
  "For use in emacs diary. Cyclic item with limited number of recurrences.
Occurs every INTERVAL days, starting on YYYY-MM-DD, for a total of
RECURRENCES occasions."
  (let ((startdate (calendar-absolute-from-gregorian (list m d y)))
        (today (calendar-absolute-from-gregorian date)))
    (and (not (minusp (- today startdate)))
         (zerop (% (- today startdate) interval))
         (< (floor (- today startdate) interval) recurrences))))

The item in the org file looks like this:


** 19:00-21:00 Spanish lessons
<%%(diary-limited-cyclic 8 7 8 18 2010)>


2. Public holiday that is "the nearest Monday to DATE"

In New Zealand each regional capital has an "Anniversary Day". The date of 
Auckland's anniversary day is "the nearest Monday to 29 January". 

Put this in your .emacs:

(defun calendar-nearest-to (target-dayname target-day target-month)
  "Recurring event that occurs in the nearest TARGET-DAYNAME to
the date TARGET-DAY, TARGET-MONTH each year."
  (interactive)
  (let* ((dayname (calendar-day-of-week date))
         (target-date (list target-month target-day (calendar-extract-year date)))
         (days-diff (abs (- (calendar-day-number date)
                            (calendar-day-number target-date)))))
    (and (= dayname target-dayname)
         (< days-diff 4))))

Now we can schedule Auckland Anniversary Day. The first argument, 1, means
Monday (days of the week are numbered starting with Sunday=0).


*** Auckland Anniversary Day
<%%(calendar-nearest-to 1 29 1)>


3. Public holiday on "the 4th Monday in October".

This does not require any additions to .emacs:


*** Labour Day (NZ)
<%%(diary-float 10 1 4)>


4. Easter

Easter's date moves around from year to year according to a complicated set of
criteria which I do not claim to understand. However the following code will
allow you to schedule recurring events relative to Easter sunday.

Note: the function da-easter is from:
http://github.com/soren/elisp/blob/master/da-kalender.el

Put the following in your .emacs:

(defun da-easter (year)
  "Calculate the date for Easter Sunday in YEAR. Returns the date in the
Gregorian calendar, ie (MM DD YY) format."
  (let* ((century (1+ (/ year 100)))
         (shifted-epact (% (+ 14 (* 11 (% year 19))
                              (- (/ (* 3 century) 4))
                              (/ (+ 5 (* 8 century)) 25)
                              (* 30 century))
                           30))
         (adjusted-epact (if (or (= shifted-epact 0)
                                 (and (= shifted-epact 1)
                                      (< 10 (% year 19))))
                             (1+ shifted-epact)
                           shifted-epact))
         (paschal-moon (- (calendar-absolute-from-gregorian
                           (list 4 19 year))
                          adjusted-epact)))
    (calendar-dayname-on-or-before 0 (+ paschal-moon 7))))


(defun da-easter-gregorian (year)
  (calendar-gregorian-from-absolute (da-easter year)))

(defun calendar-days-from-easter ()
  "When used in a diary sexp, this function will calculate how many days
are between the current date (DATE) and Easter Sunday."
  (- (calendar-absolute-from-gregorian date)
     (da-easter (calendar-extract-year date))))

Now we can schedule the public holidays associated with Easter as 
recurring events. Good Friday is 2 days before "Easter", Easter Monday is one
day after.


*** Good Friday
<%%(= -2 (calendar-days-from-easter))>

*** Easter Sunday
<%%(= 0 (calendar-days-from-easter))>

*** Easter Monday
<%%(= 1 (calendar-days-from-easter))>


Paul

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

* Re: Some useful timestamp s-expressions
  2010-08-18 20:22 Some useful timestamp s-expressions Paul Sexton
@ 2010-08-18 22:47 ` Noorul Islam K M
  2010-08-18 23:19   ` Daniel Martins
  2010-08-21 17:26 ` Manish
  1 sibling, 1 reply; 4+ messages in thread
From: Noorul Islam K M @ 2010-08-18 22:47 UTC (permalink / raw)
  To: Paul Sexton; +Cc: emacs-orgmode@gnu.org

I think it will be great if this goes into worg?

- Noorul

On Aug 19, 2010, at 1:52 AM, Paul Sexton <psexton@xnet.co.nz> wrote:

> In org, timestamps can be in the usual angle-bracket format,
> eg <2010-08-19 +2w>, or you can use lisp s-expressions. These are in the same
> format as the s-expressions used in the 'diary'/'calendar' emacs packages. I
> only discovered these recently but have been able to use them to schedule some
> complex recurring items. I thought I would share the code here.
> 
> 1. Recurring items with a limited number of occurrences
> 
> For example, say you are taking night classes in Spanish. The class is every
> Wednesday evening at 7pm, starting on 18 August, and runs for 8 weeks. AFAIK
> Org's timestamps do not support limited occurrences of recurrent items -- you
> have to schedule the item with infinite recurrences, then delete it when it
> finishes.
> 
> To schedule the Spanish classes, put the following in your .emacs:
> 
> (defun diary-limited-cyclic (recurrences interval m d y)
>  "For use in emacs diary. Cyclic item with limited number of recurrences.
> Occurs every INTERVAL days, starting on YYYY-MM-DD, for a total of
> RECURRENCES occasions."
>  (let ((startdate (calendar-absolute-from-gregorian (list m d y)))
>        (today (calendar-absolute-from-gregorian date)))
>    (and (not (minusp (- today startdate)))
>         (zerop (% (- today startdate) interval))
>         (< (floor (- today startdate) interval) recurrences))))
> 
> The item in the org file looks like this:
> 
> 
> ** 19:00-21:00 Spanish lessons
> <%%(diary-limited-cyclic 8 7 8 18 2010)>
> 
> 
> 2. Public holiday that is "the nearest Monday to DATE"
> 
> In New Zealand each regional capital has an "Anniversary Day". The date of 
> Auckland's anniversary day is "the nearest Monday to 29 January". 
> 
> Put this in your .emacs:
> 
> (defun calendar-nearest-to (target-dayname target-day target-month)
>  "Recurring event that occurs in the nearest TARGET-DAYNAME to
> the date TARGET-DAY, TARGET-MONTH each year."
>  (interactive)
>  (let* ((dayname (calendar-day-of-week date))
>         (target-date (list target-month target-day (calendar-extract-year date)))
>         (days-diff (abs (- (calendar-day-number date)
>                            (calendar-day-number target-date)))))
>    (and (= dayname target-dayname)
>         (< days-diff 4))))
> 
> Now we can schedule Auckland Anniversary Day. The first argument, 1, means
> Monday (days of the week are numbered starting with Sunday=0).
> 
> 
> *** Auckland Anniversary Day
> <%%(calendar-nearest-to 1 29 1)>
> 
> 
> 3. Public holiday on "the 4th Monday in October".
> 
> This does not require any additions to .emacs:
> 
> 
> *** Labour Day (NZ)
> <%%(diary-float 10 1 4)>
> 
> 
> 4. Easter
> 
> Easter's date moves around from year to year according to a complicated set of
> criteria which I do not claim to understand. However the following code will
> allow you to schedule recurring events relative to Easter sunday.
> 
> Note: the function da-easter is from:
> http://github.com/soren/elisp/blob/master/da-kalender.el
> 
> Put the following in your .emacs:
> 
> (defun da-easter (year)
>  "Calculate the date for Easter Sunday in YEAR. Returns the date in the
> Gregorian calendar, ie (MM DD YY) format."
>  (let* ((century (1+ (/ year 100)))
>         (shifted-epact (% (+ 14 (* 11 (% year 19))
>                              (- (/ (* 3 century) 4))
>                              (/ (+ 5 (* 8 century)) 25)
>                              (* 30 century))
>                           30))
>         (adjusted-epact (if (or (= shifted-epact 0)
>                                 (and (= shifted-epact 1)
>                                      (< 10 (% year 19))))
>                             (1+ shifted-epact)
>                           shifted-epact))
>         (paschal-moon (- (calendar-absolute-from-gregorian
>                           (list 4 19 year))
>                          adjusted-epact)))
>    (calendar-dayname-on-or-before 0 (+ paschal-moon 7))))
> 
> 
> (defun da-easter-gregorian (year)
>  (calendar-gregorian-from-absolute (da-easter year)))
> 
> (defun calendar-days-from-easter ()
>  "When used in a diary sexp, this function will calculate how many days
> are between the current date (DATE) and Easter Sunday."
>  (- (calendar-absolute-from-gregorian date)
>     (da-easter (calendar-extract-year date))))
> 
> Now we can schedule the public holidays associated with Easter as 
> recurring events. Good Friday is 2 days before "Easter", Easter Monday is one
> day after.
> 
> 
> *** Good Friday
> <%%(= -2 (calendar-days-from-easter))>
> 
> *** Easter Sunday
> <%%(= 0 (calendar-days-from-easter))>
> 
> *** Easter Monday
> <%%(= 1 (calendar-days-from-easter))>
> 
> 
> Paul
> 
> 
> 
> _______________________________________________
> Emacs-orgmode mailing list
> Please use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode

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

* Re: Some useful timestamp s-expressions
  2010-08-18 22:47 ` Noorul Islam K M
@ 2010-08-18 23:19   ` Daniel Martins
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Martins @ 2010-08-18 23:19 UTC (permalink / raw)
  To: Noorul Islam K M; +Cc: emacs-orgmode@gnu.org, Paul Sexton


[-- Attachment #1.1: Type: text/plain, Size: 5734 bytes --]

Really great Paul.

Did you compared your Spanish classes examples with org-diary-class? Maybe
(I did not tried!) your proposal is an improvement of this function.

Thank you/ Gracias,

Daniel



2010/8/18 Noorul Islam K M <noorul@noorul.com>

> I think it will be great if this goes into worg?
>
> - Noorul
>
> On Aug 19, 2010, at 1:52 AM, Paul Sexton <psexton@xnet.co.nz> wrote:
>
> > In org, timestamps can be in the usual angle-bracket format,
> > eg <2010-08-19 +2w>, or you can use lisp s-expressions. These are in the
> same
> > format as the s-expressions used in the 'diary'/'calendar' emacs
> packages. I
> > only discovered these recently but have been able to use them to schedule
> some
> > complex recurring items. I thought I would share the code here.
> >
> > 1. Recurring items with a limited number of occurrences
> >
> > For example, say you are taking night classes in Spanish. The class is
> every
> > Wednesday evening at 7pm, starting on 18 August, and runs for 8 weeks.
> AFAIK
> > Org's timestamps do not support limited occurrences of recurrent items --
> you
> > have to schedule the item with infinite recurrences, then delete it when
> it
> > finishes.
> >
> > To schedule the Spanish classes, put the following in your .emacs:
> >
> > (defun diary-limited-cyclic (recurrences interval m d y)
> >  "For use in emacs diary. Cyclic item with limited number of recurrences.
> > Occurs every INTERVAL days, starting on YYYY-MM-DD, for a total of
> > RECURRENCES occasions."
> >  (let ((startdate (calendar-absolute-from-gregorian (list m d y)))
> >        (today (calendar-absolute-from-gregorian date)))
> >    (and (not (minusp (- today startdate)))
> >         (zerop (% (- today startdate) interval))
> >         (< (floor (- today startdate) interval) recurrences))))
> >
> > The item in the org file looks like this:
> >
> >
> > ** 19:00-21:00 Spanish lessons
> > <%%(diary-limited-cyclic 8 7 8 18 2010)>
> >
> >
> > 2. Public holiday that is "the nearest Monday to DATE"
> >
> > In New Zealand each regional capital has an "Anniversary Day". The date
> of
> > Auckland's anniversary day is "the nearest Monday to 29 January".
> >
> > Put this in your .emacs:
> >
> > (defun calendar-nearest-to (target-dayname target-day target-month)
> >  "Recurring event that occurs in the nearest TARGET-DAYNAME to
> > the date TARGET-DAY, TARGET-MONTH each year."
> >  (interactive)
> >  (let* ((dayname (calendar-day-of-week date))
> >         (target-date (list target-month target-day (calendar-extract-year
> date)))
> >         (days-diff (abs (- (calendar-day-number date)
> >                            (calendar-day-number target-date)))))
> >    (and (= dayname target-dayname)
> >         (< days-diff 4))))
> >
> > Now we can schedule Auckland Anniversary Day. The first argument, 1,
> means
> > Monday (days of the week are numbered starting with Sunday=0).
> >
> >
> > *** Auckland Anniversary Day
> > <%%(calendar-nearest-to 1 29 1)>
> >
> >
> > 3. Public holiday on "the 4th Monday in October".
> >
> > This does not require any additions to .emacs:
> >
> >
> > *** Labour Day (NZ)
> > <%%(diary-float 10 1 4)>
> >
> >
> > 4. Easter
> >
> > Easter's date moves around from year to year according to a complicated
> set of
> > criteria which I do not claim to understand. However the following code
> will
> > allow you to schedule recurring events relative to Easter sunday.
> >
> > Note: the function da-easter is from:
> > http://github.com/soren/elisp/blob/master/da-kalender.el
> >
> > Put the following in your .emacs:
> >
> > (defun da-easter (year)
> >  "Calculate the date for Easter Sunday in YEAR. Returns the date in the
> > Gregorian calendar, ie (MM DD YY) format."
> >  (let* ((century (1+ (/ year 100)))
> >         (shifted-epact (% (+ 14 (* 11 (% year 19))
> >                              (- (/ (* 3 century) 4))
> >                              (/ (+ 5 (* 8 century)) 25)
> >                              (* 30 century))
> >                           30))
> >         (adjusted-epact (if (or (= shifted-epact 0)
> >                                 (and (= shifted-epact 1)
> >                                      (< 10 (% year 19))))
> >                             (1+ shifted-epact)
> >                           shifted-epact))
> >         (paschal-moon (- (calendar-absolute-from-gregorian
> >                           (list 4 19 year))
> >                          adjusted-epact)))
> >    (calendar-dayname-on-or-before 0 (+ paschal-moon 7))))
> >
> >
> > (defun da-easter-gregorian (year)
> >  (calendar-gregorian-from-absolute (da-easter year)))
> >
> > (defun calendar-days-from-easter ()
> >  "When used in a diary sexp, this function will calculate how many days
> > are between the current date (DATE) and Easter Sunday."
> >  (- (calendar-absolute-from-gregorian date)
> >     (da-easter (calendar-extract-year date))))
> >
> > Now we can schedule the public holidays associated with Easter as
> > recurring events. Good Friday is 2 days before "Easter", Easter Monday is
> one
> > day after.
> >
> >
> > *** Good Friday
> > <%%(= -2 (calendar-days-from-easter))>
> >
> > *** Easter Sunday
> > <%%(= 0 (calendar-days-from-easter))>
> >
> > *** Easter Monday
> > <%%(= 1 (calendar-days-from-easter))>
> >
> >
> > Paul
> >
> >
> >
> > _______________________________________________
> > Emacs-orgmode mailing list
> > Please use `Reply All' to send replies to the list.
> > Emacs-orgmode@gnu.org
> > http://lists.gnu.org/mailman/listinfo/emacs-orgmode
>
> _______________________________________________
> Emacs-orgmode mailing list
> Please use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode
>

[-- Attachment #1.2: Type: text/html, Size: 7454 bytes --]

[-- Attachment #2: Type: text/plain, Size: 201 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Please use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

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

* Re: Some useful timestamp s-expressions
  2010-08-18 20:22 Some useful timestamp s-expressions Paul Sexton
  2010-08-18 22:47 ` Noorul Islam K M
@ 2010-08-21 17:26 ` Manish
  1 sibling, 0 replies; 4+ messages in thread
From: Manish @ 2010-08-21 17:26 UTC (permalink / raw)
  To: Paul Sexton; +Cc: emacs-orgmode

I added these to Worg.

-- Manish


On Thu, Aug 19, 2010 at 1:52 AM, Paul Sexton <psexton@xnet.co.nz> wrote:
> In org, timestamps can be in the usual angle-bracket format,
> eg <2010-08-19 +2w>, or you can use lisp s-expressions. These are in the same
> format as the s-expressions used in the 'diary'/'calendar' emacs packages. I
> only discovered these recently but have been able to use them to schedule some
> complex recurring items. I thought I would share the code here.
>
> 1. Recurring items with a limited number of occurrences
>
> For example, say you are taking night classes in Spanish. The class is every
> Wednesday evening at 7pm, starting on 18 August, and runs for 8 weeks. AFAIK
> Org's timestamps do not support limited occurrences of recurrent items -- you
> have to schedule the item with infinite recurrences, then delete it when it
> finishes.
>
> To schedule the Spanish classes, put the following in your .emacs:
>
> (defun diary-limited-cyclic (recurrences interval m d y)
>  "For use in emacs diary. Cyclic item with limited number of recurrences.
> Occurs every INTERVAL days, starting on YYYY-MM-DD, for a total of
> RECURRENCES occasions."
>  (let ((startdate (calendar-absolute-from-gregorian (list m d y)))
>        (today (calendar-absolute-from-gregorian date)))
>    (and (not (minusp (- today startdate)))
>         (zerop (% (- today startdate) interval))
>         (< (floor (- today startdate) interval) recurrences))))
>
> The item in the org file looks like this:
>
>
> ** 19:00-21:00 Spanish lessons
> <%%(diary-limited-cyclic 8 7 8 18 2010)>
>
>
> 2. Public holiday that is "the nearest Monday to DATE"
>
> In New Zealand each regional capital has an "Anniversary Day". The date of
> Auckland's anniversary day is "the nearest Monday to 29 January".
>
> Put this in your .emacs:
>
> (defun calendar-nearest-to (target-dayname target-day target-month)
>  "Recurring event that occurs in the nearest TARGET-DAYNAME to
> the date TARGET-DAY, TARGET-MONTH each year."
>  (interactive)
>  (let* ((dayname (calendar-day-of-week date))
>         (target-date (list target-month target-day (calendar-extract-year date)))
>         (days-diff (abs (- (calendar-day-number date)
>                            (calendar-day-number target-date)))))
>    (and (= dayname target-dayname)
>         (< days-diff 4))))
>
> Now we can schedule Auckland Anniversary Day. The first argument, 1, means
> Monday (days of the week are numbered starting with Sunday=0).
>
>
> *** Auckland Anniversary Day
> <%%(calendar-nearest-to 1 29 1)>
>
>
> 3. Public holiday on "the 4th Monday in October".
>
> This does not require any additions to .emacs:
>
>
> *** Labour Day (NZ)
> <%%(diary-float 10 1 4)>
>
>
> 4. Easter
>
> Easter's date moves around from year to year according to a complicated set of
> criteria which I do not claim to understand. However the following code will
> allow you to schedule recurring events relative to Easter sunday.
>
> Note: the function da-easter is from:
> http://github.com/soren/elisp/blob/master/da-kalender.el
>
> Put the following in your .emacs:
>
> (defun da-easter (year)
>  "Calculate the date for Easter Sunday in YEAR. Returns the date in the
> Gregorian calendar, ie (MM DD YY) format."
>  (let* ((century (1+ (/ year 100)))
>         (shifted-epact (% (+ 14 (* 11 (% year 19))
>                              (- (/ (* 3 century) 4))
>                              (/ (+ 5 (* 8 century)) 25)
>                              (* 30 century))
>                           30))
>         (adjusted-epact (if (or (= shifted-epact 0)
>                                 (and (= shifted-epact 1)
>                                      (< 10 (% year 19))))
>                             (1+ shifted-epact)
>                           shifted-epact))
>         (paschal-moon (- (calendar-absolute-from-gregorian
>                           (list 4 19 year))
>                          adjusted-epact)))
>    (calendar-dayname-on-or-before 0 (+ paschal-moon 7))))
>
>
> (defun da-easter-gregorian (year)
>  (calendar-gregorian-from-absolute (da-easter year)))
>
> (defun calendar-days-from-easter ()
>  "When used in a diary sexp, this function will calculate how many days
> are between the current date (DATE) and Easter Sunday."
>  (- (calendar-absolute-from-gregorian date)
>     (da-easter (calendar-extract-year date))))
>
> Now we can schedule the public holidays associated with Easter as
> recurring events. Good Friday is 2 days before "Easter", Easter Monday is one
> day after.
>
>
> *** Good Friday
> <%%(= -2 (calendar-days-from-easter))>
>
> *** Easter Sunday
> <%%(= 0 (calendar-days-from-easter))>
>
> *** Easter Monday
> <%%(= 1 (calendar-days-from-easter))>
>
>
> Paul
>
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Please use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode
>

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

end of thread, other threads:[~2010-08-21 17:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-18 20:22 Some useful timestamp s-expressions Paul Sexton
2010-08-18 22:47 ` Noorul Islam K M
2010-08-18 23:19   ` Daniel Martins
2010-08-21 17:26 ` Manish

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).