Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date math should produce objects, not numbers #1032

Open
LeaVerou opened this issue Aug 1, 2024 · 0 comments
Open

Date math should produce objects, not numbers #1032

LeaVerou opened this issue Aug 1, 2024 · 0 comments

Comments

@LeaVerou
Copy link
Member

LeaVerou commented Aug 1, 2024

One of Formula2’s advantages over spreadsheets is its superior temporal math capabilities as our latest study showed.
However, the way this is implemented today is rather awkward.
Operators do their own checks within their logic to decide whether temporal math is desired, e.g. see https://github.com/mavoweb/mavo/blob/main/src/mavoscript.js#L231
This does not produce a coherent result.

  • Functions like duration() need to operate on numbers of milliseconds,
    which means they can be inaccurate for durations longer than a month, since they convert milliseconds to months using a number of average days in a month (30.4something).
  • When a date difference is actually output without going through a suitable function first, it's a weird number (of milliseconds)
  • We have separate functions to produce machine readable temporal values (e.g. datetime() and readable_datime())

With suitable values, operators would be able to get the info they need without parsing strings (which should also be faster), and when the strings actually do need to be output, they would produce a human-readable representation (though we'd need to be careful to output ISO 8601 values when used in datetime attributes — but this is no different than how we handle numbers differently in attributes vs text).

This means:

  • duration() would be stringified as it does today, but would include properties about the start and end of the interval (if available), as well as all terms that can be read if it's passed around. E.g. duration(interval) - 2 * days() would do the right thing.
  • $now should be a structured object, and should output the right info for the usage. E.g. datetime="[$now]" should Just Work™ without needing hullabaloos like time($now).
  • date1 - date2 should basically be equivalent to duration(date1 - date2)

It's important that we preserve the functionality that strings containing dates can automatically be operated on as dates.
However, we should probably represent this as actual objects (with suitable valueOf(), toString(), toJSON(), Symbol.toPrimitive, Symbol.toStringTag, etc.).
These objects could be subclassing String, so that we maintain the current handling as much as possible. We could call it TemporalString.
One benefit of this is that strings are naturally immutable, so we can parse it, store info about it, and the info will never change.

Operators and functions should still work and would have more information to produce better results. But also outputting the raw value would also work.
The object would keep track of whether this is a date or an interval, its granularity, and cache its elements (year, month, etc) for performance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant