How do I find all notes with a start date in the previous month?

I have looked all over aTbref, through the forum, and the program’s Help and I still haven’t the faintest idea of how to achieve this.

Just to be clear about what I mean by “the previous month”, I mean that when I’m in March I want to look at what I did in February, in April I want what I did in March, and so forth.

Any ideas would be welcome.

Suppose that we have an agent named Last Month.. Its $StartDate is the start of last month, and its $EndDate is the end of last month. For now, we’ll just suppose those are set by magic — or that you type them yourself.

Now, what is the agent’s query? I think it would be:

$Created>$StartDate(agent) & $Created<$EndDate(agent)

I haven’t tested this, but really it’s restating your problem. OK so far?


Now, how would we set the start date? I’m going to use a Rule on the agent. That’s overkill — an edict would be fine — but it’s simpler to test.

First, a slightly easier problem. How would we find all the notes in the last 30 days?

$StartDate=date("today-30 days");
$EndDate=date("today");

Now, that’s not what you asked, but it’s just a little easier. OK so far?


Now, how would we construct “the first day of last month”? Let’s start by figuring out what this month is:

$MyDate=date("today");
$MyNumber=$MyDate.month();

So, last month is one less. Of course, there’s the problem of January!

var:number year=$MyDate.year();
var:number month=$MyDate.month()-1;
if (month<=0) {
     month=12; 
     year = year-1;
     }
$StartDate=date(year,month,1);
$EndDate=date($MyDate.year(),$MyDate.month(),1);

Again, untested, but you should get the idea.

Or if we just want dates in the previous calendar month, i.e. not one-month’s worth of days ago or the days in the previous month within that 30-day rolling window, then you could try this (also not tested, caught this as I close up here):

$Created.month==(date("today").month-1) & $Created.year==date("today").year

