841497bc0a62bead51d628dfd798c35d7b860aef5a02d5e4c79f43ef409987acf2e54d4cf88d6daab1215d4dca8183314a008f71debc386bf6fe43eb797f34 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import absFloor from '../utils/abs-floor';
  2. import absCeil from '../utils/abs-ceil';
  3. export function bubble() {
  4. var milliseconds = this._milliseconds,
  5. days = this._days,
  6. months = this._months,
  7. data = this._data,
  8. seconds,
  9. minutes,
  10. hours,
  11. years,
  12. monthsFromDays;
  13. // if we have a mix of positive and negative values, bubble down first
  14. // check: https://github.com/moment/moment/issues/2166
  15. if (
  16. !(
  17. (milliseconds >= 0 && days >= 0 && months >= 0) ||
  18. (milliseconds <= 0 && days <= 0 && months <= 0)
  19. )
  20. ) {
  21. milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
  22. days = 0;
  23. months = 0;
  24. }
  25. // The following code bubbles up values, see the tests for
  26. // examples of what that means.
  27. data.milliseconds = milliseconds % 1000;
  28. seconds = absFloor(milliseconds / 1000);
  29. data.seconds = seconds % 60;
  30. minutes = absFloor(seconds / 60);
  31. data.minutes = minutes % 60;
  32. hours = absFloor(minutes / 60);
  33. data.hours = hours % 24;
  34. days += absFloor(hours / 24);
  35. // convert days to months
  36. monthsFromDays = absFloor(daysToMonths(days));
  37. months += monthsFromDays;
  38. days -= absCeil(monthsToDays(monthsFromDays));
  39. // 12 months -> 1 year
  40. years = absFloor(months / 12);
  41. months %= 12;
  42. data.days = days;
  43. data.months = months;
  44. data.years = years;
  45. return this;
  46. }
  47. export function daysToMonths(days) {
  48. // 400 years have 146097 days (taking into account leap year rules)
  49. // 400 years have 12 months === 4800
  50. return (days * 4800) / 146097;
  51. }
  52. export function monthsToDays(months) {
  53. // the reverse of daysToMonths
  54. return (months * 146097) / 4800;
  55. }