Is there a way to express yesterday or tomorrow with the now-macro?

Hello I need a way to generate a date in the format YYYY0MM0DD to compare it to other dates in a list.
It would be nice to have an aditional parameter in the macro like <<now “YYYY0MM0DD” “+1d, +2d”>> to express that I want tomorrow and the day after tomorrow.

@TW_Tones already suggested that the days-operator could be usefull, but I could not figure a way to do this either.

I figured out how to use the days filter to show tiddlers with a field “due” that is tomorrow or the day after. I tried to exclude days before today, but I couldn’t get it to work.

<$list filter="[days:due[1]days:due[2]]" />

I documented this once in Google groups, but there were still gaps.

  • I will try and present something tomorrow

The days operator is a range specifier from N days past or forward, then a second range can define a precise set between them.

  • The days operator only works on dates in tiddlers fields not dates that done exist in date fields for example if there was nothing yesterday it returns nothing.
1 Like

In my case I do not have a field to use the days macro and the format is not compatible…
The dates to compare are indexes in a dictionary Tiddler with the format YYYY0MM0DD.

Here’s how to calculate tomorrow and yesterday date, hope it helps :

Date : <$edit-text type="number" field="day" default=<<now DD>>/>/<$edit-text type="number" field="month" default=<<now MM>>/>/<$edit-text type="number" field="year" default=<<now YYYY>>/>


<$let
year={{{ [{!!year}]:map[<currentTiddler>is[blank]then<now YYYY>else<currentTiddler>] }}}
month={{{ [{!!month}]:map[<currentTiddler>is[blank]then<now MM>else<currentTiddler>] }}}
day={{{ [{!!day}]:map[<currentTiddler>is[blank]then<now DD>else<currentTiddler>] }}}
is_leap={{{ 
[<year>]
:filter[remainder[100]match[0]]
:map[<currentTiddler>remainder[400]match[0]then[1]else[0]]
~[<year>remainder[4]match[0]then[1]]
~[[0]]
}}}

days_month_list="=31 =[[28]add<is_leap>] =31 =30 =31 =30 =31 =31 =30 =31 =30 =31"

total_days_of_current_month={{{ [subfilter<days_month_list>nth<month>] }}}

tomorrow_day={{{ 
[<total_days_of_current_month>add[1]]
:map[<day>add[1]remainder<currentTiddler>]
:map[<currentTiddler>match[0]then[1]else<currentTiddler>]
}}}

tomorrow_month={{{ 
[<tomorrow_day>compare:number:gt<day>then[0]else[1]add<month>]
:map[<currentTiddler>compare:number:gt[12]then[1]else<currentTiddler>] 
}}}

tomorrow_year={{{ 
[<tomorrow_month>compare:number:gteq<month>then[0]else[1]add<year>] 
}}}

yesterday_month={{{ 
[<day>!match[1]then[0]else[-1]add<month>] 
:map[<currentTiddler>match[0]then[12]else<currentTiddler>]
}}}

yesterday_day={{{ 
[subfilter<days_month_list>nth<yesterday_month>]:filter[<yesterday_month>!match<month>]~[<day>add[-1]] 
}}}
yesterday_year={{{  
[<yesterday_month>compare:number:gt<month>then[-1]else[0]add<year>]
}}}

>

* Yesterday = <<yesterday_day>>/<<yesterday_month>>/<<yesterday_year>>
* Today = <<day>>/<<month>>/<<year>>
* Tomorrow = <<tomorrow_day>>/<<tomorrow_month>>/<<tomorrow_year>>

</$let>

Demo : How to get tomorrow and yesterday date in the Gregorian calendar

EDIT: updated with the method for finding yesterday date
EDIT2: Seems like there is an error in my formula, I’m fixing it
EDIT3: fixed !

3 Likes

Wow, I did not see this problem is so complex.
I bundled it up to a [DistantDayMacro.json|attachment] which should work for other days in the same month (?).
But I am not sure so nobody should use it to steer a nuclear power plant.

