Hey guys,
I’m using obsidian for work and tracking the time for different tasks with the super simple time tracker plugin.
In order to not get distracted after a month I’m getting a report each month and I just wanted to showcase the dataviewjs query I got while using LLM:
// get the time tracker plugin api instance
let api = dv.app.plugins.plugins["simple-time-tracker"].api;
let dailyDurations = {};
let startDate = moment("01.10.2024", "DD.MM.YYYY"); // Startdatum
let endDate = moment("31.10.2024", "DD.MM.YYYY"); // Enddatum
let totalDuration = 0;
for (let page of dv.pages()) {
// Überprüfe, ob der Dateiname ein Datum enthält (z.B. 01.10.24)
let dateStr = page.file.name.split(".")[0] + "." + page.file.name.split(".")[1];
let fileDate = moment(dateStr, "DD.MM.YY"); // Datei-Datum als Moment-Objekt
// Prüfe, ob das Datum im gewünschten Zeitraum liegt
if (fileDate.isBetween(startDate, endDate, null, '[]')) {
// load trackers in the file with the given path
let trackers = await api.loadAllTrackers(page.file.path);
for (let { section, tracker } of trackers) {
// Überprüfe, ob die tracker.entries-Eigenschaft definiert ist
if (tracker.entries) {
// Summiere die Dauer der Tracker für jeden Tag
let day = dateStr;
let duration = api.getTotalDuration(tracker.entries);
if (dailyDurations[day]) {
dailyDurations[day] += duration;
} else {
dailyDurations[day] = duration;
}
totalDuration += duration;
}
}
}
}
// Sortiere die Tage nach dem Titel der Notiz
let sortedDays = Object.keys(dailyDurations).sort((a, b) => moment(a, "DD.MM.YY").diff(moment(b, "DD.MM.YY")));
// Erstelle die Markdown-Tabelle
let output = "| Datum | Dauer |\n";
output += "| --- | --- |\n"; // Tabellenkopf
for (let day of sortedDays) {
output += `| ${day} | ${api.formatDuration(dailyDurations[day])} |\n`;
}
output += `| **Gesamt** | **${api.formatDuration(totalDuration)}** |\n`;
dv.el("div", output);
In the end it looks like this:
It’s still expandable but I like the simplicity and yet the versatility in it.
Have a great day
2 Likes
Since this might be of interest for somebody: I extended my query and the table with the summary of the overtime each day with a regular working time of 7 hours.
The whole thing looks like this in the end:
I included a line break between each week for the sake of better readability.
// get the time tracker plugin api instance
let api = dv.app.plugins.plugins["simple-time-tracker"].api;
let dailyDurations = {};
let startDate = moment("01.09.2024", "DD.MM.YYYY"); // Startdatum
let endDate = moment("30.09.2024", "DD.MM.YYYY"); // Enddatum
let totalDuration = 0;
let totalOvertime = moment.duration(0);
for (let page of dv.pages()) {
// Überprüfe, ob der Dateiname ein Datum enthält (z.B. 01.10.24)
let dateStr = page.file.name.split(".")[0] + "." + page.file.name.split(".")[1];
let fileDate = moment(dateStr, "DD.MM.YY"); // Datei-Datum als Moment-Objekt
// Prüfe, ob das Datum im gewünschten Zeitraum liegt
if (fileDate.isBetween(startDate, endDate, null, '[]')) {
// load trackers in the file with the given path
let trackers = await api.loadAllTrackers(page.file.path);
for (let { section, tracker } of trackers) {
// Überprüfe, ob die tracker.entries-Eigenschaft definiert ist
if (tracker.entries) {
// Summiere die Dauer der Tracker für jeden Tag
let day = dateStr;
let duration = api.getTotalDuration(tracker.entries);
if (dailyDurations[day]) {
dailyDurations[day] += duration;
} else {
dailyDurations[day] = duration;
}
totalDuration += duration;
}
}
}
}
// Berechne die Überstunden für jeden Tag
let normalWorkHours = moment.duration(7, 'hours');
for (let day in dailyDurations) {
let fileDate = moment(day, "DD.MM.YY");
if (fileDate.day() !== 0 && fileDate.day() !== 6) { // 0 = Sonntag, 6 = Samstag
let overtime = moment.duration(dailyDurations[day]) - normalWorkHours;
dailyDurations[day] = {
duration: dailyDurations[day],
overtime: overtime
};
totalOvertime.add(overtime);
} else {
dailyDurations[day] = {
duration: dailyDurations[day],
overtime: moment.duration(0)
};
}
}
// Sortiere die Tage nach dem Titel der Notiz
let sortedDays = Object.keys(dailyDurations).sort((a, b) => moment(a, "DD.MM.YY").diff(moment(b, "DD.MM.YY")));
// Erstelle die Markdown-Tabelle
let output = "| Wochentag | Datum | Dauer | Überstunden |\n";
output += "| --- | --- | --- | --- |\n"; // Tabellenkopf
let lastWeek = null;
for (let day of sortedDays) {
// Erstelle einen Link im Format [[DD.MM.YY]] für das Datum
let dayFormatted = moment(day, "DD.MM.YY").format("DD.MM.YY");
let dayLink = `[[${dayFormatted}]]`;
let dayOfWeek = moment(day, "DD.MM.YY").format("dddd");
let overtime = dailyDurations[day].overtime;
let hours = Math.floor(overtime / 3600000);
let minutes = Math.floor((overtime % 3600000) / 60000);
let overtimeStr = `${hours}:${minutes.toString().padStart(2, '0')}`;
if (overtime < 0) {
overtimeStr = `- ${overtimeStr}`;
}
// Überprüfe, ob eine neue Woche beginnt
let currentWeek = moment(day, "DD.MM.YY").week();
if (lastWeek !== null && currentWeek !== lastWeek) {
output += "| --- | --- | --- | --- |\n";
}
lastWeek = currentWeek;
output += `| ${dayOfWeek} | ${dayLink} | ${api.formatDuration(dailyDurations[day].duration)} | ${overtimeStr} |\n`;
}
output += `| **--** | **--** | **${api.formatDuration(totalDuration)}** | **${api.formatDuration(totalOvertime)}** |\n`;
dv.el("div", output);
Maybe somebody has an idea for improvement but right now I am pretty happy and it is working fine with a template using templater