The test is asking, does an item have a $Created date value whose month is last month and year this year (based on today’s date? Thus, in February 2024, it would match all notes created in January 2024. You actually have the same year end problem as above so if the current month is January, you’d need to decrement the year tested. A bit more work to add to the above. So, in fact you’d best figure out the number for the month and year in the agent and then read those values into the query using the agent designator. Whinch when done might look like:

$Created.month==$MyMonth(agent) & $Created.year==$MyYear(agent)

which for Feb 2004 would be, if using literal values, like the query:

$Created.month==1 & $Created.year==2004

whereas in Jan 2004 is would equate to testing literal values:

$Created.month==12 & $Created.year==2003

For checking the year issue the logic in code @eastgate gave above can be used for decrementing last month from 0 to 12 and using year-1 not year.

Relevant docs: see Date.month, Date.year , and date()

@eastgate @mwra Thank you to both. I’ll play around and see how I get on (though maybe not today, as I will be busy). Dealing with dates always seems to be complicated, no doubt because they are “human-based” rather than “mathematically-based”. The French Republic tried to institute something more rational, but it didn’t catch on, of course.

You have much more faith in my abilities than I have. I’ve been seeing “For-Each” and “While” loops for decades, and I still have no understanding of them. The light just refuses to go on … Coding and scripting of most sorts remains stubbornly inaccessible to me. Human languages I can pick up more easily.

Thank you again.

1 Like

10 Ventôse CCXXXII, @MartinBoycott-Brown a écrit,

There are some possible conversion methods at French Republican Calendar Tools - Lagomorph.

Meanwhile…

OK, here’s a quick demo. As $Created is a read-only attribute, my demo uses $StartDate, but got your purposes just replace $StartDate in the query with $Created and all should work. The agent query is:

$StartDate.month==$MyMonth(agent) & $StartDate.year==$MyYear(agent)

This uses 2 user Number-type attributes $MyMonth and $MyYear. There are set via the agent’s rule:

$MyDate = date("today");
var:list vList = fLastMonth($MyDate);
$MyMonth = vList[0];
$MyYear = vList[1];

To aid reuse, the month/year calculations are put in a user function:

function fLastMonth(iDate:date){
   var:number vMonth = (iDate.month)-1;
   var:number vYear = iDate.year;
   //check for rollback to last year
   if(vMonth == 0){
       vMonth = 12;
      vYear = vYear-1;
   };
// pass vars back as a list
return list(vMonth,vYear);
}; //END

If you want to experiment with the year-end issue, comment out (//) the first line of the agent’s rule and manually set the agent’s $MyDate to a date in January 2024. In fact, I’ve added a second agent in the demo that does this.

Notes: do read the README and I did note that at times I needed to update agents (File menu or ⌘⌃=) to ensure the date calculations percolated through correctly. I accord with @eastgate 's suggestion that in actual use an edict would be a better production choice rather than a rule for the agent but YMMV.

Here’s the demo file: LastMonth1.tbx (213.5 KB)

2 Likes

@eastgate and @mwra, brilliant as usual :clap::clap:

1 Like

I used to have an app on my phone to convert Republican dates. I wish such a thing had existed in the 1990s when I was writing about Napoleon. Thanks for the link, it will be useful.

Many thanks for all the work, and apologies for taking a while to respond – it’s been a busy few days.

I will take a closer look at everything over the next few days and see if I can understand how it all works. I sometimes think I became a psychotherapist because I don’t have too much trouble understanding irrationality. Logic of the kind used in coding seems to be more difficult for me. :wink:

At the simplest I can state it, the solution is:

give me every note whose [date attribute of interest] date value has a month numbered one less than the current month and is in the current year.

So, in March 2024 (month #3) that means note with a target date value of February (month #2) in 2024. This is what the Date.month and Date.year codes are doing - extracting the month number of the date’s moth segment and getting the date’s year segment.

The fly in the ointment of this January (month #1), a 1- 1 is zero and there is no month numbered zero, only months 1 through 12. But we know only January gives this anomalous we also know that the answer is to provide month #12 (December) from the previous year (i.e. Date.year - 1).

So whilst the code seen ‘raw’ might look abstract, the logic isn’t very complex.

HTH

That is the kind of thinking that would never occur to me, so your explanation helps a lot. Sadly, I fear it will not help me much for the future because my mind doesn’t seem to be capable of working that way. No doubt it is partly because of lack of training, but this has got me wondering if there is something special about the styles of thinking needed to be good at coding. I’ve just wandered off to have a look at what the internet says about this, but I guess I’ll have to take a closer look at scholarly literature to find anything useful.

Thanks again. I don’t know how you manage to do any work while also providing all this support on the forum!

1 Like

I suspect your supposing there is a ‘get me last month’ operator or the like. There isn’t a built-in one, but it’s not too hard to do and even if unable to write it yourself, the examples up-thread can be used as copy and keep examples. Just copy the code into your own TBXs. Unless the current Western calendar changes, you won’t need to re-work the code.

In truth is were there a built-in function for this, it would still be doing essentially the same task as the code I’ve showed (find the previous month except for month one, …etc.). OK, here we get to see behind the curtain. But we don’t have to look/understand, we can just use the code. :slight_smile:

Aware that my last demo ducked the ‘last month’ as ‘last 30 days’ option, here is an update to the previous demo file. The ‘Previous 30 days’ agent uses this query:

$StartDate<date("today") & $StartDate>=date("today-30 days")

The agent’s $Text is set via edict, just for testing:

$Text = "30 days ago is: "+ date("today - 30 days").format("L");

Viewed today, 3 March 2024, you will notice how agents ‘Previous 30 days’ and ‘Last month’s notes’ have differing content.

This reminds us of the unstated (and thus often untested) assumptions in our general descriptions of intent. Software can’t (yet!) read our implicit intent—though current AI boosters may claim otherwise.

Here’s the modified demo TBX: LastMonth2.tbx (283.6 KB)