-
Notifications
You must be signed in to change notification settings - Fork 147
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
Interval API #205
Comments
This has actually been talked about. The conclusion was that we do not want to do this at this time, though there is nothing hindering a follow-on proposal. Here are some of the reasons: What is an Interval:
are just the ones that come to mind immediately. So in fact an Interval isn't a single thing, it's any one of several things. In short which one it should be is very much a business logic decision. In addition there is nothing that prevents anyone from creating any of those Interval types. This goes with the decision not to include the combination types for Absolute/TimeZone and DateTime/TimeZone either. |
Is this something which is really not wanted? Something similar like luxon Interval would really be helpful! |
Thanks for the feedback! So if I understand correctly, this is the business logic that you would need:
The reason for not doing it so far is as stated above, there would be three (possibly four: Temporal.Date, Temporal.DateTime, Temporal.Absolute, maybe Temporal.YearMonth) interval types needed which would clutter the interface, whereas there's only one Luxon interval type because it deals with legacy Date. We'd expect that business logic would use at most one of the interval types. See also #682 for discussion of the last item. That said, I will reopen this issue and put it on our feedback list for consideration. FWIW, off the top of my head it'd look something like this to implement it in your business logic: class Interval {
constructor(start, end) {
this._start = Temporal.Absolute.from(start);
this._end = Temporal.Absolute.from(end);
}
contains(absolute) {
// assuming start inclusive, end exclusive?
return Temporal.Absolute.compare(absolute, this._start) >= 0 &&
Temporal.Absolute.compare(absolute, this._end) < 0;
}
encloses(interval) {
return Temporal.Absolute.compare(interval._start, this._start) >= 0 &&
Temporal.Absolute.compare(interval._end, this._end) < 0;
}
*iterate(duration) {
let absolute = this._start;
while (this.contains(absolute)) {
yield absolute;
absolute = absolute.plus(duration);
}
}
} |
Thanks for putting it on the feedback list!! Yes my business logic would look something like your described Interval class except i also need sometimes that the end of the Interval is included ( And if i understand the Temporal API correctly Temporal.Absolute.from is always a ISO 8601 string because the documentation described it as Maybe it would be possible to create something like this so the Interval would be related to its construction types... type TemporalType = Temporal.Absolute | Temporal.DateTime | Temporal.YearMonth | Temporal.Date | Temporal.Time ...;
class Interval {
constructor(start: TemporalType , end: TemporalType) {
if(start !instanceof end){
throw new TypeError(`start is not from the same type as end...`);
}
this._start = start;
this._end = end;
this._temporalType = start.constructor;
}
contains(temporalType: TemporalType, inclusive?: {...}) {
// check if start or end should be inclusive
const containable = temporalType.toTemporalType(); //don't know how to do this right now
return this._temporalType.compare(containable, this._start) >= 0 &&
this._temporalType.compare(containable, this._end) < 0;
}
encloses(interval: Interval, inclusive?: {...}) {
// check interval has the same TemporalType ...
return this._temporalType.compare(interval._start, this._start) >= 0 &&
this._temporalType.compare(interval._end, this._end) < 0;
}
*iterate(duration: Temporal.Duration) {
let absolute = this._start;
while (this.contains(absolute)) {
yield absolute;
absolute = absolute.plus(duration);
}
}
} |
Just to add a bit of history. When we closed this issue, we were of a mindset to keep the API as slim as possible. For that reason we wanted to have as little in scope as possible. (No calendars, durations-type, etc). We have since (with calendars I think it became real) abandoned the idea of going incremental and having the smallest possible API footprint. (While I’m still advocating to keep it small and not go over board). So there is no fundamental reason why we should not have intervals. At the same time: I seriously question the value of it. That’s because an interval makes sense both in terms of So to my mind adding |
I'd personally consider the concept of I think @boeckMt's draft implementation well abstracts the dependency to a specific type TemporalType = Temporal.Absolute | Temporal.DateTime;
class Interval {
constructor(start: TemporalType, end: TemporalType | Temporal.Duration) {
if (end !instanceof Temporal.Duration && start !instanceof end){
throw new TypeError(`start is not from the same type as end...`);
}
this._start = start;
this._end = end instanceof Temporal.Duration ? start.plus(end) : end;
}
contains(datetime: TemporalType, inclusive?: {...}) {
// check if start or end should be inclusive
return containable.compare(this._start) >= 0 && containable.compare(this._end) < 0;
}
encloses(interval: Interval, inclusive?: {...}) {
// check if start or end should be inclusive
return this._start.compare(interval._start) >= 0 && this._end.compare(interval._end) < 0;
}
*iterate(duration: Temporal.Duration) {
let value = this._start;
while (this.contains(value)) {
yield value;
value = value.plus(duration);
}
}
} |
This is not present in the revision of Temporal that's currently under review, but let's continue gathering information at js-temporal/proposal-temporal-v2#4. |
Using code from @stebogit and @boeckMt, I created the temporal-interval package which implements the Interval class. I expanded upon it, fixed some edge cases, and wrote unit tests. https://www.npmjs.com/package/temporal-interval A few other considerations:
|
I was mostly looking for a way of formatting (printing) a date format. In case others are looking for the same thing, there is already an API that does this today, available in most browers. |
I couldn't see this being discussed elsewhere, but has an interval API been thought about? Many use cases require passing around "start" and "end" points in time, and many calculations you want to do with
Duration
only work if you anchor it with a start or end date, like checking if two intervals (e.g. events) overlap, or if a point in time falls into an interval. ISO6801 defines intervals as a concept and their string representation.The API could look roughly like this:
On a side note: I have a feeling considering these APIs that compose the objects already in the proposal is very important for making decisions such as whether to go with separate
ZonedDateTime
and the semantics ofDuration
. For example, without timezone information, we need to provide it totoString()
, andduration
can only be expressed in hours, not in days or larger (because depending on timezone there could be DST shifts within the interval which means not every day will be 24h long).The text was updated successfully, but these errors were encountered: