Repository navigation
A fix for the dates computed in the timezones at ±12 hours from UTC and beyond (toISODateString, nowISODateString), two new isEmpty types for values where 0 is valid, and a stricter TimeInterval.validate().
Nothing breaking for valid data: outside those timezones the dates are the same as 7.4.0, the new isEmpty types are only additions, and TimeInterval.validate() rejects only a from that was already invalid.
🐛 Fixes
toISODateString and nowISODateString give the right day in every timezone (#32). From an offset of +12h onwards, or at −12h, the day could shift by one: in Fiji toISODateString('2026-07-15') returned 2026-07-16, in New Zealand's summer a Date at midday gave the day before. Besides the timezones in the issue (Fiji, New Zealand, Chatham, Tonga, Samoa, Kiribati), the other +12h ones were affected too: Kamchatka, Anadyr, Marshall Islands, Tarawa, Tuvalu, Nauru, Wallis, Wake, Norfolk in summer.
- A day
YYYY-MM-DDkeeps its date in any timezone. - A
Date, an epoch or an ISO date-time string gives its day in the local timezone.
Everywhere else the results are the same as 7.4.0, invalid inputs included (they still throw a RangeError): checked in every IANA timezone, in V8 (Node.js, Chrome, Android) and JavaScriptCore (Safari, iOS).
→ If an app had users in those timezones, the dates saved from their devices may be one day off.
TimeInterval.validate() rejects a from that isn't a valid number. A non-numeric from (loaded as NaN) used to pass, since NaN < 0 is false.
✨ New: non-negative numbers in isEmpty (#22)
Two new field types for isEmpty() / Resource.iE(), for values where 0 is valid but negatives aren't (amounts, quantities, durations, …). Until now every numeric type treated 0 as empty.
'nonNegativeNumber'— empty if not a finite number, or< 0.iE(price, 'nonNegativeNumber')replaces!Number.isFinite(price) || price < 0.'nonNegativeInteger'— empty if not an integer, or< 0.iE(qty, 'nonNegativeInteger')replaces!Number.isInteger(qty) || qty < 0.
Unlike a plain x < 0 — which lets NaN through, since NaN < 0 is false — they also reject NaN, ±Infinity and non-numbers.
A percentage type was considered and left out: the right range depends on the context ([0,100], [1,100], [0,1], …). With the new type it's a one-liner: iE(vat, 'nonNegativeNumber') || vat > 100.