Dataviewjs: How to work with datetimes? Best practice: moment.js vs. luxon?

Hi, I was working on a dataviewjs table that shows me all websites (notes containing a special link) and the last time I checked them. As there is (at least to my knowledge) no feature to update a last-checked-date on clicking a url-link, I created a custom button to update a date (in my case a note property called modified)[Would probably make more sense to name it last-checked].

Each note containing a website looks e.g. like this:

# Note 1
---
url: https://help.obsidian.md/Home
created: 2024-07-17 12:38
modified: 2024-07-18 12:38
tag-links:
  - "[[specialwebsite]]"
---

And my dataviewjs table looks like this:

// https://stackoverflow.com/questions/10830357/javascript-toisostring-ignores-timezone-offset
// offset in milliseconds
var tzoffset = (new Date()).getTimezoneOffset() * 60000;
var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, -5).replace("T", " ");

const now = moment()

dv.table(["Company", "Last Checked", "Update"], dv.pages('"MyFolder"')
	.where(p => dv.func.contains(p["tag-links"], dv.func.link("specialwebsite")))
	.map(p => [
		p.file.link,
		moment(p.file.mtime.toISO()).from(now),
        // Next line doesn't work (probably because they're Strings?)
        // localISOTime - p.file.mtime.toISO().slice(0, -10).replace("T", " "),
		dv.el("span", "Update", {
		    cls: "edit-button",
		    onclick: async () => {
				const file = await app.vault.getAbstractFileByPath(p.file.path); 
				if (file) {
					const content = await app.vault.read(file);
					const updatedContent = content.replace(/modified: .*/, `modified: ${localISOTime}`);
					await app.vault.modify(file, updatedContent);
				}
			}
		})
	])
);

I’ve read that moment.js is kind of deprecated (Moment.js | Docs) and luxon should be preferred. However, I couldn’t get luxon running and really liked the function from() using moment.js as it beautifully prints the time difference.

As I also like to stay “minimal” I tried to find a way without using moment.js and luxon. Except for calculating and printing the time difference as elegant as with from() from moment.js it works fine (see comments).

Do you have any solutions or suggestions in general? What is the way to go?

I’ve briefly touched in on this in Moment.js date issue for specific formats (/w dashes) - #6 by holroy , but I’ve found that we kind of have to live with both variants depending on the task at hand.

One suggestion I would give though is to use a proper ISO data recognised by Dataview directly in your properties. This would both allow for Obsidian utilities to change the date through the editor, and somewhat easier handling from within your Dataview scripts since it’s then automatically a date. This would also allow for using some of the date functions available through Dataview’s API.

In short the change you’d need to do is to add the T between the date and time part of your properties, so that it matches a proper ISO8601 format like described here.

(I’ve been contemplating on providing a PR for Dataview to allow for the date not having the T in there, but I’ve not gotten around to it, and I’m not sure how feasible it is.)

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.