assemblyscript-temporal
Advanced tools
Comparing version 2.2.0 to 2.2.1
import { RegExp } from "assemblyscript-regex"; | ||
import { addDuration, coalesce, durationSign, sign, largerTimeComponent } from "./utils"; | ||
import { MICROS_PER_SECOND, MILLIS_PER_SECOND, NANOS_PER_SECOND } from "./constants"; | ||
import { PlainDateTime } from "./plaindatetime"; | ||
import { TimeComponent } from "./enums"; | ||
import { coalesce, sign } from "./util"; | ||
import { | ||
MICROS_PER_SECOND, | ||
MILLIS_PER_SECOND, | ||
NANOS_PER_SECOND | ||
} from "./util/constants"; | ||
// @ts-ignore | ||
@lazy | ||
@lazy | ||
const NULL = i32.MAX_VALUE; | ||
@@ -19,5 +24,5 @@ | ||
seconds: i32 = NULL; | ||
milliseconds: i32 = NULL; | ||
microseconds: i32 = NULL; | ||
nanoseconds: i32 = NULL; | ||
milliseconds: i64 = NULL; | ||
microseconds: i64 = NULL; | ||
nanoseconds: i64 = NULL; | ||
@@ -43,4 +48,3 @@ toDuration(): Duration { | ||
if (isString<T>()) { | ||
// @ts-ignore: cast | ||
return Duration.fromString(<string>duration); | ||
return Duration.fromString(changetype<string>(duration)); | ||
} else if (duration instanceof DurationLike) { | ||
@@ -93,4 +97,10 @@ return Duration.fromDurationLike(duration); | ||
const nanosecond = I32.parseInt(fraction.substring(6, 9)) * sign; | ||
return new Duration(years, months, weeks, days, hours, minutes, seconds, millisecond, microsecond, nanosecond); | ||
return new Duration( | ||
years, months, weeks, days, | ||
hours, minutes, seconds, | ||
millisecond, | ||
microsecond, | ||
nanosecond | ||
); | ||
} | ||
@@ -110,18 +120,19 @@ | ||
public seconds: i32 = 0, | ||
public milliseconds: i32 = 0, | ||
public microseconds: i32 = 0, | ||
public nanoseconds: i32 = 0 | ||
public milliseconds: i64 = 0, | ||
public microseconds: i64 = 0, | ||
public nanoseconds: i64 = 0 | ||
) { | ||
// durationSign returns the sign of the first non-zero component | ||
const s = this.sign; | ||
if ((years && sign(years) != s) || | ||
(months && sign(months) != s) || | ||
(weeks && sign(weeks) != s) || | ||
(days && sign(days) != s) || | ||
(hours && sign(hours) != s) || | ||
(minutes && sign(minutes) != s) || | ||
(seconds && sign(seconds) != s) || | ||
(milliseconds && sign(milliseconds) != s) || | ||
(microseconds && sign(microseconds) != s) || | ||
(nanoseconds && sign(nanoseconds) != s) | ||
const sig = this.sign; | ||
if ( | ||
(years && sign(years) != sig) || | ||
(months && sign(months) != sig) || | ||
(weeks && sign(weeks) != sig) || | ||
(days && sign(days) != sig) || | ||
(hours && sign(hours) != sig) || | ||
(minutes && sign(minutes) != sig) || | ||
(seconds && sign(seconds) != sig) || | ||
(milliseconds && sign(milliseconds) != sig) || | ||
(microseconds && sign(microseconds) != sig) || | ||
(nanoseconds && sign(nanoseconds) != sig) | ||
) { | ||
@@ -148,14 +159,13 @@ throw new RangeError("mixed-sign values not allowed as duration fields"); | ||
get sign(): i32 { | ||
return durationSign( | ||
this.years, | ||
this.months, | ||
this.weeks, | ||
this.days, | ||
this.hours, | ||
this.minutes, | ||
this.seconds, | ||
this.milliseconds, | ||
this.microseconds, | ||
this.nanoseconds | ||
); | ||
if (this.years) return sign(this.years); | ||
if (this.months) return sign(this.months); | ||
if (this.weeks) return sign(this.weeks); | ||
if (this.days) return sign(this.days); | ||
if (this.hours) return sign(this.hours); | ||
if (this.minutes) return sign(this.minutes); | ||
if (this.seconds) return sign(this.seconds); | ||
if (this.milliseconds) return sign(this.milliseconds as i32); | ||
if (this.microseconds) return sign(this.microseconds as i32); | ||
if (this.nanoseconds) return sign(this.nanoseconds as i32); | ||
return 0; | ||
} | ||
@@ -167,2 +177,15 @@ | ||
private get largestDurationUnit(): TimeComponent { | ||
if (this.years) return TimeComponent.Years; | ||
if (this.months) return TimeComponent.Months; | ||
if (this.weeks) return TimeComponent.Weeks; | ||
if (this.days) return TimeComponent.Days; | ||
if (this.hours) return TimeComponent.Hours; | ||
if (this.minutes) return TimeComponent.Minutes; | ||
if (this.seconds) return TimeComponent.Seconds; | ||
if (this.milliseconds) return TimeComponent.Milliseconds; | ||
if (this.microseconds) return TimeComponent.Microseconds; | ||
return TimeComponent.Nanoseconds; | ||
} | ||
// P1Y1M1DT1H1M1.1S | ||
@@ -197,52 +220,55 @@ toString(): string { | ||
const duration = Duration.from(durationToAdd); | ||
const largestUnit = min(this.largestDurationUnit, duration.largestDurationUnit); | ||
return addDuration(this.years, | ||
this.months, | ||
this.weeks, | ||
this.days, | ||
this.hours, | ||
this.minutes, | ||
this.seconds, | ||
this.milliseconds, | ||
this.microseconds, | ||
this.nanoseconds, | ||
duration.years, | ||
duration.months, | ||
duration.weeks, | ||
duration.days, | ||
duration.hours, | ||
duration.minutes, | ||
duration.seconds, | ||
duration.milliseconds, | ||
duration.microseconds, | ||
duration.nanoseconds, | ||
relativeTo | ||
); | ||
if (!relativeTo) { | ||
if ( | ||
largestUnit == TimeComponent.Years || | ||
largestUnit == TimeComponent.Months || | ||
largestUnit == TimeComponent.Weeks | ||
) throw new RangeError("relativeTo is required for years, months, or weeks arithmetic"); | ||
const balanced = balancedDuration( | ||
this.days + duration.days, | ||
this.hours + duration.hours, | ||
this.minutes + duration.minutes, | ||
this.seconds + duration.seconds, | ||
this.milliseconds + duration.milliseconds, | ||
this.microseconds + duration.microseconds, | ||
this.nanoseconds + duration.nanoseconds, | ||
largestUnit | ||
); | ||
return balanced; | ||
} else { | ||
const datePart = relativeTo.toPlainDate(); | ||
const dateDuration1 = new Duration(this.years, this.months, this.weeks, this.days); | ||
const dateDuration2 = new Duration(duration.years, duration.months, duration.weeks, duration.days); | ||
const intermediate = datePart.add(dateDuration1); | ||
const end = intermediate.add(dateDuration2); | ||
const dateLargestUnit = min(largestUnit, TimeComponent.Days) as TimeComponent; | ||
const dateDiff = datePart.until(end, dateLargestUnit); | ||
const dur = balancedDuration( | ||
dateDiff.days, | ||
this.hours + duration.hours, | ||
this.minutes + duration.minutes, | ||
this.seconds + duration.seconds, | ||
this.milliseconds + duration.milliseconds, | ||
this.microseconds + duration.microseconds, | ||
this.nanoseconds + duration.nanoseconds, | ||
largestUnit | ||
); | ||
return new Duration( | ||
dateDiff.years, dateDiff.months, dateDiff.weeks, | ||
dur.days, dur.hours, dur.minutes, dur.seconds, | ||
dur.milliseconds, dur.microseconds, dur.nanoseconds | ||
); | ||
} | ||
} | ||
subtract<T = DurationLike>(durationToAdd: T, relativeTo: PlainDateTime | null = null): Duration { | ||
const duration = Duration.from(durationToAdd); | ||
return addDuration(this.years, | ||
this.months, | ||
this.weeks, | ||
this.days, | ||
this.hours, | ||
this.minutes, | ||
this.seconds, | ||
this.milliseconds, | ||
this.microseconds, | ||
this.nanoseconds, | ||
-duration.years, | ||
-duration.months, | ||
-duration.weeks, | ||
-duration.days, | ||
-duration.hours, | ||
-duration.minutes, | ||
-duration.seconds, | ||
-duration.milliseconds, | ||
-duration.microseconds, | ||
-duration.nanoseconds, | ||
relativeTo | ||
); | ||
return this.add(Duration.from(durationToAdd).negated(), relativeTo); | ||
} | ||
@@ -282,5 +308,4 @@ | ||
function toString<T extends number>(value: T, suffix: string): string { | ||
return value | ||
? (isFloat<T>() ? stringify(value) : value.toString()) + suffix | ||
: ""; | ||
if (value) return (isFloat<T>() ? stringify(value) : value.toString()) + suffix; | ||
return ""; | ||
} | ||
@@ -292,2 +317,145 @@ | ||
return F64.isSafeInteger(value) ? i64(value).toString() : value.toString(); | ||
} | ||
} | ||
function totalDurationNanoseconds( | ||
days: i64, | ||
hours: i64, | ||
minutes: i64, | ||
seconds: i64, | ||
milliseconds: i64, | ||
microseconds: i64, | ||
nanoseconds: i64 | ||
): i64 { | ||
hours += days * 24; | ||
minutes += hours * 60; | ||
seconds += minutes * 60; | ||
milliseconds += seconds * MILLIS_PER_SECOND; | ||
microseconds += milliseconds * 1000; | ||
return nanoseconds + microseconds * 1000; | ||
} | ||
export function balancedDuration( | ||
days: i32, | ||
hours: i32, | ||
minutes: i32, | ||
seconds: i32, | ||
milliseconds: i64, | ||
microseconds: i64, | ||
nanoseconds: i64, | ||
largestUnit: TimeComponent | ||
): Duration { | ||
const durationNs = totalDurationNanoseconds( | ||
days as i64, | ||
hours as i64, | ||
minutes as i64, | ||
seconds as i64, | ||
milliseconds, | ||
microseconds, | ||
nanoseconds | ||
); | ||
let | ||
nanosecondsI64: i64 = 0, | ||
microsecondsI64: i64 = 0, | ||
millisecondsI64: i64 = 0, | ||
secondsI64: i64 = 0, | ||
minutesI64: i64 = 0, | ||
hoursI64: i64 = 0, | ||
daysI64: i64 = 0; | ||
if ( | ||
largestUnit >= TimeComponent.Years && | ||
largestUnit <= TimeComponent.Days | ||
) { | ||
// inlined nanosecondsToDays | ||
const oneDayNs: i64 = 24 * 60 * 60 * NANOS_PER_SECOND; | ||
if (durationNs != 0) { | ||
daysI64 = durationNs / oneDayNs; | ||
nanosecondsI64 = durationNs % oneDayNs; | ||
} | ||
} else { | ||
nanosecondsI64 = durationNs; | ||
} | ||
const sig = i32(sign(nanosecondsI64)); | ||
nanosecondsI64 = abs(nanosecondsI64); | ||
switch (largestUnit) { | ||
case TimeComponent.Years: | ||
case TimeComponent.Months: | ||
case TimeComponent.Weeks: | ||
case TimeComponent.Days: | ||
case TimeComponent.Hours: | ||
microsecondsI64 = nanosecondsI64 / 1000; | ||
nanosecondsI64 = nanosecondsI64 % 1000; | ||
millisecondsI64 = microsecondsI64 / 1000; | ||
microsecondsI64 = microsecondsI64 % 1000; | ||
secondsI64 = millisecondsI64 / 1000; | ||
millisecondsI64 = millisecondsI64 % 1000; | ||
minutesI64 = secondsI64 / 60; | ||
secondsI64 = secondsI64 % 60; | ||
hoursI64 = minutesI64 / 60; | ||
minutesI64 = minutesI64 % 60; | ||
break; | ||
case TimeComponent.Minutes: | ||
microsecondsI64 = nanosecondsI64 / 1000; | ||
nanosecondsI64 = nanosecondsI64 % 1000; | ||
millisecondsI64 = microsecondsI64 / 1000; | ||
microsecondsI64 = microsecondsI64 % 1000; | ||
secondsI64 = millisecondsI64 / 1000; | ||
millisecondsI64 = millisecondsI64 % 1000; | ||
minutesI64 = secondsI64 / 60; | ||
secondsI64 = secondsI64 % 60; | ||
break; | ||
case TimeComponent.Seconds: | ||
microsecondsI64 = nanosecondsI64 / 1000; | ||
nanosecondsI64 = nanosecondsI64 % 1000; | ||
millisecondsI64 = microsecondsI64 / 1000; | ||
microsecondsI64 = microsecondsI64 % 1000; | ||
secondsI64 = millisecondsI64 / 1000; | ||
millisecondsI64 = millisecondsI64 % 1000; | ||
break; | ||
case TimeComponent.Milliseconds: | ||
microsecondsI64 = nanosecondsI64 / 1000; | ||
nanosecondsI64 = nanosecondsI64 % 1000; | ||
millisecondsI64 = microsecondsI64 / 1000; | ||
microsecondsI64 = microsecondsI64 % 1000; | ||
break; | ||
case TimeComponent.Microseconds: | ||
microsecondsI64 = nanosecondsI64 / 1000; | ||
nanosecondsI64 = nanosecondsI64 % 1000; | ||
break; | ||
case TimeComponent.Nanoseconds: | ||
break; | ||
} | ||
return new Duration( | ||
0, | ||
0, | ||
0, | ||
i32(daysI64), | ||
i32(hoursI64) * sig, | ||
i32(minutesI64) * sig, | ||
i32(secondsI64) * sig, | ||
i32(millisecondsI64) * sig, | ||
i32(microsecondsI64) * sig, | ||
i32(nanosecondsI64) * sig | ||
); | ||
} | ||
import "./env"; | ||
export * from "./plaintime"; | ||
export * from "./plaindate"; | ||
export * from "./plaindatetime"; | ||
export * from "./duration"; | ||
export { PlainTime } from "./plaintime"; | ||
export { PlainDate } from "./plaindate"; | ||
export { PlainDateTime } from "./plaindatetime"; | ||
export { Duration } from "./duration"; | ||
export * from "./enums"; | ||
export * from "./now"; | ||
export * from "./instant"; | ||
export { now } from "./now"; | ||
export { Instant } from "./instant"; |
@@ -1,10 +0,7 @@ | ||
import { Duration, DurationLike } from "./duration"; | ||
import { NANOS_PER_SECOND } from "./util/constants"; | ||
import { balancedDuration, Duration, DurationLike } from "./duration"; | ||
import { TimeComponent } from "./enums"; | ||
import { PlainDateTime } from "./plaindatetime"; | ||
import { | ||
getPartsFromEpoch, | ||
formatISOString, | ||
ord, | ||
balanceDuration, | ||
} from "./utils"; | ||
import { ord } from "./util"; | ||
import { formatISOString } from "./util/format"; | ||
@@ -33,6 +30,8 @@ export class Instant { | ||
@inline | ||
public static fromEpochSeconds(seconds: i64): Instant { | ||
return new Instant(seconds * 1_000_000_000); | ||
return new Instant(seconds * NANOS_PER_SECOND); | ||
} | ||
@inline | ||
public static fromEpochMilliseconds(millis: i64): Instant { | ||
@@ -42,2 +41,3 @@ return new Instant(millis * 1_000_000); | ||
@inline | ||
public static fromEpochMicroseconds(micros: i64): Instant { | ||
@@ -47,2 +47,3 @@ return new Instant(micros * 1_000); | ||
@inline | ||
public static fromEpochNanoseconds(nanos: i64): Instant { | ||
@@ -52,3 +53,3 @@ return new Instant(nanos); | ||
constructor(public epochNanoseconds: i64) {} | ||
constructor(public readonly epochNanoseconds: i64) {} | ||
@@ -67,3 +68,3 @@ @inline | ||
get epochSeconds(): i64 { | ||
return this.epochNanoseconds / 1_000_000_000; | ||
return this.epochNanoseconds / NANOS_PER_SECOND; | ||
} | ||
@@ -102,6 +103,6 @@ | ||
if (largestUnit <= TimeComponent.Days) { | ||
throw new RangeError("Largest unit must be smaller than days") | ||
throw new RangeError("Largest unit must be smaller than days"); | ||
} | ||
const diffNanos = this.epochNanoseconds - instant.epochNanoseconds; | ||
return balanceDuration(0, 0, 0, 0, 0, 0, diffNanos, largestUnit); | ||
return balancedDuration(0, 0, 0, 0, 0, 0, diffNanos, largestUnit); | ||
} | ||
@@ -114,10 +115,11 @@ | ||
if (largestUnit <= TimeComponent.Days) { | ||
throw new RangeError("Largest unit must be smaller than days") | ||
throw new RangeError("Largest unit must be smaller than days"); | ||
} | ||
const diffNanos = instant.epochNanoseconds - this.epochNanoseconds; | ||
return balanceDuration(0, 0, 0, 0, 0, 0, diffNanos, largestUnit); | ||
return balancedDuration(0, 0, 0, 0, 0, 0, diffNanos, largestUnit); | ||
} | ||
equals(other: Instant): boolean { | ||
return this.epochNanoseconds == other.epochNanoseconds; | ||
equals<T>(other: T): boolean { | ||
const otherInstant = other instanceof Instant ? other : Instant.from(other); | ||
return this.epochNanoseconds == otherInstant.epochNanoseconds; | ||
} | ||
@@ -127,15 +129,33 @@ | ||
toString(): string { | ||
const parts = getPartsFromEpoch(this.epochNanoseconds); | ||
const quotient = this.epochNanoseconds / 1_000_000; | ||
const remainder = this.epochNanoseconds % 1_000_000; | ||
let epochMilliseconds = +quotient; | ||
let nanos = +remainder; | ||
if (nanos < 0) { | ||
nanos += 1_000_000; | ||
epochMilliseconds -= 1; | ||
} | ||
const microsecond = i32((nanos / 1_000) % 1_000); | ||
const nanosecond = i32(nanos % 1_000); | ||
const item = new Date(epochMilliseconds); | ||
const year = item.getUTCFullYear(); | ||
const month = item.getUTCMonth() + 1; | ||
const day = item.getUTCDate(); | ||
const hour = item.getUTCHours(); | ||
const minute = item.getUTCMinutes(); | ||
const second = item.getUTCSeconds(); | ||
const millisecond = item.getUTCMilliseconds(); | ||
return ( | ||
formatISOString( | ||
parts.year, | ||
parts.month, | ||
parts.day, | ||
parts.hour, | ||
parts.minute, | ||
parts.second, | ||
parts.millisecond, | ||
parts.microsecond, | ||
parts.nanosecond | ||
year, | ||
month, | ||
day, | ||
hour, | ||
minute, | ||
second, | ||
millisecond, | ||
microsecond, | ||
nanosecond | ||
) + "Z" | ||
@@ -151,6 +171,6 @@ ); | ||
i64(duration.milliseconds) * 1_000_000 + | ||
i64(duration.seconds) * 1_000_000_000 + | ||
i64(duration.minutes) * 60 * 1_000_000_000 + | ||
i64(duration.hours) * 60 * 60 * 1_000_000_000 | ||
i64(duration.seconds) * NANOS_PER_SECOND + | ||
i64(duration.minutes) * 60 * NANOS_PER_SECOND + | ||
i64(duration.hours) * 60 * 60 * NANOS_PER_SECOND | ||
); | ||
} |
@@ -1,4 +0,2 @@ | ||
import { RegExp } from "assemblyscript-regex"; | ||
import { Duration, DurationLike } from "./duration"; | ||
import { balancedDuration, Duration, DurationLike } from "./duration"; | ||
import { Overflow, TimeComponent } from "./enums"; | ||
@@ -8,5 +6,5 @@ import { PlainDateTime } from "./plaindatetime"; | ||
import { PlainTime } from "./plaintime"; | ||
import { PlainYearMonth } from "./plainyearmonth"; | ||
import { PlainYearMonth, balancedYearMonth } from "./plainyearmonth"; | ||
import { parseISOString } from "./util/format"; | ||
import { | ||
addDate, | ||
dayOfWeek, | ||
@@ -18,11 +16,13 @@ leapYear, | ||
daysInYear, | ||
balanceDuration, | ||
checkDateTimeRange | ||
} from "./util/calendar"; | ||
import { | ||
ord, | ||
sign, | ||
clamp, | ||
toPaddedString, | ||
rejectDate, | ||
checkDateTimeRange, | ||
compareTemporalDate, | ||
differenceDate, | ||
coalesce, | ||
parseISOString, | ||
} from "./utils"; | ||
checkRange, | ||
floorDiv, | ||
} from "./util"; | ||
@@ -150,11 +150,122 @@ export class DateLike { | ||
const date = PlainDate.from(dateLike); | ||
return differenceDate( | ||
this.year, | ||
this.month, | ||
this.day, | ||
date.year, | ||
date.month, | ||
date.day, | ||
largestUnit | ||
); | ||
switch (largestUnit) { | ||
case TimeComponent.Years: | ||
case TimeComponent.Months: { | ||
let sign = -PlainDate.compare(this, date); | ||
if (sign == 0) return new Duration(); | ||
let startYear = this.year; | ||
let startMonth = this.month; | ||
let endYear = date.year; | ||
let endMonth = date.month; | ||
let endDay = date.day; | ||
let years = endYear - startYear; | ||
let mid = new PlainDate(this.year, this.month, this.day).add(new Duration(years)); | ||
let midSign = -PlainDate.compare(mid, date); | ||
if (midSign === 0) { | ||
return largestUnit === TimeComponent.Years | ||
? new Duration(years) | ||
: new Duration(0, years * 12); | ||
} | ||
let months = endMonth - startMonth; | ||
if (midSign !== sign) { | ||
years -= sign; | ||
months += sign * 12; | ||
} | ||
mid = new PlainDate(this.year, this.month, this.day).add(new Duration(years, months)); | ||
midSign = -PlainDate.compare(mid, date); | ||
if (midSign === 0) { | ||
return largestUnit === TimeComponent.Years | ||
? new Duration(years, months) | ||
: new Duration(0, months + years * 12); | ||
} | ||
if (midSign !== sign) { | ||
// The end date is later in the month than mid date (or earlier for | ||
// negative durations). Back up one month. | ||
months -= sign; | ||
if (months === -sign) { | ||
years -= sign; | ||
months = sign * 11; | ||
} | ||
mid = new PlainDate(this.year, this.month, this.day).add(new Duration(years, months)); | ||
} | ||
let days = endDay - mid.day; // If we get here, months and years are correct (no overflow), and `mid` | ||
// is within the range from `start` to `end`. To count the days between | ||
// `mid` and `end`, there are 3 cases: | ||
// 1) same month: use simple subtraction | ||
// 2) end is previous month from intermediate (negative duration) | ||
// 3) end is next month from intermediate (positive duration) | ||
if (mid.month === endMonth && mid.year === endYear) { | ||
// 1) same month: use simple subtraction | ||
} else if (sign < 0) { | ||
// 2) end is previous month from intermediate (negative duration) | ||
// Example: intermediate: Feb 1, end: Jan 30, DaysInMonth = 31, days = -2 | ||
days -= daysInMonth(endYear, endMonth); | ||
} else { | ||
// 3) end is next month from intermediate (positive duration) | ||
// Example: intermediate: Jan 29, end: Feb 1, DaysInMonth = 31, days = 3 | ||
days += daysInMonth(mid.year, mid.month); | ||
} | ||
if (largestUnit === TimeComponent.Months) { | ||
months += years * 12; | ||
years = 0; | ||
} | ||
return new Duration(years, months, 0, days); | ||
} | ||
case TimeComponent.Weeks: | ||
case TimeComponent.Days: { | ||
let neg = PlainDate.compare(this, date) < 0; | ||
let smallerYear = neg ? this.year : date.year; | ||
let smallerMonth = neg ? this.month : date.month; | ||
let smallerDay = neg ? this.day : date.day; | ||
let largerYear = neg ? date.year : this.year; | ||
let largerMonth = neg ? date.month : this.month; | ||
let largerDay = neg ? date.day : this.day; | ||
let years = largerYear - smallerYear; | ||
let days = ( | ||
dayOfYear(largerYear, largerMonth, largerDay) - | ||
dayOfYear(smallerYear, smallerMonth, smallerDay) | ||
); | ||
while (years > 0) { | ||
days += daysInYear(smallerYear + years - 1); | ||
years -= 1; | ||
} | ||
let weeks = 0; | ||
if (largestUnit === TimeComponent.Weeks) { | ||
weeks = floorDiv(days, 7); | ||
days -= weeks * 7; | ||
} | ||
return new Duration( | ||
0, 0, | ||
neg ? weeks : -weeks, | ||
neg ? days : -days | ||
); | ||
} | ||
default: | ||
throw new Error('differenceDate - cannot support TimeComponent < Days'); | ||
} | ||
} | ||
@@ -166,12 +277,3 @@ | ||
): Duration { | ||
const date = PlainDate.from(dateLike); | ||
return differenceDate( | ||
date.year, | ||
date.month, | ||
date.day, | ||
this.year, | ||
this.month, | ||
this.day, | ||
largestUnit | ||
); | ||
return PlainDate.from(dateLike).until(this, largestUnit); | ||
} | ||
@@ -181,5 +283,5 @@ | ||
return new PlainDate( | ||
coalesce(dateLike.year, this.year), | ||
coalesce(dateLike.month, this.month), | ||
coalesce(dateLike.day, this.day) | ||
coalesce(dateLike.year, this.year, -1), | ||
coalesce(dateLike.month, this.month, -1), | ||
coalesce(dateLike.day, this.day, -1) | ||
); | ||
@@ -194,3 +296,3 @@ } | ||
const balancedDuration = balanceDuration( | ||
const balancedDur = balancedDuration( | ||
duration.days, | ||
@@ -205,13 +307,19 @@ duration.hours, | ||
); | ||
const newDate = addDate( | ||
this.year, | ||
this.month, | ||
const yearMonth = balancedYearMonth( | ||
this.year + duration.years, | ||
this.month + duration.months | ||
); | ||
const regulatedDate = regulateDate( | ||
yearMonth.year, | ||
yearMonth.month, | ||
this.day, | ||
duration.years, | ||
duration.months, | ||
duration.weeks, | ||
balancedDuration.days, | ||
overflow | ||
); | ||
return new PlainDate(newDate.year, newDate.month, newDate.day); | ||
return balancedDate( | ||
regulatedDate.year, regulatedDate.month, | ||
regulatedDate.day + balancedDur.days + duration.weeks * 7 | ||
); | ||
} | ||
@@ -224,26 +332,3 @@ | ||
const duration = Duration.from(durationToSubtract); | ||
const balancedDuration = balanceDuration( | ||
duration.days, | ||
duration.hours, | ||
duration.minutes, | ||
duration.seconds, | ||
duration.milliseconds, | ||
duration.microseconds, | ||
duration.nanoseconds, | ||
TimeComponent.Days | ||
); | ||
const newDate = addDate( | ||
this.year, | ||
this.month, | ||
this.day, | ||
-duration.years, | ||
-duration.months, | ||
-duration.weeks, | ||
-balancedDuration.days, | ||
overflow | ||
); | ||
return new PlainDate(newDate.year, newDate.month, newDate.day); | ||
return this.add(duration.negated(), overflow); | ||
} | ||
@@ -279,4 +364,92 @@ | ||
if (a === b) return 0; | ||
return compareTemporalDate(a.year, a.month, a.day, b.year, b.month, b.day); | ||
let res = a.year - b.year; | ||
if (res) return sign(res); | ||
res = a.month - b.month; | ||
if (res) return sign(res); | ||
return ord(a.day, b.day); | ||
} | ||
} | ||
function rejectDate(year: i32, month: i32, day: i32): void { | ||
if (!checkRange(month, 1, 12)) { | ||
throw new RangeError("month out of range"); | ||
} | ||
if (!checkRange(day, 1, daysInMonth(year, month))) { | ||
throw new RangeError("day out of range"); | ||
} | ||
} | ||
// https://github.com/tc39/proposal-temporal/blob/49629f785eee61e9f6641452e01e995f846da3a1/polyfill/lib/ecmascript.mjs#L2617 | ||
function constrainDate(year: i32, month: i32, day: i32): PlainDate { | ||
month = clamp(month, 1, 12); | ||
day = clamp(day, 1, daysInMonth(year, month)); | ||
return new PlainDate(year, month, day); | ||
} | ||
// https://github.com/tc39/proposal-temporal/blob/49629f785eee61e9f6641452e01e995f846da3a1/polyfill/lib/ecmascript.mjs#L2617 | ||
function regulateDate( | ||
year: i32, | ||
month: i32, | ||
day: i32, | ||
overflow: Overflow | ||
): PlainDate { | ||
switch (overflow) { | ||
case Overflow.Reject: | ||
rejectDate(year, month, day); | ||
break; | ||
case Overflow.Constrain: | ||
const date = constrainDate(year, month, day); | ||
year = date.year; | ||
month = date.month; | ||
day = date.day; | ||
break; | ||
} | ||
return new PlainDate(year, month, day); | ||
} | ||
export function balancedDate(year: i32, month: i32, day: i32): PlainDate { | ||
const yearMonth = balancedYearMonth(year, month); | ||
year = yearMonth.year; | ||
month = yearMonth.month; | ||
let daysPerYear = 0; | ||
let testYear = month > 2 ? year : year - 1; | ||
while (((daysPerYear = daysInYear(testYear)), day < -daysPerYear)) { | ||
year -= 1; | ||
testYear -= 1; | ||
day += daysPerYear; | ||
} | ||
testYear += 1; | ||
while (((daysPerYear = daysInYear(testYear)), day > daysPerYear)) { | ||
year += 1; | ||
testYear += 1; | ||
day -= daysPerYear; | ||
} | ||
while (day < 1) { | ||
const yearMonth = balancedYearMonth(year, month - 1); | ||
year = yearMonth.year; | ||
month = yearMonth.month; | ||
day += daysInMonth(year, month); | ||
} | ||
let monthDays = 0; | ||
while (monthDays = daysInMonth(year, month), day > monthDays) { | ||
const yearMonth = balancedYearMonth(year, month + 1); | ||
year = yearMonth.year; | ||
month = yearMonth.month; | ||
day -= monthDays; | ||
} | ||
return new PlainDate(year, month, day); | ||
} |
@@ -1,6 +0,12 @@ | ||
import { Duration, DurationLike } from "./duration"; | ||
import { balancedDuration, Duration, DurationLike } from "./duration"; | ||
import { Overflow, TimeComponent } from "./enums"; | ||
import { PlainTime } from "./plaintime"; | ||
import { balancedTime, PlainTime } from "./plaintime"; | ||
import { balancedDate, PlainDate } from "./plaindate"; | ||
import { PlainYearMonth } from "./plainyearmonth"; | ||
import { PlainMonthDay } from "./plainmonthday"; | ||
import { ord, sign, coalesce } from "./util"; | ||
import { formatISOString, parseISOString } from "./util/format"; | ||
import { | ||
dayOfWeek, | ||
leapYear, | ||
dayOfYear, | ||
@@ -10,14 +16,4 @@ weekOfYear, | ||
daysInYear, | ||
coalesce, | ||
compareTemporalDateTime, | ||
addDateTime, | ||
parseISOString, | ||
leapYear, | ||
epochFromParts, | ||
differenceDateTime, | ||
formatISOString, | ||
} from "./utils"; | ||
import { PlainDate } from "./plaindate"; | ||
import { PlainYearMonth } from "./plainyearmonth"; | ||
import { PlainMonthDay } from "./plainmonthday"; | ||
epochFromParts | ||
} from "./util/calendar"; | ||
@@ -197,23 +193,37 @@ // @ts-ignore | ||
return differenceDateTime( | ||
const diffTime = this.toPlainTime().until(other.toPlainTime()); | ||
const balanced = balancedDate( | ||
this.year, | ||
this.month, | ||
this.day, | ||
this.hour, | ||
this.minute, | ||
this.second, | ||
this.millisecond, | ||
this.microsecond, | ||
this.nanosecond, | ||
other.year, | ||
other.month, | ||
other.day, | ||
other.hour, | ||
other.minute, | ||
other.second, | ||
other.millisecond, | ||
other.microsecond, | ||
other.nanosecond, | ||
this.day + diffTime.days | ||
); | ||
const diffDate = balanced.until( | ||
other.toPlainDate(), | ||
min(largestUnit, TimeComponent.Days) | ||
); | ||
// Signs of date part and time part may not agree; balance them together | ||
const balancedBoth = balancedDuration( | ||
diffDate.days, | ||
diffTime.hours, | ||
diffTime.minutes, | ||
diffTime.seconds, | ||
diffTime.milliseconds, | ||
diffTime.microseconds, | ||
diffTime.nanoseconds, | ||
largestUnit | ||
); | ||
return new Duration( | ||
diffDate.years, | ||
diffDate.months, | ||
diffDate.weeks, | ||
balancedBoth.days, | ||
balancedBoth.hours, | ||
balancedBoth.minutes, | ||
balancedBoth.seconds, | ||
balancedBoth.milliseconds, | ||
balancedBoth.microseconds, | ||
balancedBoth.nanoseconds | ||
); | ||
} | ||
@@ -225,14 +235,7 @@ | ||
): Duration { | ||
const other = PlainDateTime.from(otherLike); | ||
return PlainDateTime.from(otherLike).until(this, largestUnit); | ||
} | ||
return differenceDateTime( | ||
other.year, | ||
other.month, | ||
other.day, | ||
other.hour, | ||
other.minute, | ||
other.second, | ||
other.millisecond, | ||
other.microsecond, | ||
other.nanosecond, | ||
toString(): string { | ||
return formatISOString( | ||
this.year, | ||
@@ -246,19 +249,6 @@ this.month, | ||
this.microsecond, | ||
this.nanosecond, | ||
largestUnit | ||
this.nanosecond | ||
); | ||
} | ||
toString(): string { | ||
return formatISOString(this.year, | ||
this.month, | ||
this.day, | ||
this.hour, | ||
this.minute, | ||
this.second, | ||
this.millisecond, | ||
this.microsecond, | ||
this.nanosecond); | ||
} | ||
toPlainTime(): PlainTime { | ||
@@ -289,22 +279,28 @@ return new PlainTime( | ||
if (a === b) return 0; | ||
return compareTemporalDateTime( | ||
a.year, | ||
a.month, | ||
a.day, | ||
a.hour, | ||
a.minute, | ||
a.second, | ||
a.millisecond, | ||
a.microsecond, | ||
a.nanosecond, | ||
b.year, | ||
b.month, | ||
b.day, | ||
b.hour, | ||
b.minute, | ||
b.second, | ||
b.millisecond, | ||
b.microsecond, | ||
b.nanosecond | ||
); | ||
let res = a.year - b.year; | ||
if (res) return sign(res); | ||
res = a.month - b.month; | ||
if (res) return sign(res); | ||
res = a.day - b.day; | ||
if (res) return sign(res); | ||
res = a.hour - b.hour; | ||
if (res) return sign(res); | ||
res = a.minute - b.minute; | ||
if (res) return sign(res); | ||
res = a.second - b.second; | ||
if (res) return sign(res); | ||
res = a.millisecond - b.millisecond; | ||
if (res) return sign(res); | ||
res = a.microsecond - b.microsecond; | ||
if (res) return sign(res); | ||
return ord(a.nanosecond, b.nanosecond); | ||
} | ||
@@ -334,34 +330,31 @@ | ||
const newDate = addDateTime( | ||
this.year, | ||
this.month, | ||
this.day, | ||
this.hour, | ||
this.minute, | ||
this.second, | ||
this.millisecond, | ||
this.microsecond, | ||
this.nanosecond, | ||
duration.years, | ||
duration.months, | ||
duration.weeks, | ||
duration.days, | ||
duration.hours, | ||
duration.minutes, | ||
duration.seconds, | ||
duration.milliseconds, | ||
duration.microseconds, | ||
duration.nanoseconds, | ||
const addedTime = balancedTime( | ||
duration.hours + this.hour, | ||
duration.minutes + this.minute, | ||
duration.seconds + this.second, | ||
(duration.milliseconds + this.millisecond) as i64, | ||
(duration.microseconds + this.microsecond) as i64, | ||
(duration.nanoseconds + this.nanosecond) as i64 | ||
); | ||
const addedDate = new PlainDate(this.year, this.month, this.day).add( | ||
new Duration( | ||
duration.years, | ||
duration.months, | ||
duration.weeks, | ||
duration.days + addedTime.deltaDays | ||
), | ||
overflow | ||
); | ||
return new PlainDateTime( | ||
newDate.year, | ||
newDate.month, | ||
newDate.day, | ||
newDate.hour, | ||
newDate.minute, | ||
newDate.second, | ||
newDate.millisecond, | ||
newDate.microsecond, | ||
newDate.nanosecond | ||
addedDate.year, | ||
addedDate.month, | ||
addedDate.day, | ||
addedTime.hour, | ||
addedTime.minute, | ||
addedTime.second, | ||
addedTime.millisecond, | ||
addedTime.microsecond, | ||
addedTime.nanosecond | ||
); | ||
@@ -374,38 +367,4 @@ } | ||
): PlainDateTime { | ||
const duration = Duration.from(durationToSubtract); | ||
const newDate = addDateTime( | ||
this.year, | ||
this.month, | ||
this.day, | ||
this.hour, | ||
this.minute, | ||
this.second, | ||
this.millisecond, | ||
this.microsecond, | ||
this.nanosecond, | ||
-duration.years, | ||
-duration.months, | ||
-duration.weeks, | ||
-duration.days, | ||
-duration.hours, | ||
-duration.minutes, | ||
-duration.seconds, | ||
-duration.milliseconds, | ||
-duration.microseconds, | ||
-duration.nanoseconds, | ||
overflow | ||
); | ||
return new PlainDateTime( | ||
newDate.year, | ||
newDate.month, | ||
newDate.day, | ||
newDate.hour, | ||
newDate.minute, | ||
newDate.second, | ||
newDate.millisecond, | ||
newDate.microsecond, | ||
newDate.nanosecond | ||
); | ||
return this.add(Duration.from(durationToSubtract).negated(), overflow); | ||
} | ||
} |
import { RegExp } from "assemblyscript-regex"; | ||
import { PlainDateTime } from "./plaindatetime"; | ||
import { PlainDate } from "./plaindate"; | ||
import { | ||
coalesce, | ||
toPaddedString, | ||
checkDateTimeRange | ||
} from "./utils"; | ||
import { checkDateTimeRange } from "./util/calendar"; | ||
import { coalesce, toPaddedString } from "./util"; | ||
@@ -97,4 +94,4 @@ export class MonthDayLike { | ||
return ( | ||
this.day == other.day && | ||
this.month == other.month && | ||
this.day == other.day && | ||
this.referenceISOYear == other.referenceISOYear | ||
@@ -101,0 +98,0 @@ ); |
@@ -1,2 +0,2 @@ | ||
import { Duration, DurationLike } from "./duration"; | ||
import { balancedDuration, Duration, DurationLike } from "./duration"; | ||
import { Overflow, TimeComponent } from "./enums"; | ||
@@ -9,11 +9,8 @@ import { RegExp } from "assemblyscript-regex"; | ||
ord, | ||
checkRange, | ||
rejectTime, | ||
balanceDuration, | ||
addTime, | ||
toPaddedString, | ||
coalesce, | ||
differenceTime, | ||
regulateTime, | ||
} from "./utils"; | ||
clamp, | ||
floorDiv, | ||
checkRange | ||
} from "./util"; | ||
@@ -29,2 +26,12 @@ export class TimeLike { | ||
export class BalancedTime { | ||
deltaDays: i32; | ||
hour: i32; | ||
minute: i32; | ||
second: i32; | ||
millisecond: i32; | ||
microsecond: i32; | ||
nanosecond: i32; | ||
} | ||
export class PlainTime { | ||
@@ -233,3 +240,3 @@ @inline | ||
) | ||
return balanceDuration( | ||
return balancedDuration( | ||
// diffTime.days, | ||
@@ -271,3 +278,3 @@ 0, | ||
) | ||
return balanceDuration( | ||
return balancedDuration( | ||
// diffTime.days, | ||
@@ -336,3 +343,3 @@ 0, | ||
const regulatedTime = regulateTime( | ||
return regulateTime( | ||
newTime.hour, | ||
@@ -346,10 +353,2 @@ newTime.minute, | ||
) | ||
return new PlainTime( | ||
regulatedTime.hour, | ||
regulatedTime.minute, | ||
regulatedTime.second, | ||
regulatedTime.millisecond, | ||
regulatedTime.microsecond, | ||
regulatedTime.nanosecond | ||
); | ||
} | ||
@@ -375,3 +374,3 @@ | ||
const regulatedTime = regulateTime( | ||
return regulateTime( | ||
newTime.hour, | ||
@@ -384,12 +383,190 @@ newTime.minute, | ||
Overflow.Reject | ||
) | ||
return new PlainTime( | ||
regulatedTime.hour, | ||
regulatedTime.minute, | ||
regulatedTime.second, | ||
regulatedTime.millisecond, | ||
regulatedTime.microsecond, | ||
regulatedTime.nanosecond | ||
); | ||
} | ||
} | ||
// https://github.com/tc39/proposal-temporal/blob/515ee6e339bb4a1d3d6b5a42158f4de49f9ed953/polyfill/lib/ecmascript.mjs#L2874-L2910 | ||
export function differenceTime( | ||
h1: i32, m1: i32, s1: i32, ms1: i32, µs1: i32, ns1: i32, | ||
h2: i32, m2: i32, s2: i32, ms2: i32, µs2: i32, ns2: i32 | ||
): Duration { | ||
let hours = h2 - h1; | ||
let minutes = m2 - m1; | ||
let seconds = s2 - s1; | ||
let milliseconds = ms2 - ms1; | ||
let microseconds = µs2 - µs1; | ||
let nanoseconds = ns2 - ns1; | ||
let sig = 0; | ||
if (hours) sig = sign(hours); | ||
else if (minutes) sig = sign(minutes); | ||
else if (seconds) sig = sign(seconds); | ||
else if (milliseconds) sig = sign(milliseconds); | ||
else if (microseconds) sig = sign(microseconds); | ||
else if (nanoseconds) sig = sign(nanoseconds); | ||
const balanced = balancedTime( | ||
hours * sig, | ||
minutes * sig, | ||
seconds * sig, | ||
milliseconds * sig, | ||
microseconds * sig, | ||
nanoseconds * sig | ||
); | ||
return new Duration( | ||
0, | ||
0, | ||
0, | ||
balanced.deltaDays * sig, | ||
balanced.hour * sig, | ||
balanced.minute * sig, | ||
balanced.second * sig, | ||
balanced.millisecond * sig, | ||
balanced.microsecond * sig, | ||
balanced.nanosecond * sig | ||
); | ||
} | ||
function addTime( | ||
hour: i32, | ||
minute: i32, | ||
second: i32, | ||
millisecond: i32, | ||
microsecond: i32, | ||
nanosecond: i32, | ||
hours: i32, | ||
minutes: i32, | ||
seconds: i32, | ||
milliseconds: i64, | ||
microseconds: i64, | ||
nanoseconds: i64 | ||
): BalancedTime { | ||
hours += hour; | ||
minutes += minute; | ||
seconds += second; | ||
milliseconds += millisecond; | ||
microseconds += microsecond; | ||
nanoseconds += nanosecond; | ||
return balancedTime( | ||
hours, minutes, seconds, | ||
milliseconds, microseconds, nanoseconds | ||
); | ||
} | ||
// https://github.com/tc39/proposal-temporal/blob/515ee6e339bb4a1d3d6b5a42158f4de49f9ed953/polyfill/lib/ecmascript.mjs#L2676-L2684 | ||
function constrainTime( | ||
hour: i32, | ||
minute: i32, | ||
second: i32, | ||
millisecond: i32, | ||
microsecond: i32, | ||
nanosecond: i32, | ||
): PlainTime { | ||
hour = clamp(hour, 0, 23); | ||
minute = clamp(minute, 0, 59); | ||
second = clamp(second, 0, 59); | ||
millisecond = clamp(millisecond, 0, 999); | ||
microsecond = clamp(microsecond, 0, 999); | ||
nanosecond = clamp(nanosecond, 0, 999); | ||
return new PlainTime(hour, minute, second, millisecond, microsecond, nanosecond); | ||
} | ||
// https://github.com/tc39/proposal-temporal/blob/515ee6e339bb4a1d3d6b5a42158f4de49f9ed953/polyfill/lib/ecmascript.mjs#L407-L422 | ||
function regulateTime( | ||
hour: i32, | ||
minute: i32, | ||
second: i32, | ||
millisecond: i32, | ||
microsecond: i32, | ||
nanosecond: i32, | ||
overflow: Overflow | ||
): PlainTime { | ||
switch (overflow) { | ||
case Overflow.Reject: | ||
rejectTime(hour, minute, second, millisecond, microsecond, nanosecond); | ||
break; | ||
case Overflow.Constrain: | ||
const time = constrainTime( | ||
hour, | ||
minute, | ||
second, | ||
millisecond, | ||
microsecond, | ||
nanosecond | ||
); | ||
hour = time.hour; | ||
minute = time.minute; | ||
second = time.second; | ||
millisecond = time.millisecond; | ||
microsecond = time.microsecond; | ||
nanosecond = time.nanosecond; | ||
break; | ||
} | ||
return new PlainTime(hour, minute, second, millisecond, microsecond, nanosecond); | ||
} | ||
function rejectTime( | ||
hour: i32, | ||
minute: i32, | ||
second: i32, | ||
millisecond: i32, | ||
microsecond: i32, | ||
nanosecond: i32 | ||
): void { | ||
if (!( | ||
checkRange(hour, 0, 23) && | ||
checkRange(minute, 0, 59) && | ||
checkRange(second, 0, 59) && | ||
checkRange(millisecond, 0, 999) && | ||
checkRange(microsecond, 0, 999) && | ||
checkRange(nanosecond, 0, 999) | ||
)) throw new RangeError("time out of range"); | ||
} | ||
export function balancedTime( | ||
hour: i64, | ||
minute: i64, | ||
second: i64, | ||
millisecond: i64, | ||
microsecond: i64, | ||
nanosecond: i64 | ||
): BalancedTime { | ||
let quotient = floorDiv(nanosecond, 1000); | ||
microsecond += quotient; | ||
nanosecond -= quotient * 1000; | ||
quotient = floorDiv(microsecond, 1000); | ||
millisecond += quotient; | ||
microsecond -= quotient * 1000; | ||
quotient = floorDiv(millisecond, 1000); | ||
second += quotient; | ||
millisecond -= quotient * 1000; | ||
quotient = floorDiv(second, 60); | ||
minute += quotient; | ||
second -= quotient * 60; | ||
quotient = floorDiv(minute, 60); | ||
hour += quotient; | ||
minute -= quotient * 60; | ||
let deltaDays = floorDiv(hour, 24); | ||
hour -= deltaDays * 24; | ||
return { | ||
deltaDays: i32(deltaDays), | ||
hour: i32(hour), | ||
minute: i32(minute), | ||
second: i32(second), | ||
millisecond: i32(millisecond), | ||
microsecond: i32(microsecond), | ||
nanosecond: i32(nanosecond) | ||
}; | ||
} |
import { RegExp } from "assemblyscript-regex"; | ||
import { Duration, DurationLike } from "./duration"; | ||
import { balancedDuration, Duration, DurationLike } from "./duration"; | ||
import { Overflow, TimeComponent } from "./enums"; | ||
import { PlainDate } from "./plaindate"; | ||
import { PlainDateTime } from "./plaindatetime"; | ||
import { isoYearString } from "./util/format"; | ||
import { | ||
balanceDuration, | ||
checkDateTimeRange, | ||
leapYear, | ||
daysInMonth, | ||
daysInYear, | ||
checkDateTimeRange | ||
} from "./util/calendar" | ||
import { | ||
coalesce, | ||
compareTemporalDate, | ||
daysInMonth, | ||
durationSign, | ||
isoYearString, | ||
leapYear, | ||
toPaddedString, | ||
daysInYear, | ||
} from "./utils"; | ||
floorDiv, | ||
sign, | ||
ord | ||
} from "./util"; | ||
@@ -199,3 +201,3 @@ export class YearMonthLike { | ||
const balancedDuration = balanceDuration( | ||
const balancedDur = balancedDuration( | ||
duration.days, | ||
@@ -211,10 +213,9 @@ duration.hours, | ||
const sign = durationSign( | ||
duration.years, | ||
duration.months, | ||
duration.weeks, | ||
balancedDuration.days | ||
); | ||
let sig = 0; | ||
if (duration.years) sig = sign(duration.years); | ||
else if (duration.months) sig = sign(duration.months); | ||
else if (duration.weeks) sig = sign(duration.weeks); | ||
else if (balancedDur.days) sig = sign(balancedDur.days); | ||
const day = sign < 0 ? daysInMonth(this.year, this.month) : 1; | ||
const day = sig < 0 ? daysInMonth(this.year, this.month) : 1; | ||
const startDate = new PlainDate(this.year, this.month, day); | ||
@@ -244,3 +245,3 @@ const addedDate = startDate.add(duration, overflow); | ||
const balancedDuration = balanceDuration( | ||
const balancedDur = balancedDuration( | ||
duration.days, | ||
@@ -256,10 +257,9 @@ duration.hours, | ||
const sign = durationSign( | ||
duration.years, | ||
duration.months, | ||
duration.weeks, | ||
balancedDuration.days | ||
); | ||
let sig = 0; | ||
if (duration.years) sig = sign(duration.years); | ||
else if (duration.months) sig = sign(duration.months); | ||
else if (duration.weeks) sig = sign(duration.weeks); | ||
else if (balancedDur.days) sig = sign(balancedDur.days); | ||
const day = sign < 0 ? daysInMonth(this.year, this.month) : 1; | ||
const day = sig < 0 ? daysInMonth(this.year, this.month) : 1; | ||
const startdate = new PlainDate(this.year, this.month, day); | ||
@@ -272,11 +272,19 @@ const subtractedDate = startdate.add(duration, overflow); | ||
if (a === b) return 0; | ||
return compareTemporalDate( | ||
a.year, | ||
a.month, | ||
a.referenceISODay, | ||
b.year, | ||
b.month, | ||
b.referenceISODay | ||
); | ||
let res = a.year - b.year; | ||
if (res) return sign(res); | ||
res = a.month - b.month; | ||
if (res) return sign(res); | ||
return ord(a.referenceISODay, b.referenceISODay); | ||
} | ||
} | ||
export function balancedYearMonth(year: i32, month: i32): PlainYearMonth { | ||
month -= 1; | ||
year += floorDiv(month, 12); | ||
month %= 12; | ||
month += month < 0 ? 13 : 1; | ||
return new PlainYearMonth(year, month); | ||
} |
{ | ||
"name": "assemblyscript-temporal", | ||
"version": "2.2.0", | ||
"version": "2.2.1", | ||
"description": "An implementation of temporal within AssemblyScript, with an initial focus on non-timezone-aware classes and functionality.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37
501859
11701