Moment.js date issue for specific formats (/w dashes)

What I’m trying to do

I’m attempting to use the following dataviewjs inline query. That takes the files created today using a YAML header that is generated using templater in the format shown below and counts them.

$=dv.pages().where(f=>f.date == moment().format('YYYY-MM-DD')).length

All my “date” headers are in the YYYY-MM-DD format which for today would be “2023-11-04”

Things I have tried

I know that the right output is given when using the moment().format(‘YYYY-MM-DD’) code in the terminal (VS code).

I know the query works if I change it something without dashes, for example YYYY or dddd.
Changing the “date” header to 2023 has it count, or changing the “date” header to Saturday (dddd) has it count as well.

I really don’t understand what is going on because everywhere I’ve tested, this should query any files created today and count them, but it is not. I’ve narrowed it down to something to do with dashes because even using “MMM DD, YYYY” and changing the “date” header to “Nov 04, 2023” also worked.

Has anyone seen this weird issue before?

have you tried .format(‘yyyy-MM-DD’)? I feel like there was a reason to use lower case over upper but it escapes me

no it didn’t seem to work. Which is really strange because running the command to console log on VSCode shows the correct date format. :confused:

Obsidian_AajN796DGh

Obsidian_lJNPoSZQnO

Obsidian_y5sojAApog

Code_DfeFee23L9

hrm this might be a matter of comparing an object and a string.

for example if I give my note a date attribute in the yaml, this returns “object”:

`$=typeof dv.current().date`

whereas this returns string:

`$=typeof dv.date(dv.current().date).toFormat('yyyy-MM-dd')`

as does this:

`$=typeof moment().format('YYYY-MM-DD')`

Which may be why the comparison is failing. Hopefully this gives you more to go on!

Thanks for all the information. After trying to find a way to turn both to either string or objects I came up with nothing. 2023 is a number so it works, Saturday is a string so it also works. But anything beyond that is seen as an object so it does not.

Heres the latest iteration:
$=dv.pages().where(f=> f.date == (dv.date(moment().format('yyyy-MM-dd')))).length

where f.date should be returning an date object as $=dv.current().date is automatically formatted to November 04, 2023 and the type being object.

and the dv.date also returning a date object, same formatting and with a type of object.

So I genuinely don’t see how I could get this to work. Both are date objects (apparently) but return the number 0. I don’t know if its even possible with inline dataviewjs.

Obsidian_5YPWaayNDE

Sadly, dv.date("today") != dv.date("today"), to get the equality operator working you need to use .ts on those dates, like in the following:
$= dv.pages().where( f=> f.date.ts == dv.date( moment().format('yyyy-MM-dd') ).ts ).length


Date handling is icky, very icky. As stated doing dv.date("today") == dv.date("today") returns false. However, you could do dv.date("today").ts == dv.date("today").ts which would return true

When handling dates using dataview they’re of the type DateTime (a Luxon time object), which are indeed not the same as a moment() date object. You could do stuff like dv.date( moment().toISOString() ) to convert the moment date into a DateTime object (but be vary of the time portion of the moment date in question.

So what reliable option do you have?

  • Convert both parts to strings, compare the following:
    • Using dv.date().toFormat("yyyy-MM-dd") (using Luxon tokens)
    • and moment.format("YYYY-MM-DD") (using Moment tokens)
  • Convert to dv.date() (aka DateTime) and use .ts equality comparison
    • Add .ts to the DateTime object: dv.date().ts
    • Strip the time part, and convert to DateTime before adding .ts: dv.date(moment().startOf('day').toISOString()).ts
  • Convert to moment dates, and use .isSame() comparison
    • moment(dv.date("today")).isSame(moment().startOf('day'))
    • It turns out that moment() != moment() also, so you need to use the isSame() comparison even though the date (and timestamp) is the same
An ugly, very ugly test file

Here is the test file showing the return value of various incantation, and comparison of those return values. Read and weep…

[dvDate:: 2023-11-10]

- field value: `$= dv.current().dvDate `
- dv.date > moment > start of day > format: `$= dv.date( moment().startOf('day').format("YYYY-MM-DD") ) `
 - [d] dv.date equality comparison: `$= dv.current().dvDate == dv.date( moment().startOf('day').format("YYYY-MM-DD")) `
   - Or alternatively: `dv.date( moment().format("YYYY-MM-DD") ).ts`
- [p] dv.date.ts equality comparison: `$= dv.current().dvDate.ts == dv.date( moment().startOf('day').format("YYYY-MM-DD")).ts `

#### Reasoning .ts comparison
- [c] dv.date == dv.date: `$= dv.date("today") == dv.date("today") `
- [p] dv.date.ts == dv.date.ts: `$= dv.date("today").ts == dv.date("today").ts `

### Moment comparison
- moment - dv.date: `$= moment(dv.current().dvDate).toISOString() `
- moment - start of day:  `$= moment().startOf('day').toISOString() `
- [c] moment equality comparison: `$= moment(dv.current().dvDate) == moment().startOf('day') `
- [p] moment.isSame comparison: `$= moment(dv.current().dvDate).isSame(moment().startOf('day')) `
- [p] moment.toISOString() comparison:  `$= moment(dv.current().dvDate).toISOString() == moment().startOf('day').toISOString() ` 

### String comparison
- dvDate: `$= dv.current().dvDate.toFormat("yyyy-MM-dd") `
- moment: `$= moment().format("YYYY-MM-DD") `
- [p] String comparison: `$= dv.current().dvDate.toFormat("yyyy-MM-dd") == moment().format("YYYY-MM-DD") `

### TS comparison
- dvDate: `$= dv.current().dvDate.ts `
- moment: `$= dv.date(moment().startOf('day').toISOString()).ts `
- [p] String comparison: `$= dv.current().dvDate.ts == dv.date(moment().startOf('day').toISOString()).ts `

My display of these statements

Using custom checkboxes to indicates which matches [p] and which fails [d], we get this output:

Note especially how many of the displayed values are indeed equal, and yet the comparison is false.

PS! The moment().startOf('day').format("YYYY-MM-DD") is somewhat redundant, as we also use the formatting to loose the time part. Left in there as I’m way too confused already by my own code and date handling…