Dateformat for weekyear

Things I have tried

Many things. But I don’t understand why my recent attempt does not work in my daily note:

WHERE date(topPriority), "W") = this.file.day.weekyear

This also does not show the top priority files:

WHERE dateformat(date(topPriority), "W") = this.file.day.weekyear

What I’m trying to do

I would like to have links to my priority files rendered in my daily note on the day they are a top priority.

# Priority note 1
topPriority:: [[2023-W01]]

# Priority note 2
topPriority:: [[2023-W02]]

# Priority note 3
topPriority:: [[2021-W01]]

My daily notes have format “YYYY-MM-DD”. Every day for the first week in 2023, I would like to see a priority list like this:

  • [[Priority note 1]]
  • [[Priority note 3]]

What am I doing wrong?

This

`=dateformat(date(today), "W")`

works, right?

dateformat() takes a valid date (not a string, a link, a duration, a number…) and render a string according the defined luxon token (in your case, the “W” - ISO week year number).

But the main problem is: [[2023-W01]] isn’t a date, neither date(topPriority)!
date(<link>) isn’t the best practice, but it can works. But for that you need to have a title with the right syntax to be read as date: “[[2023-01-01]]” (or the minimum for valid iso dates - docs)

Unfortunately, this shows today’s date, not the fixed day of the note. I am looking for something that takes advantage of the daily note’s implicit dates (e.g. file.day.weekyear).

I have trouble understanding. Sorry, English is not my mother tongue. I don’t want to do NOT best practice. So what “file title with the right syntax” should I set in the priority for the week, so that I can render it in the daily notes? Sometimes the priority will last a month or a quarter.

This is intended to show you that dateformat() works… but under certain conditions.
What’s the main condition? In dateformat(something, "W") something need to be a valid date: a field already read as a date - for example dateformat(file.cday, "W") - or a date created with the date() function - as dateformat(date("2023-01-05"), "W").

In your case the problem is: you’re trying to transform something like “[[2023-W02]]” in a date with date(topPriority). That is no possible, because even if date() can do that with a link - [[2023-W02]] is a link, not a string - “2023-W02” isn’t a valid string to be transformed in a date. Why? Well, if you’ve read the content in the link I give you in the last post…

… you will conclude that “2023-W02” isn’t a valid format (neither with quarter…). As a minimum to be read as a date you need to have YYYY-MM!

OK! I think I understand now. So there are 2 possiblie solutions to my question. Are there others? The two I understand now are:

  1. Use month dates:
  • In the priority note: topPriority:: 2023-01 i.e. January
  • In the daily note: WHERE topPriority = dateformat(date(this.file.day), "yyyy-MM")

OR

  1. Use strings instead of dates. Something like:
  • in priority note: topPriority:: [[2023-W01]] i.e. week 1
  • in daily note: WHERE topPriority = [[<% tp.date.now("YYYY-[W]WW", 0, tp.file.title, "YYYY-MM-DD") %>]] with Templater plugin

The weekly notes (e.g. [[2023-W01]]) exist as a .md files? Or by topPriority:: you just want to define a specific week?

way 1

If you want use a string instead of a link (to an existing file), then you can play with something like:

topPriority:: 2023-W01

Then you can compare in this way:

WHERE topPriority = dateformat(this.file.day, "yyyy-'W'WW")

way 2

Using a link (to an existing .md file, i.e., “2023-W01” needs to exist as a md file):

topPriority:: [[2023-W01]]

Then you can use:

WHERE number(split(topPriority.file.name, "W")[1]) = this.file.day.weekyear
1 Like

Thank you so much for your clarifications! The devil is definitely in the details. In testing them out, I find I’m not able to make it work if the priority extends for a period other than a week, or if there are two dates.
e.g. if it extends over a month, this does not work WHERE topPriority = dateformat(this.file.day, "yyyy-MM")

Am I looking at this problem incorrectly? Do you think I should I be looking at durations syntax instead? I don’t want to overcomplicate. All I need to know in the beginning of the week is which projects have priority. Much appreciate your kind consideration @mnvwvnm

Well, following the iso rules, if you use:

topPriority:: 2023-01

then this value is already a date, not a string! (please read the docs!)

In these cases, maybe you need to convert the two dates:

WHERE dateformat(topPriority,"yyyy-MM") = dateformat(this.file.day, "yyyy-MM")

