Tinderbox Forum

Calculating dates of beginning and end to the week

I’m trying to create a “dynamic” event that always represents “this week”. It should have a $StartDate of last Sunday, and an $EndDate of this Saturday. For example, today is 2020-12-09, so the $StartDate should be 2020-12-06 and the $EndDate should be 2020-12-12.

I can get last Sundays’ date with: $StartDate=date(today-today.weekday); but I’m stumped with getting Saturday’s date.

I thought $EndDate=date(today-today.weekday+"7 days") would work and give “Dec 12, 2020”, but it gives me “Nov 2, 2020”. I think it might be a bug. Here’s (almost) everything I tried.

Broken

The following all give “Dec 6, 2020” (last Sunday), as if the interval was ignored

  • $EndDate=date(today-today.weekday+interval("7 days"));
  • $EndDate=date(today-today.weekday) +interval("7 days");
  • $EndDate=today-today.weekday+interval("7 days");

These also don’t work right:

  • $EndDate=date(today+interval("7 days")); is Dec 9 instead of 16.
  • $EndDate=today+interval("7 days"); is Dec 9 instead of 16.
  • $EndDate=today-today.weekday+"1 week"; give May 6, 2020
  • $EndDate=(today-today.weekday)+"1 week"; also gives May 6 (thankfully! :slight_smile:)
  • $EndDate=today-today.weekday+"1 day"; gives Nov 8, 2020

Works

But these work fine:

  • $EndDate=date(today+"7 days"); works fine and gives Dec 16, 2020
  • $EndDate=today+"7 days"; works fine and gives Dec 16, 2020

This is using version 8.8.0 (b479) on macOS 10.15.7.

I’ve read the following articles to lead me to something that mostly worked, but they still didn’t provide an answer:

Hi, and welcome to the forum, and thanks for taking the trouble to describe what has hasn’t worked. For me, both your start and End date methods fail, But, I have a solution:

$StartDate=date("today -"+today.weekday+" days");
$EndDate = $StartDate + "6 days";

I should explain the logic for the change. The .weekday value of date("today") is 3`, as I write this. So in literal values the $StartDate is:

$StartDate=date("today - 3 days");

Note how the expression is a string. But, we want the ‘3’ to be a variable, so we break the string inside date() into two parts and concatenate (i.e. join together) into the middle today.weekday so it is evaluated. In truth I didn’t think this was possible, I assume that because the today part is already inside a day() operator so is evaluated into date-type data and the weekday is then returned into the statement to return the needed ‘3’ back into the overall string.

The enddate is easier, the end of the week is the sixth day after the start date. If the latter is correct then the latter will be, even across a month boundary.

Do ask if that doesn’t make sense!

Perhaps, I need to add to this article to include examples that use attribute values as in the post you cited, or inline use of an operation within date() as above. I’m also tempted to move the description of date calculations out of that article and into a new article in the section on Actions, Rules & Action code. Would that have been more helpful when you were looking for guidance on this??

Great explanation…I think it would be useful for this example to be in the data operators’ explanation, and since dates are such a useful tool it would also be good in the overview of the action.

What, in the article for date(). If it goes too many places, experience shows (some) instances get overlooked and not updated. With 2k notes it’s hard to keep track of things. I thought one good larger set of examples as a note in the Actions and Rules section could then replace (and be linked from) current info in the Date Data Type note (actually an agent) and linked to from such action operators as pertinent. This better conforms to the hypertextual model of a single canonical reference and relevant linkage.

In truth, I also need to check with Mark B about evaluated expressions inside date(). What I posted works, but I’m not 100% sure I’ve used what amounts to best practice.

1 Like

The argument to date() is a string that represents a date. If the argument is not a string — for example, if it’s a date — it’s coerced to a date.

Sorry, in my original replay to you I forgot to say that intervals are not the tool to use here (which is why I didn’t), but it would have been more helpful if I’d stated that at the time. So, sorry if that omission caused you any confusion.

Thanks Marks! Problem solved thanks to mwra’s (much simpler) expression of adding an offset to the start date.

Discussion on the behavior of date()

The argument to date() is a string that represents a date.

This is the piece of knowledge I was missing. But based on some testing, it looks like date() accepts only one offset, right? I mean that date(a + b + c) doesn’t work, but date(date(a + b) + c) does.

It looks like $StartDate=date("today + 1 day + 2 days"); only does a “+1 day” offset, but $StartDate=date(date("today + 1 day") + " 2 days"); effectively does a “+3 days” offset.

It’s a little surprising to me, but I assume it makes the parser much simpler.

On documentation

I can’t remember if I had read the Date Data Type aTbRef article, but if had, I would have seen part of the “answer” in the sentence:

Constructions like "yesterday + 1 week" , "tomorrow + 1 year" or "tomorrow - 2 hours" are also possible;

When looking for this sort of issue in other programming languages, I usually search for “date calculations”, or “date arithmetics”. Maybe updating the article with those terms, maybe in section header would have brought me to the right place.

Reading the Date Designators articles would also have provided some of the answer. For example, I could just do $EndDate=Saturday;. That’s short and sweet!

Not really. date() accepts 2 types of input:

In the string form you want a single string such as "yesterday - 2 weeks". Tinderbox takes this single string and parses out the parts: the date designator ‘yesterday’ / subtraction / number 2/ the date designator ‘week[s]’.

That same result could be from several strings joined together, for sake of example "yesterday - 2"+" weeks". So, now we know that although date(“string”) takes a single string but it can be composed of several ±joined (i.e. ‘concatenated’) strings to form the formal string. But however composed that string is not evaluated for contained action operators. We know this doesn’t work:

"today - today.weekday  days"
So what is it that allows us to insert 'today.weekend' into the date() string?

First we need to look at .weekday . We know ‘.weekday’ needs a date object, and we see that if chained to a string will evaluate it as if it were enclosed in date(). Thus

June.weekdaydate("june").weekday0 i.e. error as valid returns are 1–7

today.weekdaydate("today").weekday → 4 (Thursday, which is correct at time of writing this)

yesterday.weekdaydate("yesterday").weekday → 3 (Wednesday, which is correct at time of writing this)

However, I would argue this short form is not totally safe for if I use 22.weekday → 1. ! is a valid (Monday) figure but wrong, as we don’t know what ‘22’ means but if it were the day of the current month (December) the correct day of the week for 22 Dec 2020 is 2. Also, date("22").weekday gives a different answer of 3 (also wrong if assuming 22 Dec).

But, I’d accept my last tests are rather pushing the bounds of sense. Yet, if a user gets carried away and makes a mis-presumption using `.weekday’ on a bare date designator is not totally safe, yet should work in most circumstances. We can write

$MyString  = "today - " + today.weekday + " days"

and get “today - 3 days”. We have also seen we can use the same right side expression in date(). However, now I’ve unpeeled the years of the onion, I think I have a clearer method if inserting the variable day number:

var dateStr("today - "+today.weekday+" days");
$StartDate = date(dateStr);

The first line places the input string for date() into an action variable (see var) which I’ve called datStr. In the second line we use it as the single string for setting a date for $StartDate. If you are still getting lost, a more explicit form of the the above is

var dateStr;
dateStr = "today - "+date("today").weekday+" days";
$StartDate = date(dateStr);

As the variable is destroyed after the code runs, there is no trash to clear up.

Separately, thanks re the documentation, I’ll think on that while I figure a shorter way of describing the above.