Caveat: Using moment() in day-only calculations → Wrong results!

A moment() always includes the time, so it’s more like a now() than like a today()!

Partial “moments” (like those gotten from, say moment("2021-05-23")) always get their time set to 00:00:00 local time.

Thus, when calculating “days to some date” you will get wrong results, especially when “now” is late in the day!

This is a trap I also often fell into.

The easy cure—if doing something with whole days, i.e. when not needing the time—is to always use moment().startOf('day') in these cases. This will also set the time part to 00:00:00 local time, and thus make things calculate correctly again!

Great to see this thread getting momentum—keep ’em coming!

4 Likes

A bit late but yes, you’re absolutely right here concerning the use of Moment() :blush:, I should have been more precise in my explanations :innocent: !

Thank you for clearing this out :blush: !

1 Like

I’m building a template for monthly notes (which will be created from the Periodic Notes plugin. I would like the template to include a link to the next month and the previous month, and I’d like the template to already calculate the next month based off of the month of the template instance.

For example, if I use the template to create a note for [[2021-08]], then I want there to be a note for [[2021-07]] (last month) and a note for [[2021-09]] (next month).

I don’t want it to be calculated based off of the date for today tp.date.now(). I want it to be based off of whatever the month for that monthly note is.

Does anyone know how I would build something like this?

I just started to use Templater and I am really liking it. Apparently all my old built in template dates fell apart since an update.

I have watching YouTube Tutorials on how to use Templater from the likes of Bryan Jenks and Productivity Guru.

I am wishing for a daysInYear() for moment. I really would like to set up a thing that outputs:

  • Day 68 out of 365, or a shorthand 68/365
  • In a leap year:
  • Day 68 out of 366 or 68/365

It has been about 14 years since I have done any java programming, so please excuse my bad attempt of showing code.

I am guessing one could use an if then else statement to do this instead of my complicated thinking, with a variable for year, and then a variable for the return value if the statement comes back true then the moment format would have the constant of 366, else it prints out the moment format with constant of 365.

So something like:
varA = YYYY
If moment(“varA”,”YYYY”).isLeapYear() is true
Then moment().format(“[Day] DDDD [of 366]”)
Else
moment().format(“[Day] DDDD [of 365]”)

Some of these coding examples are excellent, and I will be snagging some to use for days until vacation, etc.

Oh and a lot of Danes use a local format for date as: of dd/mm - YYYY

For the number of days in the current year (for example), you can use:

<%+ moment("12-31", "MM-DD").dayOfYear() %>

This will return the day number of December 31st in the current year, which is the last day in a year, and thus the same as the number of days in the year. :wink:

What is the + after the <%t+ moment code you wrote? I didn’t see your reply before I edited my post.

The + after <% tells Templater it’s a Dynamic Command, i.e., freshly evaluated everytime.

So your new example above could be written either as

<% moment().format("[Day] DDDD of " + moment("12-31", "MM-DD").dayOfYear()) %>

(static), or

<%+ moment().format("[Day] DDDD of " + moment("12-31", "MM-DD").dayOfYear()) %>

(dynamic, for automatic updating).

2 Likes

You answered my question before I could formulate it and type it out. I was going to ask about nesting functions such as moment.

Thank you!

Glad if it helped you! :slight_smile:

Productivity Guru is a great resource on YouTube with his video on Templater and Date formats. I have been playing with Date formats since I watched his video earlier today

For your christmas example I get PTO.159S

Try the one further down below.

Or, the better one:

<%+* let edate = moment("12-24", "MM-DD"); let from = moment().startOf('day'); edate.diff(from, "days") >= 0 ? tR += edate.diff(from, "days") : tR += edate.add(1, "year").diff(from, "days") %>

which takes into consideration that Christmas this year might already have passed.

Or even:

<!-- Days until any "MM-DD" date this year/next year with "TODAY" -->
<%+* let edate = moment("12-24", "MM-DD"); let from = moment().startOf('day'); edate.diff(from, "days") >= 0 ? edate.diff(from, "days") == 0 ? tR += "It’s today!" : tR += edate.diff(from, "days") : tR += edate.add(1, "year").diff(from, "days") %>

Will do once I get my windows sync with iCloud working again. Actually I believe now it is totally corrupted and I can only use my iPad or phone to work with Obsidian. Then all the templates do not work because of it being the private beta version.

1 Like

It’s been super helpful to incorporate these into my regular reviews & my workflow. Any idea how I could list the weekly notes in each month’s note?
I know how to list the daily notes for that month, and the monthly notes for that year, but not the weeks. I’m doing weekly notes in the format GGGG-[W]WW, yielding e.g. 2021-W38

In case anyone else needs to do this, @shabegom suggested this answer which works great:

const currentMonthDates = new Array(moment(tp.file.title,'YYYY-MM').endOf('month').week() - moment(tp.file.title, 'YYYY-MM').startOf('month').week() + 1).fill(null).map((x, i) => moment(tp.file.title,'YYYY-MM').startOf('month').add(i, 'weeks').format("- ![[gggg-[W]ww[]]]")).join('\r\n') %>
<%* tR +=  currentMonthDates %>

Hi all,

Is it possible to create a time-blocking list of 15 minute increments, something like;

e.g. if the current time is 08:51, I might want to start my time blocking at 09:00

- <% tp.date.now("HH:mm", +x min) %>
- <% tp.date.now("HH:mm", +15 min) %>
- <% tp.date.now("HH:mm", +30 min) %>
- <% tp.date.now("HH:mm", +45 min) %>
- <% tp.date.now("HH:mm", +60 min) %>

one would just need to insert the adjustment time x, and it would be a nice little focus prompt alongside a pomodoro timer.

thanks!

Hey @dryice! I’ve actually once written two complete moment.js addons for rounding date/time and generating date/time intervals. These are a little more complicated and not so easy to add to Obsidian, so here are two simpler solutions, maybe one of these fits your bill:

Very simple (and ugly) solution without Javascript:

- <% moment().add(15-(moment().minute()%15),'minutes').startOf('minute').format('HH:mm') %>
- <% moment().add(15-(moment().minute()%15),'minutes').startOf('minute').add(15, 'minutes').format('HH:mm') %>
- <% moment().add(15-(moment().minute()%15),'minutes').startOf('minute').add(30, 'minutes').format('HH:mm') %>

Simple solution using Javascript:

<%*
let start = moment().add(15-(moment().minute()%15),'minutes').startOf('minute');
tR += "- " + start.format('HH:mm') + "  \n";
// moment.js dates are mutable, so always only add 15 mins!
tR += "- " + start.add(15, 'minutes').format('HH:mm') + "  \n";
tR += "- " + start.add(15, 'minutes').format('HH:mm') + "  \n";
%>

It is assumed that both of these are saved as a Templater template in the template folder, and inserted upon request (Alt+E).

Result (for both) should be (at 19:58:17):

  • 20:00
  • 20:15
  • 20:30
1 Like

Many thanks, both solutions work perfectly, and yes, the second is nice and tidy! :ok_hand:
Have a lovely weekend!

1 Like

Hello @Moonbase59 – I’m reading through this read and this is a wealth of knowledge. You’re a true tinkerer. I’m running into trouble and wanted to see if you saw something I was doing simply wrong or if you knew of a smart way to achieve this.

I’m looking to dynamically link all the months in a quarter, depending on the quarter. As such, I was planning on writing something like:

 <%* if (tp.date.quarter() == "1") { %>
- 2021-1
- 2021-2
- etc
<%* } %>

However, I’m getting Templater Error: Template parsing error, aborting. tp.date.quarter is not a function.

I’ve also tried to use tp.date.now().quarter(), but get a similar error.

Am I doing something wrong? I thought that Templater exposed the entire Moment object and methods?

Thanks in advance for your help!

@ScottKillen has a terrific “if-else if” example using the Templater plugin that may be able to help you. use-the-templater-plugin-to-create-repeating-tasks-on-future-or-past-daily-notes

1 Like