Bug | tp.date.now() will incorrectly parse the last week of the year and first week of the next year
LeCheenaX opened this issue · 2 comments
Plugin information (please complete the following information):
- OS: Windows 10
- Templater version: 2.4.1
Describe the bug
When I use templater to generate weekly report, every report seems fine except the report of 2024 Week 53 or 2025 Week 1, the number of week is depended on your locale.
Scripts I use:
<%*
const referdate = "2024-12-30"; //This should be the beginning of 2025 Week 1 in my locale.
%>
Reference date: <% referdate %>
Week Number: <% tp.date.now("YYYY-w",0,"referdate","YYYY-MM-DD") %> //This will convert the reference date to week format.
Factually, the number of week is correct. when you execute the scripts above it will output week 1.
However, the full output is:
Reference date: 2024-12-30
Week Number: 2024-1
I managed to skip this trap in another way, where I could have the correct filename "2025-1". Now all I need to do is to duplicate the filename to my content by tp.file.title
However, this still failed.
You can duplicate the issue with the following brief case:
<% tp.date.now("YYYY-w",0,"2025-1","YYYY-w") %>
And the Output will be:
2024-1
Expected behavior
The correct Output of
<% tp.date.now("YYYY-w",0,"2025-1","YYYY-w") %>
should be:
2025-1
Dangerous edge case with moment.js formatting, but not a templater bug! Your reference date is still within 2024! Just imagine the opposite case:
<% tp.date.now("YYYY-MM-DD",0,"2025-1","YYYY-w") %> - The first week of the new year actually starts... in 2024!
In theory, it should be possible to play with offsets based on day-of-the-week (making sure you always reference the last day of the week, avoiding the edge cases where the first half is still within the previous year).
Edit:
Maybe like this?
<%*
const date = moment("2024-12-30", "YYYY-MM-DD")
const last_week_day = date.add(6 - date.day(), "days")
tR += last_week_day.format("YYYY-w") -%> - The first week of the new year actually starts... in 2024!
Dangerous edge case with moment.js formatting, but not a templater bug! Your reference date is still within 2024! Just imagine the opposite case:
<% tp.date.now("YYYY-MM-DD",0,"2025-1","YYYY-w") %> - The first week of the new year actually starts... in 2024!
In theory, it should be possible to play with offsets based on day-of-the-week (making sure you always reference the last day of the week, avoiding the edge cases where the first half is still within the previous year).
Edit: Maybe like this?
<%* const date = moment("2024-12-30", "YYYY-MM-DD") const last_week_day = date.add(6 - date.day(), "days") tR += last_week_day.format("YYYY-w") -%> - The first week of the new year actually starts... in 2024!
Thank you for the reminding. This is actually a bug from Moment.js, where I mistakenly blame it on templater.
Btw, another similar Moment.js bug is found, when you want to parse the first day of 2024 week 1 (Set Monday as the first day of week. )
<%*
moment().locale('zh-cn').weekday(0)
let referdate = moment("2024 - Week 1", "YYYY [- Week] w"); // first week of 2024
tR += moment(referdate, "YYYY [- Week] w").locale('zh-cn').weekday(0).format("YYYY-MM-DD"); //Get the date of Monday in first week, 2024.
%>
This functions in 2 steps I believe:
- Calculate the first day of 2024 week 1;
- Convert the calculated result to zh-cn locale;
Only the step2 will be parsed with locale 'zh-cn'.
In step1, the the week 1 of 2024 will start from 2023-12-31, because it is not correctly parsed by locale setting. (It follows default locale 'en'. )
For anyone with the similar issue, you can try the global locale setting of Moment.js.
Workaround
<%*
//initialization
moment.locale('zh-cn');
let title;
let referdate;
//Parsing file name or reference date
if (tp.file.title.startsWith("Untitled")||tp.file.title.startsWith("未命名")) {
referdate = moment(tp.file.creation_date("YYYY-MM-DD"), "YYYY-MM-DD").format("YYYY-MM-DD");
title = tp.date.now("YYYY [- Week] w",0,referdate,"YYYY-MM-DD");
await tp.file.rename(title);
}
else {
title = tp.file.title;
referdate = moment(title, "YYYY [- Week] w").weekday(0).format("YYYY-MM-DD"); //Use Monday as a reference date
}
%>
First day of week:
<% moment(referdate, "YYYY-MM-DD").weekday(0).format("YYYY-MM-DD") %> // Get Monday, this fixes the locale mixture:
First day of 2024 week1 = 2023-12-31 (Sunday)
Last day of week:
<% moment(referdate, "YYYY-MM-DD").weekday(6).format("YYYY-ww") %> //Get Sunday, then convert to week of year. This fixes the edging case:
First week of 2025 = 2024 week1 (because the reference date is 2024-12-30)