How to Calculate Duration between Dates in Dataview

I am building a family tree in Obsidian and would like to show the age of every family member with dataview. However, I found no solution to calculate dates.


Name: Peter Doe
Born: 1854-7-24
Died: 1942-3-13
Age:


TABLE
Born, Died, Age
FROM #person
SORT Name DESC

Any suggestion on how to show the age dynamically?

1 Like

Does the sample file attached work as you want?

Angel

philippalexanders2.md.zip (734 Bytes)

You will probably need dataviewjs for this, instead of dataview. It requires using Javascript a bit, however.

Reference docs are here:

https://blacksmithgu.github.io/obsidian-dataview/api/intro/

The actual date math is possible via dataviewjs’s use of Luxon.DateTime, e.g.,

You’ll end up doing something like:

age = luxon.DateTime.fromISO(person.died).diff(luxon.DateTime.fromISO(person.born))

No idea how close that is, though—just a quick guess.

1 Like

Angel’s answer will work using just dataview, if you don’t want to go down the Javascript path.

One thing to note however, if the person does not have a recorded date of death, then that person will not be listed in the table. Not knowing how all the files are set up, this might not be a problem. If there are people who are still living, you could calculate the age with something similar to the following in your dataview query:

choice(!Death, date(today), Death) - Birth as Age

This says if there is no value for Death replace it with the current date.

Screenshot of original post, and the updated view taking living persons into account:

8 Likes

Code is poetry. And you are a bard.

Beautiful work. Thanks for sharing.

Angel

1 Like

Hello, @dugdun

Dumb question, but…where / how are you recording the YAML for Bob Jones? In the same note? If yes, how do you separate John’s data from Bob’s?

Thanks

Angel

In the sample attached, if I delete Jack or Jill from the YAML, the table will fill with the data of whoever remains.

But why can’t I get both Jack and Jill?

Angel

test.md.zip (359 Bytes)

You can’t repeat the same field key in yaml.
You can’t create “groups” in yaml (neither in inline fields).

In inline fields you can do this:

Name:: Jack

blabla...

Name:: Jill

but the result is an array similar to this in yaml:

Name:
  - Jack
  - Jill

Each field is an array (multiple values) without direct relation with values in other fields.

Name:
  - Jack
  - Jill
Born:
  - 1854-07-24
  - 1955-07-27

No direct relation with Jack and 1854-07-24 (only the first in the list).

At @anon12638239 there are separate pages for each person. As mnvwvnm states, if you have the same key multiple times in a single document then you will turn the values into an array and you would have to deal with this those in a different way. I don’t know if dataview would let you properly flatten multiple arrays properly, although it might be easily done with dataviewjs. In that case you would need to make sure the data is correctly entered so perons 1’s name/dates all aligned.

Since the OP is building a family tree I would assume that each person had their own page that would contain interesting facts about the person’s life.

1 Like

Many thanks, @mnvwvnm and @dugdun.

I had assumed I could keep multiple people’s data in one set of YAML (similar to the employee records in this link) and then draw out the data using Dataview. My bad.

Separate files it is.

Appreciate the advice and explanations.

Angel

1 Like

Hello.

I am working on a version of this for my own needs.

I would like ‘Time’ to be in days only, rather than years, months, weeks, and days.

Is that possible?

```dataview
TABLE WITHOUT ID
file.link AS What,

choice(!DatesEnd, date(today), DatesEnd) - DatesStart as Time

FROM #obsidian

WHERE DatesID

SORT DatesStart ASC
```

Any ideas greatly appreciated.

Sample file attached.

Thanks

Angel

samplefile2.zip (542 Bytes)

Try this:
(choice(!DatesEnd, date(today), DatesEnd) - DatesStart).days as Time

2 Likes

That’s so brilliant. Why could I not get that myself?!?!

Can I add the word ‘days’ to that? And can I get a thousands separator? So something like: 1,321 days

Thanks for the speed, help, patience, and kindness.

Angel

You were kind enough to help with a javascript date format.

If I use both DV and JS to calculate the number of days between two dates, they give different amounts (see the sample file attached). I know there is an issue with how dates are calculated in DV, but I thought that would be when calculating years / months / weeks / days. Assumed that a count of just days would be the same, but it seems not.

Ah, well, still close-ish.

Angel

sampleDVandJS.zip (470 Bytes)

Well, JS isn’t my ground… :slight_smile:
About DQL queries, it seems that the date calculations aren’t very rigorous (because it fails in the number of days per month).
If you want to add the word “days” you can write (choice(!DatesEnd, date(today), DatesEnd) - DatesStart).days + " days" AS Time.
About how to format the output in similar way as toLocaleString() I really don’t know how to do it. There’s no similar function as format() in sql.

1 Like

Thanks, @mnvwvnm, yet again for the help.

At the moment, I will stick with your brilliant JS solution at it produces a completely accurate calculation.

The DV query is out by a varying number of days in every test I have done, so keeping the JS solution at least means I have reliable data.

I was looking to switch as DV renders in live preview, but JS only works in reading mode.

I am trying to adjust to the new editor, knowing the old one will be deprecated in time. Thing I miss most is being able to see whitespace / invisibles. The old CSS and plugin solutions don’t work at the moment, and I have had no success when trying to create suitable CSS snippets for CM6.

Thanks and best wishes

Angel

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