Warning! :ghost:
Well, it worked for yesterday but looking at it more closely, it will only work by accident.
But How do you do this correctly

\define distantDay(dist:"1")
<$let
year=<<now YYYY>> 
is_leap={{{ 
[<year>]
:filter[remainder[100]match[0]]
:map[<currentTiddler>remainder[400]match[0]then[1]else[0]]
~[<year>remainder[4]match[0]then[1]]
~[[0]]
}}}
days_month_list="=31 =[[28]add<is_leap>] =31 =30 =31 =30 =31 =31 =30 =31 =30 =31"
total_days_of_current_month={{{ [subfilter<days_month_list>nth<now MM>] }}}

distant_day={{{ 
[<total_days_of_current_month>add[1]]
:map[<now DD>add[-1]remainder<currentTiddler>]
:map[match[0]then[1]else<currentTiddler>]
}}}

distant_month={{{ 
[<distant_day>compare:number:lt<now DD>then[0]else[1]add<now MM>remainder[12]] 
:map[match[0]then[1]else<currentTiddler>]
}}}

distant_year={{{ 
[<distant_month>compare:number:lte<now MM>then[0]else[1]add<now YYYY>]
}}}
 >

Distant = <<distant_year>><<distant_month>><<distant_day>>

</$let>
\end
<<distantDay "-1">>

.

@JanJo FIY there was an error in my post, I updated it with the correct formulas (you can test it on the demo link).

The update is great, in fact I needed yesterday…and the day before yesterday

I think it should be possible to loop this, give me a few minutes

1 Like

And one more issue: I need YYYY0MM0DD :wink:

Mh it’s harder than I thought, I’ll notify you when/if I manage to find a way to do that

1 Like

Here :

Date : 

<$edit-text type="number" field="year" default=<<now YYYY>>/>
<$edit-text type="number" field="month" default=<<now MM>>/>
<$edit-text type="number" field="day" default=<<now DD>>/>

<$let
year={{{ [{!!year}]:map[<currentTiddler>is[blank]then<now YYYY>else<currentTiddler>] }}}
month={{{ [{!!month}]:map[<currentTiddler>is[blank]then<now MM>else<currentTiddler>] }}}
day={{{ [{!!day}]:map[<currentTiddler>is[blank]then<now DD>else<currentTiddler>] }}}
is_leap={{{ 
[<year>]
:filter[remainder[100]match[0]]
:map[<currentTiddler>remainder[400]match[0]then[1]else[0]]
~[<year>remainder[4]match[0]then[1]]
~[[0]]
}}}

days_month_list="=31 =[[28]add<is_leap>] =31 =30 =31 =30 =31 =31 =30 =31 =30 =31"

total_days_of_current_month={{{ [subfilter<days_month_list>nth<month>] }}}

tomorrow_day={{{ 
[<total_days_of_current_month>add[1]]
:map[<day>add[1]remainder<currentTiddler>]
:map[<currentTiddler>match[0]then[1]else<currentTiddler>]
}}}

tomorrow_month={{{ 
[<tomorrow_day>compare:number:gt<day>then[0]else[1]add<month>]
:map[<currentTiddler>compare:number:gt[12]then[1]else<currentTiddler>] 
}}}

tomorrow_year={{{ 
[<tomorrow_month>compare:number:gteq<month>then[0]else[1]add<year>] 
}}}

yesterday_month={{{ 
[<day>!match[1]then[0]else[-1]add<month>] 
:map[<currentTiddler>match[0]then[12]else<currentTiddler>]
}}}

yesterday_day={{{ 
[subfilter<days_month_list>nth<yesterday_month>]:filter[<yesterday_month>!match<month>]~[<day>add[-1]] 
}}}
yesterday_year={{{  
[<yesterday_month>compare:number:gt<month>then[-1]else[0]add<year>]
}}}

