First copy this code into a new file called GetShamsiDate.js and put that inside your obsidian vault. I recommend in a separate folder called Templates/scripts.
// Simplified Gregorian to Shamsi date converter
function toJalaali(gy, gm, gd) {
var g_days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var j_days_in_month = [31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29];
gy = parseInt(gy) - 1600;
gm = parseInt(gm) - 1;
gd = parseInt(gd) - 1;
var g_day_no = 365 * gy + parseInt((gy + 3) / 4) - parseInt((gy + 99) / 100) + parseInt((gy + 399) / 400);
for (var i = 0; i < gm; ++i)
g_day_no += g_days_in_month[i];
if (gm > 1 && ((gy % 4 == 0 && gy % 100 != 0) || (gy % 400 == 0)))
++g_day_no;
g_day_no += gd;
var j_day_no = g_day_no - 79;
var j_np = parseInt(j_day_no / 12053);
j_day_no %= 12053;
var jy = 979 + 33 * j_np + 4 * parseInt(j_day_no / 1461);
j_day_no %= 1461;
if (j_day_no >= 366) {
jy += parseInt((j_day_no - 1) / 365);
j_day_no = (j_day_no - 1) % 365;
}
var jm, jd;
for (i = 0; i < 11 && j_day_no >= j_days_in_month[i]; ++i) {
j_day_no -= j_days_in_month[i];
}
jm = i + 1;
jd = j_day_no + 1;
return [jy, jm, jd];
}
// Function to pad numbers with leading zeros
function padWithZeros(number, length) {
return String(number).padStart(length, '0');
}
// Main function to get formatted Shamsi date
function getShamsiDate(inputDate) {
let date;
if (inputDate) {
date = new Date(inputDate);
if (isNaN(date.getTime())) {
throw new Error('Invalid date input. Please use a valid date format (e.g., "YYYY-MM-DD" or a valid Date object).');
}
} else {
date = new Date();
}
var [jy, jm, jd] = toJalaali(date.getFullYear(), date.getMonth() + 1, date.getDate());
const dateParts = {
year: jy,
month: padWithZeros(jm, 2),
day: padWithZeros(jd, 2),
hours: padWithZeros(date.getHours(), 2),
minutes: padWithZeros(date.getMinutes(), 2),
seconds: padWithZeros(date.getSeconds(), 2)
};
// Check if input contains time components
const hasTime = inputDate && typeof inputDate === 'string' &&
(inputDate.includes(':') || inputDate.includes('T'));
// Return date-only or date-time format based on input
return hasTime
? `${dateParts.year}-${dateParts.month}-${dateParts.day} ${dateParts.hours}:${dateParts.minutes}:${dateParts.seconds}`
: `${dateParts.year}-${dateParts.month}-${dateParts.day}`;
}
module.exports = getShamsiDate;Then in Templater, you should set the script template folder and hit reload button. It should now say: Detected 1 user script.
GitHub - SilentVoid13/Templater: A template plugin for obsidian
You can now use the function wherever you want.
I use it like this:
date: <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD") %>
day: <% tp.date.now("dddd", 0, tp.file.title, "YYYY-MM-DD") %>
shamsi: <% tp.user.getShamsiDate(tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD")) %>obsidian
Obsidian Plugins