iso-string.js 2.0 KB

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