iso-string.js (2078B)
1import absFloor from '../utils/abs-floor'; 2var abs = Math.abs; 3 4function sign(x) { 5 return (x > 0) - (x < 0) || +x; 6} 7 8export function toISOString() { 9 // for ISO strings we do not use the normal bubbling rules: 10 // * milliseconds bubble up until they become hours 11 // * days do not bubble at all 12 // * months bubble up until they become years 13 // This is because there is no context-free conversion between hours and days 14 // (think of clock changes) 15 // and also not between days and months (28-31 days per month) 16 if (!this.isValid()) { 17 return this.localeData().invalidDate(); 18 } 19 20 var seconds = abs(this._milliseconds) / 1000, 21 days = abs(this._days), 22 months = abs(this._months), 23 minutes, 24 hours, 25 years, 26 s, 27 total = this.asSeconds(), 28 totalSign, 29 ymSign, 30 daysSign, 31 hmsSign; 32 33 if (!total) { 34 // this is the same as C#'s (Noda) and python (isodate)... 35 // but not other JS (goog.date) 36 return 'P0D'; 37 } 38 39 // 3600 seconds -> 60 minutes -> 1 hour 40 minutes = absFloor(seconds / 60); 41 hours = absFloor(minutes / 60); 42 seconds %= 60; 43 minutes %= 60; 44 45 // 12 months -> 1 year 46 years = absFloor(months / 12); 47 months %= 12; 48 49 // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js 50 s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; 51 52 totalSign = total < 0 ? '-' : ''; 53 ymSign = sign(this._months) !== sign(total) ? '-' : ''; 54 daysSign = sign(this._days) !== sign(total) ? '-' : ''; 55 hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; 56 57 return ( 58 totalSign + 59 'P' + 60 (years ? ymSign + years + 'Y' : '') + 61 (months ? ymSign + months + 'M' : '') + 62 (days ? daysSign + days + 'D' : '') + 63 (hours || minutes || seconds ? 'T' : '') + 64 (hours ? hmsSign + hours + 'H' : '') + 65 (minutes ? hmsSign + minutes + 'M' : '') + 66 (seconds ? hmsSign + s + 'S' : '') 67 ); 68}