Signatur
Beschreibung
subtract() zieht eine andere Dauer von der aktuellen Temporal.Duration ab und liefert das Ergebnis als neues Objekt. Wie alle Temporal-Objekte ist Duration unveränderlich: Die ursprüngliche Instanz bleibt unverändert. d.subtract(other) entspricht dabei d.add(other.negated()).
Das Argument muss kein Temporal.Duration-Objekt sein. Es kann auch ein ISO-8601-Dauer-String (z. B. "PT1H30M") oder ein Objekt mit Dauer-Feldern (z. B. { minutes: 30 }) sein. Es wird intern genauso umgewandelt wie bei Temporal.Duration.from().
Das Ergebnis wird bis zur größten Einheit ausgeglichen, die in einer der beiden Dauern vorkommt. Tage zählen dabei immer als genau 24 Stunden. Ist die abgezogene Dauer größer, ist das Ergebnis negativ (z. B. -PT30M). Gemischte Vorzeichen innerhalb eines Ergebnisses gibt es nicht.
Wichtig: Wochen, Monate und Jahre sind kalenderabhängige Einheiten, denn ein Monat hat je nach Datum 28 bis 31 Tage. Enthält eine der beiden Dauern solche Einheiten mit einem Wert ungleich null, wirft subtract() einen RangeError. In diesem Fall rechnet man über ein konkretes Referenzdatum, zum Beispiel mit PlainDate.prototype.add()/subtract() und anschließend until().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $other Pflicht | Temporal.Duration | string | Object | Die Dauer, die abgezogen werden soll. Erlaubt sind eine Temporal.Duration-Instanz, ein ISO-8601-String wie "PT15M" oder ein Objekt mit Feldern wie { hours: 1, minutes: 30 }. Das Argument wird wie bei Temporal.Duration.from() umgewandelt. |
Rückgabewert
Temporal.Duration-Objekt mit der Differenz this − other. Es ist bis zur größten Einheit der beiden Dauern ausgeglichen und kann negativ sein.Beispiele
Restzeit eines Pomodoro-Timers berechnen
const sitzung = Temporal.Duration.from({ minutes: 25 });
const vergangen = Temporal.Duration.from({ minutes: 7, seconds: 30 });
const rest = sitzung.subtract(vergangen);
console.log(rest.toString());
console.log(`${rest.minutes} Min. ${rest.seconds} Sek. übrig`);
// Das Original bleibt unverändert
console.log(sitzung.toString());
String- und Objekt-Argumente, Ausgleich und negatives Ergebnis
const d = Temporal.Duration.from("PT1H30M");
console.log(d.subtract("PT45M").toString()); // String als Argument
console.log(d.subtract({ hours: 2 }).toString()); // Ergebnis wird negativ
// Tage zählen als 24 Stunden, ausgeglichen wird bis zur größten Einheit (Tage)
const zweiTage = Temporal.Duration.from({ days: 2 });
console.log(zweiTage.subtract({ hours: 12 }).toString());
const neg = d.subtract({ hours: 2 });
console.log(neg.sign, neg.minutes);
Kalendereinheiten: RangeError abfangen und über ein Referenzdatum rechnen
const vertrag = Temporal.Duration.from({ months: 3 });
const kuendigungsfrist = Temporal.Duration.from({ days: 10 });
try {
vertrag.subtract(kuendigungsfrist);
} catch (err) {
console.log(err instanceof RangeError); // Monate sind kalenderabhängig
}
// Lösung: über ein konkretes Startdatum rechnen
const start = Temporal.PlainDate.from("2024-01-31");
const ende = start.add(vertrag).subtract(kuendigungsfrist);
const ergebnis = start.until(ende, { largestUnit: "months" });
console.log(ende.toString());
console.log(ergebnis.toString());
// Wichtig · Fallstricke
- Kein
relativeTomehr: Frühe Temporal-Entwürfe und ältere Polyfills erlaubten als zweiten Parameter ein Optionsobjekt mitrelativeTo. Das wurde aus der Spezifikation entfernt. Heute führen Jahre, Monate oder Wochen ungleich null in einer der beiden Dauern zu einemRangeError. - Tage = 24 Stunden:
subtract()berücksichtigt keine Zeitzonen und keine Sommerzeitumstellungen. Wenn solche Tage eine Rolle spielen, rechne mitTemporal.ZonedDateTime. - Unveränderlichkeit: Die Methode gibt immer ein neues Objekt zurück. Ein Aufruf wie
d.subtract(x);ohne Zuweisung hat keine Wirkung. - Einheiten werden nur bis zur größten beteiligten Einheit ausgeglichen.
PT90MminusPT30MergibtPT60Mund nichtPT1H. Für eine andere Darstellung nutzeround({ largestUnit: \"hours\" }). - Kompatibilität: Temporal gibt es ab Firefox 139 und Chrome/Edge 144. Safari unterstützt es noch nicht standardmäßig, ebenso wenig ältere Node.js-Versionen. Für breite Unterstützung brauchst du einen Polyfill wie
@js-temporal/polyfillodertemporal-polyfill.