(I really don’t understand your goal and your metadata structure. I’m answering you in the “dark”. You want to use a tool - dataview plugin - but that requires knowing how metadata works… to adapt your way to it. We are forcing a solution, but I’m not sure if it’s the best solution for you. One example: you said: " I find I’m not able to make it work if the priority extends for a period other than a week, or if there are two dates." Well, I don’t know what kind of relation you define between things, but if you have multiple values for the same field, then you can’t use “=”, because “equal means equal”… maybe you need to explore the contains() function. But, once again, I’m not sure if this is a “patch” to work temporarily, instead of a structured solution.)

You truly need to show examples of all your varying topPriority values, and what you expect out of the various formats.

It seems like you’re at least using the following:

  • weeks, with something like “2023-W01”
  • months, with something like “2023-01” ?
  • date ranges, possibly with something like “2023-01-01-2023-01-03”??

We can’t help when we need to guess what variants you expect to work. We also need to know if these values are dates or some variant of a link.

What I do understand is that you’ve got notes which are named like YYYY-MM-DD, and within each of these notes, you want to list notes where the note date is within the topPriority date range of that note.

I appreciate that you help me clarify what I am trying to do. My overall approach is:

  • to check a weekly note (e.g. 2023-W01.md) that lists the most important projects I need to work on in the upcoming week.
  • to track when projects are become priorities, which I do in a project note using a field topPriority that needs to be flexible. E.g.
Write The arrogance of Peter Miles.md
topPriority:: 2022-Q4, 2023-Q1, 2023-Q2
Submit proposals for joint project.md
topPriority:: 2023-W02
Hike Colorado Trail.md
topPriority:: 2022-07, 2023-07, 2024-07, 2025-07
A project that is just an idea and I have not committed to yet.md
topPriority:: 

I also have daily (2023-01-01), monthly (2023-01) and quarterly (2023-Q1) notes, but they are not my primary means of planning my priorities. I am not wed to any date format or link. I will switch to whatever is good practice and works best.

With these kind of values you’ve got a few issues, making your queries somewhat harder to execute.

Issues related to your chosen format

First of all, these values are all just strings, and not links nor lists of various values. In order to make them a list you would need for them to be in the format [2023-Q4, 2023-Q1, 2023-Q2]. This also includes the single values of [2023-W02].

If you opt to not changing into values, you’ll need to use a looser string match to achieve your gaols.

Secondly, that is a lot of various date formats, and I actually your best bet is to convert your current date (from your weekly ( or daily) note) into each of the possible target values. So for example just now you need to generate the variants; 2023-W01, 2023-01, 2023-01-01, 2023-Q1, and then check for either of those four values in your queries. (You might also have to tweak your string checks, as the month variant can be a prefix of the given day variant causing some issues.)

Thirdly, if you’re in a weekly note, you’d either have to generate matching cases for each of that weeks days, or you must loosen the date restriction into a week match (for the match purposes) if the topPriority is a given day. Somewhat tricky, but doable since in this case the topPriority is an actual date, which is easily converted and formatted to match a weekly format.

Finally, you would also need to just make sure that if the topPriority is empty, it doesn’t cause any issue. This shouldn’t be a big one, though.

Is this still doable?

Within an ordinary dataview query? It’ll get hairy, very fast. Maybe doable, but it’ll require some trickery with FLATTEN to generate the various options, and not sure if one has to generate all seven days of the week.

And it’ll be a rather large query, I imagine.

Using _DataviewJS, it’ll still be a large query, but I think it’s easier to generate the various option as you then have ordinary access to javascript.

Proposed solution

Generate a DataviewJS roughly following this pseudocode:

  • Generate a list of nodes having a topPriority with a value

  • Based on the note name generate the four (or more) variants of date strings to match

  • Loop on all the topPriorities notes

    • Split the priority on the comma and spaces, …
    • … and match against the variants
    • If found, add the note to the prioritisedNotes list
  • If needed, then sort the list

  • Present the prioritisedNotes list

One thing I’m still unsure of is whether you want this from weekly notes, and/or only daily notes? (And what is your name format for these notes? )

hmm… with the exception of topPriority:: 2022-07, 2023-07, 2024-07, 2025-07- these values are dates.

Are they dates when just listed without being within square brackets, though?

Square brackets don’t work for “lists” in inline fields.

For multiple values you need to use quotes (if strings… if other types you just need the usual comma):

topPriority:: "2022-W07", "2023-W07", "2024-W07", "2025-W07"

And about dates, yes, any value in “YYYY-MM” format is the minimum to be read as a date.

Dang, I hate inconsistency in any form. Whether it’s me reading, or dataview trying to interpret the values.

I read (and answered) as if it was frontmatter fields, not inline fields.

I’ve now repeated the exact same definitions into the frontmatter (with single colon), and this is the output I get:
image

And we can clearly see that in the frontmatter they’re all considered strings, whilst as inline fields, the hike and the monthly thing are indeed lists of dates.

Update: This means that a change of format will be needed in any case.A change of format could be preferrable, but it’s possible to handle as is.

1 Like

As @mnvwvnm made me aware of you’re using inline fields, not frontmatter fields, so the queries will alternate a little due to that. However, the gist of my pseudocode is still correct, and one can nullify the dates in the list, through joining them up in the query.

One possible solution

In the following script I’m setting the aDate to a fixed value, which I leave for the reader to change to dynamic. And I’m also limiting the query to my test folder, ForumStuff/f51109, which also needs to be changed.

```dataviewjs
const useTable = true

let aDate = "2023-01-01"
const notes = await dv.query(`
  table without id file.link, join(topPriority, ", ")
  from "ForumStuff/f51109"
  where topPriority AND topPriority != ""
`)

let candidatePri = []
candidatePri.push( moment(aDate).format("YYYY-MM-DD") )
candidatePri.push( moment(aDate).format("YYYY-[W]ww") )
candidatePri.push( moment(aDate).format("YYYY-MM") )
candidatePri.push( moment(aDate).format("YYYY-[Q]Q") )

if (notes.successful) {
  let results = []
  for (let [noteLink, priorities] of notes.value.values)   {
    const priorityList = priorities.split(/, */)
    console.log(`${noteLink} has ${priorities}`)
    
	for (let candidate of candidatePri) {
      if ( priorityList.contains(candidate) ) {
        console.log(`Matched ${candidate}`)
        if ( useTable )
          results.push([noteLink, candidate])
        else
          results.push(noteLink)
      }
    }
  }
  
  console.log(results)
  //dv.list(results)
  if ( useTable )
    dv.table(["Note", "Priority"], results)
  else
    dv.list(results)
  
}
```

Another variant of this script can be achieved by changing the useTable to useTable = false, in case it produces a list (without the matching priority).

With my test data it produced this result:
image

It here shows which note matched, and why it matched.

Some caveats with this scripts:

  • Which date format to use is sometimes a mystery, so I’m a little baffled as to why it is checking for the week, 2023-W52. It could be that the format needs to be tweaked a little more
  • If you’ve written multiple priorities matching, it’ll list all of them
  • I’ve not done anything related to the potential weekly notes

But as a proof of concepts, it does show that it’s possible to do this when converting everything into strings, and then split and match on the various candidates based on any given date.

1 Like

I am really just a dumb writer. Based on my low skill level, I (think) understand I could simplify things greatly if I stick to one date format for topPriority key. If I decide to use only a weekly format because that is how I plan anyway e.g. topPriority:: "2022-W07", "2023-W07", "2024-W07", "2025-W07", then:

This query in my weekly note lists the priorities for the week:

LIST
FROM "Projects"
WHERE contains(topPriority, this.file.name)

And this query in my daily note lists the priorities for the day:

LIST 
FROM "Projects"
WHERE contains(topPriority, dateformat(this.file.day, "yyyy-'W'WW"))

Is this still a good way to do things? Will I run into problems later on? Should I choose month instead of week because months are valid date formats? Thanks!

Given only weekly format as your priorities, you wouldn’t need the quotes around it, as it is already string. Other than that, it seems like it should work.

I guess I just wasted a lot of time, partially building the generic solution. Oh well, that’s the story of my life currently. :crazy_face:

I am sure you’ve helped millions of others who have read this post. I am just too dumb to understand it.

It would help me a lot if you could point me to a resource that explains what is a valid date. Here is why I thought I need quotes around the week format:

@mnvwvnm did link you to the docs, and here is the relevant section as an image:

At least that’s the valid part as far as Dataview is concerned.

1 Like