before_yesterday_month={{{[<yesterday_day>!match[1]then[0]else[-1]add<yesterday_month>]:map[<currentTiddler>match[0]then[12]else<currentTiddler>]
}}}
before_yesterday_day={{{ 
[subfilter<days_month_list>nth<before_yesterday_month>]:filter[<before_yesterday_month>!match<yesterday_month>]~[<yesterday_day>add[-1]] 
}}}
before_yesterday_year={{{  
[<before_yesterday_month>compare:number:gt<yesterday_month>then[-1]else[0]add<yesterday_year>]
}}}

after_tomorrow_day={{{ 
[<total_days_of_current_month>add[1]]
:map[<tomorrow_day>add[1]remainder<currentTiddler>]
:map[<currentTiddler>match[0]then[1]else<currentTiddler>]
}}}

after_tomorrow_month={{{ 
[<after_tomorrow_day>compare:number:gt<tomorrow_day>then[0]else[1]add<tomorrow_month>]
:map[<currentTiddler>compare:number:gt[12]then[1]else<currentTiddler>] 
}}}


after_tomorrow_year={{{ 
[<after_tomorrow_month>compare:number:gteq<tomorrow_month>then[0]else[1]add<tomorrow_year>] 
}}}

>

* Before yesterday = {{{ =[<before_yesterday_year>] =[<before_yesterday_month>pad[2]] =[<before_yesterday_day>pad[2]] +[join[]] }}}
* Yesterday = {{{ =[<yesterday_year>] =[<yesterday_month>pad[2]] =[<yesterday_day>pad[2]] +[join[]] }}}
* Today = {{{ =[<year>] =[<month>pad[2]] =[<day>pad[2]] +[join[]] }}}
* Tomorrow = {{{ =[<tomorrow_year>] =[<tomorrow_month>pad[2]] =[<tomorrow_day>pad[2]] +[join[]] }}}
* After tomorrow = {{{ =[<after_tomorrow_year>] =[<after_tomorrow_month>pad[2]] =[<after_tomorrow_day>pad[2]] +[join[]] }}}

</$let>

I tried to use a loop but there was too many recursion … I’m sure there is a better way to do this tough, a javascript macro is probably a better idea

https://demos.tiddlyhost.com/#Date%20%2B-2

1 Like

As you have seen with @telumire’s solution, adding/subtracting days from a formatted date (e.g., “YYYY0MM0DD”) is not trivial, because of “overflow” handling needed to account for month and year numbers, which includes handling different number of days per month and leap years.

Fortunately, there is another method that avoids this complexity by allowing you to do “direct” math with dates.

To do this, you will need: https://tiddlytools.com/timer.html#TiddlyTools%2FTime%2FParseDate which adds a parsedate[...] filter operator that can convert formatted dates to/from “unix time” numeric values that express datetime values as signed integers representing the number of milliseconds since the beginning of the “unix epoch” (midnight on January 1st, 1970)

After importing the above tiddler you will need to save-and-reload for the filter operator to be available. Then, you can write something like this:

<$let today=<<now "YYYY0MM0DD">> format="[UTC]YYYY0MM0DD"
     oneday={{{ [[24]multiply[60]multiply[60]multiply[1000]] }}}
  yesterday={{{ [<today>parsedate[unixtime]subtract<oneday>parsedate:unixtime<format>] }}}
   tomorrow={{{ [<today>parsedate[unixtime]add<oneday>parsedate:unixtime<format>] }}}>
...
</$let>

Notes:

  • today is the current date
  • format is the desired output date format. Note the use of [UTC] to bypass making adjustments for local timezone offsets.
  • oneday is the total number of milliseconds in one day (24 hours X 60 mins/hr X 60 secs/min X 1000 msec/sec)
  • yesterday and tomorrow first use parsedate[unixtime] to convert the formatted input date to a “unixtime” numeric value, then subtract or add the number of milliseconds in one day, and then convert the result back to a formatted date by using parsedate:unixtime<format>.

enjoy,
-e

5 Likes

Thanks @EricShulman and @telumire for the intensive tinkering.
This really was quite a nut to crack.
I marked Eric’s a the solution because it is more versatile because of the format-opion and the possibility to enter arbitrary date-ranges.