Calculating days between $StartDate and $EndDate

I added the following attributes:

$StartDate
$EndDate
$Duration (As Number)

I then added the following action code in Rule:

$StartDate |= date("now");
$Duration=days($Startdate-$EndDate);

The $StartDate is 12 Apr 2025 at 10:54:12
The $EndDate is 14 Apr 2025 at 11:05:11

I then entered an EndDate on the note (i.e. 14/04/2025)

So,

The $Startdate is 12 Apr 2025 at 10:54:12
The $Enddate is 14 Apr 2025 at 11:05:11

However, the Duration is returning 0 (i.e. zero)

Is the addition of time to the date cause the problem?

Thank you!

You have two syntax errors in your rule.

  • $Startdate should be $StartDate`. Note that attribute names are case-sensitive.

Fixing those errors I get a $Duration of 2.

@mwra Thank you! It now works! (I had got the spelling of $StartDate correct in the actual code, but it was ‘-’ instead of the ‘,’ was the problem)

the $StartDate was 12/04/2025, 11:25
the $EndDate was 14 Apr 2025 at 11:05:11

The duration is returned as 1. This is technically correct as the time of the $EndDate is earlier than the $StartDate. However I would prefer the answer to be 2 :just subtracting the start date (without the time) from the end date (without the time).

To try to achieve this I created two additional attributes:
$SDate, $EDate

Then wrote the following action code in the Rule pane:

$SDate=$StartDate.date();

$EDate=$EndDate.date();

$Duration=days($SDate,$EDate);

However, the $Duration returned as 0.

How can I do the calculation on the date parts of the start and end dates?

Thank you!

OK, days() does work as documented, but that isn’t what you want. A common user assumption is that date data 'just know’s these differences but date calculations are actually very complex because of all the edge cases even if we don’t encounter them—but might. Under the hood all dates are a number: the number of milliseconds after (or before) a known reference date. So the data has no notion of a date until turned back into a string representation that a human understands.

If you want the count of calendar days between data A and date B, you’d do better to set the h:m:s of their time to be the same. See:

The time-reset days() test, as reported in $Text above shows ‘2’ which is what I think you want.

Note that I set the dates’ time element to 00:00:01 rather than 00:00:00 in case that triggered some ‘which day is this?’ ambiguity. In fact the key point is that the times are

Lest you wonder, there isn’t a single command to reset/ignore the time element of Date data. Indeed the ‘Date’ type is actually a shorthand term for what might more accurately be termed the ‘Date/Time’ type.

See more: Date-Type Attributes.

Here’s that edict code, in case it helps:

var:date vStart;
var:date vEnd;
vStart=date($StartDate.year,$StartDate.month,$StartDate.day,0,0,1);
vEnd=date($EndDate.year,$EndDate.month,$EndDate.day,0,0,1);
$Duration=days($StartDate,$EndDate);
$MyInterval = interval($StartDate,$EndDate);
$Text = days(vStart,vEnd);

By why an edict? Rules run all the time but if—as we all do—make silly mistakes, we’re now hammering bad code constantly into the app. Edicts update when they change and if using the Inspector there is always the option to hit the ‘Update now’ button.

Friends suggest friends use edicts rather than rules for testing code. :slight_smile:

1 Like

@mwra Thank you for the elegant solution for which I now appreciate a complex problem! Fabulous!

1 Like

@mwra, I like your answer; however, if $Duration is an interval, would this not be more straightforward?

$Duration=interval($StartDate,$EndDate). This is what we were doing with @lfriedla last week, no?

I think not. Look at the screen grab in my previous post. An interval (interval()) was giving 1 day when the OP wanted 2.

1 Like

The code works nicely! Thank you!

I slightly modified the code; I replaced $Text with $Subtitle. So there is no $Text in my code. However, when the code runs a ‘0’ (zero) appears on the text pane (i.e. $Text=0). Why might this zero appear in the text pane, although there is no reference to $Text in the code? Thank you!

function fElapsed()

{

var:date vStart;

var:date vEnd;

vStart=date($StartDate.year,$StartDate.month,$StartDate.day,0,0,1);

vEnd=date($EndDate.year,$EndDate.month,$EndDate.day,0,0,1);

$Duration=days($StartDate,$EndDate);

$MyInterval = interval($StartDate,$EndDate);



if ($EndDate="never" | $EndDate="")

{

$Subtitle="";

$ElapsedDays="";

}

else {

$ElapsedDays= days(vStart,vEnd);

$Subtitle="Elasped " + $ElapsedDays + " days";

}

}

$Text, which is set to show days(vStart,vEnd);, shows 2 for me (using the original date info (up thead). If it is 0, then check your start & end dates.

If I use your code, in the test TBX below, note ‘text’ (which uses the edict above) has a $Text of 2. Note ‘text #2’ uses the function you wrote and correctly shows the subtitle.

Date-test.tbx (165.4 KB)

You’ll note I’ve tidied up the layout of the function. I’m not sure exactly what white space is allowid in if(), function, etc. This is the bracket layout I’d suggest to avoid off edge case issues:

if(condition){

}else{

}

@mwra Thank you for the helpful guidance!
I tried the edit you kindly included in the attached file. I still got zero on the $Text. There might be some hidden code in my file. I will check.

Thank you!

1 Like

@mwra As the function runs, a zero appears in the text pane (as I mentioned earlier). However, this Zero does not occur when I have a text on the Text pane. As such, it works well enough for me. Next weekend, I will try to go through again line-by-line and see whether I can catch where the zero is coming from using your code and mine. Thank you!

OK, I duplicate both test notes:

  • #text #2 → test #3, where there is no text Calling your function generates no $Text.
  • test → test 1, where $EndDate is set to same day as $StartDate. $Text now shows 0.

Test file:
Date-test1.tbx (171.3 KB)

Can you upload the actual file producing the 0 in $Text (i.e. not a reconstruction)? Without seeing your exact actual code/content, I can’t tell from whence the error stems.

If the actual source file is something you can’t share publicly, I’m happy for you to sent me a forum DM with the file.

@mwra Thank you! I have sent the file by DM.

We found the gremlin. It turns out the mystery text was an easily-made mistake—user error but not obvious until you know the cause! :slight_smile: . The note in question, since made into a prototype, had acquired some $Text, i.e. “0”, during some earlier code testing. Overlooked was the fact that any note using a prototype also gets the prototype’s test. Not realising this, the $Text in a new note using this prototype was assumed to be getting the ‘0’ value from code, rather than from the prototype.

Tip, for if you get an issue like this with ‘mystery’ $Text.
If testing with a rule or edict, you can delete the unexpected $Text and if it doesn’t come back then likely it’s not being autogenerated. If using a stamp, clear $Text and re-ruse the stamp. Again if no text appears then the original source wasn’t (this) cod—but likely is left over from a previous test.

More on Tinderbox and inheritance of attributes, including via prototypes: Inheritance of attribute values

1 Like

Thank you for generously looking through the file @mwra!. Sorry that it was an elementary mistake on my part.

1 Like

No apologies needed, that’s why the community is here to help. :slight_smile:

1 Like

@mwra Thank you! :slight_smile: