* Diary sexp and comparing dates, agenda
@ 2024-01-12 5:58 David Rogers
2024-01-12 17:01 ` Tory S. Anderson
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: David Rogers @ 2024-01-12 5:58 UTC (permalink / raw)
To: Org-mode list
Hello all
I'm using the Org agenda to show when certain church occasions
will happen. Mostly I've got them working correctly, after
"stealing" the method used in holidays.el for finding the date of
Easter, along with someone else's function that then uses that to
find the difference between Easter and today. (I'm pretty sure
that whole idea was on emacswiki, and I think Paul Sexton put it
together.)
So now I have a much smaller problem to solve, but I don't
understand how to get it to work; I suspect it has to do with how
dates get formatted within different functions. Using what I
already have, I can do this:
* Example 1
<%%(= 245 (mf-days-from-easter))>
because "mf-days-from-easter" is defined in my init file, along
with the definition of Easter itself. This does what it looks like
it should do; this year, Example 1 is shown on December 1.
And I can do
* Example 2
<%%(and (diary-float 1 0 5 7) (<= (mf-days-from-easter) -56))>
to say "five Sundays after January 6th, but only if Easter is
still 8 weeks away or more".
But Example 1 isn't quite finished, because that date is too close
to Christmas. I can easily show a diary sexp defining when "too
close to Christmas" is:
<%%(diary-float 12 0 -4 24)>
So I want to combine these ideas, to say "Show Example 1 in the
agenda 245 days after Easter each year, but only if it's earlier
than the fourth Sunday before Christmas".
I could do a long string of (and (not this day, not this day, etc
etc [insert long list of days] . . . , but that seems like a last
resort.
Everything in this question fits into "the current year according
to the agenda view" - there's no need to consider dates that cross
a year boundary.
So: Is there a fairly simple way to define a (mf-days-from-advent)
that will do a similar job to what (mf-days-from-easter) is
already doing (i.e. it works when used in a diary sexp)?
Here are the relevant definitions I've been using:
(defun mf-easter (displayed-year)
(let* ((century (1+ (/ displayed-year 100)))
(shifted-epact ; age of moon for
April 5...
(% (+ 14 (* 11 (% displayed-year 19)) ; ...by
Nicaean rule
(- ; ...corrected for the Gregorian
century rule
(/ (* 3 century) 4))
(/ ; ...corrected for Metonic cycle
inaccuracy
(+ 5 (* 8 century)) 25)
(* 30 century)) ; keeps value positive
30))
(adjusted-epact ; adjust for 29.5 day
month
(if (or (zerop shifted-epact)
(and (= shifted-epact 1) (< 10 (%
displayed-year 19))))
(1+ shifted-epact)
shifted-epact))
(paschal-moon ; day after the full moon on or after
March 21
(- (calendar-absolute-from-gregorian (list 4 19
displayed-year))
adjusted-epact)))
(calendar-dayname-on-or-before 0 (+ paschal-moon
7))))
(defun mf-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)
(mf-easter (calendar-extract-year date))))
--
David
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Diary sexp and comparing dates, agenda
2024-01-12 5:58 Diary sexp and comparing dates, agenda David Rogers
@ 2024-01-12 17:01 ` Tory S. Anderson
2024-01-12 18:11 ` Ken Mankoff
2024-01-12 23:00 ` Ihor Radchenko
2 siblings, 0 replies; 7+ messages in thread
From: Tory S. Anderson @ 2024-01-12 17:01 UTC (permalink / raw)
To: Org-mode list
I don't have an answer -- my own use of diary-sexp is nothing more than standard holiday inclusion -- but I'm interested and watching for answers on the list. I personally didn't know that you could do such calculations the way you are, such as "too close to DATE", so I'm impressed!
- Tory
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Diary sexp and comparing dates, agenda
2024-01-12 5:58 Diary sexp and comparing dates, agenda David Rogers
2024-01-12 17:01 ` Tory S. Anderson
@ 2024-01-12 18:11 ` Ken Mankoff
2024-01-12 23:00 ` Ihor Radchenko
2 siblings, 0 replies; 7+ messages in thread
From: Ken Mankoff @ 2024-01-12 18:11 UTC (permalink / raw)
To: David Rogers; +Cc: emacs-orgmode
Hi David,
I'm not sure if this will help, but I have to file time sheets on the last weekday less than or equal to the 15th and last-day-of-month.
I wrote two diary functions to achieve this (I don't handle holiday edge cases). I use these functions with:
** INFO [#A] Time Sheet
<%%(kdm/diary-last-weekday-of-month date)>
<%%(kdm/diary-last-weekday-15th date)>
Functions are:
(defun kdm/diary-last-weekday-15th (date)
(let* (
(dow (calendar-day-of-week date))
(dom (calendar-extract-day date))
(weekday (and (>= dow 1) (<= dow 5))))
(or
(and weekday (= dom 15))
(and (= dow 5) (= dom 14))
(and (= dow 5) (= dom 13)))))
(defun kdm/diary-last-weekday-of-month (date)
(let* (
(dow (calendar-day-of-week date))
(dom (calendar-extract-day date))
(month (calendar-extract-month date))
(year (calendar-extract-year date))
(ldom-num (calendar-last-day-of-month month year))
(weekday (and (>= dow 1) (<= dow 5))))
(or
(and weekday (= dom ldom-num))
(and (= dow 5) (= (+ 1 dom) ldom-num))
(and (= dow 5) (= (+ 2 dom) ldom-num)))))
-k.
On 2024-01-11 at 21:58 -08, David Rogers <davidandrewrogers@gmail.com>
wrote...
> Hello all
>
> I'm using the Org agenda to show when certain church occasions will
> happen. Mostly I've got them working correctly, after "stealing" the
> method used in holidays.el for finding the date of Easter, along with
> someone else's function that then uses that to find the difference
> between Easter and today. (I'm pretty sure that whole idea was on
> emacswiki, and I think Paul Sexton put it together.)
>
> So now I have a much smaller problem to solve, but I don't understand
> how to get it to work; I suspect it has to do with how dates get
> formatted within different functions. Using what I already have, I can
> do this:
>
> * Example 1 <%%(= 245 (mf-days-from-easter))>
>
> because "mf-days-from-easter" is defined in my init file, along with
> the definition of Easter itself. This does what it looks like it
> should do; this year, Example 1 is shown on December 1.
>
> And I can do
>
> * Example 2 <%%(and (diary-float 1 0 5 7) (<= (mf-days-from-easter)
> -56))>
>
> to say "five Sundays after January 6th, but only if Easter is still 8
> weeks away or more".
>
> But Example 1 isn't quite finished, because that date is too close to
> Christmas. I can easily show a diary sexp defining when "too close to
> Christmas" is:
>
> <%%(diary-float 12 0 -4 24)>
>
> So I want to combine these ideas, to say "Show Example 1 in the agenda
> 245 days after Easter each year, but only if it's earlier than the
> fourth Sunday before Christmas".
>
> I could do a long string of (and (not this day, not this day, etc etc
> [insert long list of days] . . . , but that seems like a last resort.
>
> Everything in this question fits into "the current year according to
> the agenda view" - there's no need to consider dates that cross a year
> boundary.
>
> So: Is there a fairly simple way to define a (mf-days-from-advent)
> that will do a similar job to what (mf-days-from-easter) is already
> doing (i.e. it works when used in a diary sexp)?
>
>
> Here are the relevant definitions I've been using:
>
>
> (defun mf-easter (displayed-year)
> (let* ((century (1+ (/ displayed-year 100)))
> (shifted-epact ; age of moon for April 5...
> (% (+ 14 (* 11 (% displayed-year 19)) ; ...by Nicaean
> rule
> (- ; ...corrected for the Gregorian century rule
> (/ (* 3 century) 4)) (/ ; ...corrected for
> Metonic cycle inaccuracy
> (+ 5 (* 8 century)) 25) (* 30 century)) ; keeps
> value positive
> 30)) (adjusted-epact ; adjust for 29.5 day month
> (if (or (zerop shifted-epact)
> (and (= shifted-epact 1) (< 10 (%
> displayed-year 19))))
> (1+ shifted-epact) shifted-epact))
> (paschal-moon ; day after the full moon on or after
> March 21
> (- (calendar-absolute-from-gregorian (list 4 19
> displayed-year))
> adjusted-epact))) (calendar-dayname-on-or-before 0
> (+ paschal-moon 7))))
>
>
>
> (defun mf-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)
> (mf-easter (calendar-extract-year date))))
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Diary sexp and comparing dates, agenda
2024-01-12 5:58 Diary sexp and comparing dates, agenda David Rogers
2024-01-12 17:01 ` Tory S. Anderson
2024-01-12 18:11 ` Ken Mankoff
@ 2024-01-12 23:00 ` Ihor Radchenko
2024-01-13 5:41 ` David Rogers
2 siblings, 1 reply; 7+ messages in thread
From: Ihor Radchenko @ 2024-01-12 23:00 UTC (permalink / raw)
To: David Rogers; +Cc: Org-mode list
David Rogers <davidandrewrogers@gmail.com> writes:
> * Example 1
> <%%(= 245 (mf-days-from-easter))>
>
> because "mf-days-from-easter" is defined in my init file, along
> with the definition of Easter itself. This does what it looks like
> it should do; this year, Example 1 is shown on December 1.
>
> And I can do
>
> * Example 2
> <%%(and (diary-float 1 0 5 7) (<= (mf-days-from-easter) -56))>
>
> to say "five Sundays after January 6th, but only if Easter is
> still 8 weeks away or more".
>
> But Example 1 isn't quite finished, because that date is too close
> to Christmas. I can easily show a diary sexp defining when "too
> close to Christmas" is:
>
> <%%(diary-float 12 0 -4 24)>
>
> So I want to combine these ideas, to say "Show Example 1 in the
> agenda 245 days after Easter each year, but only if it's earlier
> than the fourth Sunday before Christmas".
You don't need diary-float - it returns true/false whether current DATE
fits the arguments.
Instead, you can make use of `calendar-nth-named-absday'.
For example,
<%%(and (= 245 (mf-days-from-easter))
(< (calendar-absolute-from-gregorian date)
(calendar-nth-named-absday -4 0 12 24)))>
Diary sexps are nothing but ordinary Elisp, with an extra twist that
during evaluation `date' variable is bound to current calendar date.
When they return nil, DATE does not match.
--
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Diary sexp and comparing dates, agenda
2024-01-12 23:00 ` Ihor Radchenko
@ 2024-01-13 5:41 ` David Rogers
2024-01-13 20:05 ` Ihor Radchenko
0 siblings, 1 reply; 7+ messages in thread
From: David Rogers @ 2024-01-13 5:41 UTC (permalink / raw)
To: Ihor Radchenko; +Cc: Org-mode list
Ihor Radchenko <yantar92@posteo.net> writes:
> You don't need diary-float - it returns true/false whether
> current DATE
> fits the arguments.
>
> Instead, you can make use of `calendar-nth-named-absday'.
> For example,
>
> <%%(and (= 245 (mf-days-from-easter))
> (< (calendar-absolute-from-gregorian date)
> (calendar-nth-named-absday -4 0 12 24)))>
>
> Diary sexps are nothing but ordinary Elisp, with an extra twist
> that
> during evaluation `date' variable is bound to current calendar
> date.
> When they return nil, DATE does not match.
Thank you!
It seems that `calendar-nth-named-absday' wants the year after the
month, and then an (optional) day of the month to count from.
Since I hoped to keep re-using this material every year without
re-entering the calculations, I've tried the following:
In my init file, I've added these two short definitions:
(defun mf-beginning-of-advent (displayed-year)
(calendar-nth-named-absday -4 0 12 displayed-year 24))
(defun mf-days-from-advent ()
(- (calendar-absolute-from-gregorian date)
(mf-beginning-of-advent (calendar-extract-year date))))
And my Org file has this:
* Example 1
<%%(and (= 245 (mf-days-from-easter)) (<= (mf-days-from-advent)
-1))>
This setup seems to work so far. Does it look reasonable to you?
--
David
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Diary sexp and comparing dates, agenda
2024-01-13 5:41 ` David Rogers
@ 2024-01-13 20:05 ` Ihor Radchenko
2024-01-13 23:44 ` David Rogers
0 siblings, 1 reply; 7+ messages in thread
From: Ihor Radchenko @ 2024-01-13 20:05 UTC (permalink / raw)
To: David Rogers; +Cc: Org-mode list
David Rogers <davidandrewrogers@gmail.com> writes:
> This setup seems to work so far. Does it look reasonable to you?
Yes, but I may not be a reliable judge. I do not have a lot of practical
experience with diary sexps other than when people report Org mode bugs :)
--
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Diary sexp and comparing dates, agenda
2024-01-13 20:05 ` Ihor Radchenko
@ 2024-01-13 23:44 ` David Rogers
0 siblings, 0 replies; 7+ messages in thread
From: David Rogers @ 2024-01-13 23:44 UTC (permalink / raw)
To: Ihor Radchenko; +Cc: Org-mode list
Ihor Radchenko <yantar92@posteo.net> writes:
> David Rogers <davidandrewrogers@gmail.com> writes:
>
>> This setup seems to work so far. Does it look reasonable to
>> you?
>
> Yes, but I may not be a reliable judge. I do not have a lot of
> practical
> experience with diary sexps other than when people report Org
> mode bugs :)
Since it looks not-stupid to you, and it gives the right answer,
and if there WAS a mistake the risk of injuring anyone is . . .
rather low :) , I'm declaring it good enough.
--
Thanks again
David
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2024-01-13 23:45 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-12 5:58 Diary sexp and comparing dates, agenda David Rogers
2024-01-12 17:01 ` Tory S. Anderson
2024-01-12 18:11 ` Ken Mankoff
2024-01-12 23:00 ` Ihor Radchenko
2024-01-13 5:41 ` David Rogers
2024-01-13 20:05 ` Ihor Radchenko
2024-01-13 23:44 ` David Rogers
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).