moment.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. var Class = require('./Class');
  2. var toDate = require('./toDate');
  3. var dateFormat = require('./dateFormat');
  4. var isLeapYear = require('./isLeapYear');
  5. var extend = require('./extend');
  6. var toStr = require('./toStr');
  7. var isNil = require('./isNil');
  8. var ms = require('./ms');
  9. exports = function(val) {
  10. return new Moment(val);
  11. };
  12. var Moment = Class({
  13. initialize: function Moment(val) {
  14. this._d = toDate(val);
  15. this._init();
  16. },
  17. _init: function() {
  18. var d = this._d;
  19. extend(this, {
  20. _year: d.getFullYear(),
  21. _month: d.getMonth(),
  22. _date: d.getDate(),
  23. _hour: d.getHours(),
  24. _minute: d.getMinutes(),
  25. _second: d.getSeconds(),
  26. _millisecond: d.getMilliseconds()
  27. });
  28. return this;
  29. },
  30. format: function(mask) {
  31. return dateFormat(this._d, mask);
  32. },
  33. isValid: function() {
  34. return !(this._d.toString() === 'Invalid Date');
  35. },
  36. isLeapYear: function() {
  37. return isLeapYear(this._year);
  38. },
  39. isSame: function(that) {
  40. return this.valueOf() === that.valueOf();
  41. },
  42. valueOf: function() {
  43. return this._d.getTime();
  44. },
  45. isBefore: function(that) {
  46. return this.valueOf() < that.valueOf();
  47. },
  48. isAfter: function(that) {
  49. return this.valueOf() > that.valueOf();
  50. },
  51. year: makeGetSet('year'),
  52. month: makeGetSet('month'),
  53. date: makeGetSet('date'),
  54. hour: makeGetSet('hour'),
  55. minute: makeGetSet('minute'),
  56. second: makeGetSet('second'),
  57. millisecond: makeGetSet('millisecond'),
  58. unix: function() {
  59. return floor(this.valueOf() / 1000);
  60. },
  61. clone: function() {
  62. return new Moment(this);
  63. },
  64. toDate: function() {
  65. return new Date(this._d);
  66. },
  67. toArray: function() {
  68. return [
  69. this._year,
  70. this._month,
  71. this._date,
  72. this._hour,
  73. this._minute,
  74. this._second,
  75. this._millisecond
  76. ];
  77. },
  78. toJSON: function() {
  79. return this.toISOString();
  80. },
  81. toISOString: function() {
  82. return this.toDate().toISOString();
  83. },
  84. toObject: function() {
  85. return {
  86. years: this._year,
  87. months: this._month,
  88. date: this._date,
  89. hours: this._hour,
  90. minutes: this._minute,
  91. seconds: this._second,
  92. milliseconds: this._millisecond
  93. };
  94. },
  95. toString: function() {
  96. return this._d.toUTCString();
  97. },
  98. set: function(unit, num) {
  99. var d = this._d;
  100. unit = normalizeUnit(unit);
  101. switch (unit) {
  102. case 'year':
  103. d.setFullYear(num);
  104. break;
  105. case 'month':
  106. d.setMonth(num);
  107. break;
  108. case 'date':
  109. d.setDate(num);
  110. break;
  111. case 'hour':
  112. d.setHours(num);
  113. break;
  114. case 'minute':
  115. d.setMinutes(num);
  116. break;
  117. case 'second':
  118. d.setSeconds(num);
  119. break;
  120. case 'millisecond':
  121. d.setMilliseconds(num);
  122. break;
  123. }
  124. return this._init();
  125. },
  126. startOf: function(unit) {
  127. unit = normalizeUnit(unit);
  128. /* eslint-disable no-fallthrough */
  129. switch (unit) {
  130. case 'year':
  131. this.month(0);
  132. case 'month':
  133. this.date(1);
  134. case 'day':
  135. case 'date':
  136. this.hour(0);
  137. case 'hour':
  138. this.minute(0);
  139. case 'minute':
  140. this.second(0);
  141. case 'second':
  142. this.millisecond(0);
  143. }
  144. return this;
  145. },
  146. endOf: function(unit) {
  147. return this.startOf(unit)
  148. .add(1, unit)
  149. .subtract(1, 'ms');
  150. },
  151. daysInMonth: function() {
  152. return this.clone()
  153. .endOf('month')
  154. .date();
  155. },
  156. add: createAdder(1),
  157. subtract: createAdder(-1),
  158. diff: function(input, unit, asFloat) {
  159. var that = input instanceof Moment ? input : new Moment(input);
  160. var ret;
  161. unit = normalizeUnit(unit);
  162. var diff = this - that;
  163. switch (unit) {
  164. case 'year':
  165. ret = monthDiff(this, that) / 12;
  166. break;
  167. case 'month':
  168. ret = monthDiff(this, that);
  169. break;
  170. case 'second':
  171. ret = diff / 1e3;
  172. break;
  173. // 1000
  174. case 'minute':
  175. ret = diff / 6e4;
  176. break;
  177. case 'hour':
  178. ret = diff / 36e5;
  179. break;
  180. // 1000 * 60 * 60
  181. case 'day':
  182. ret = diff / 864e5;
  183. break;
  184. default:
  185. ret = diff;
  186. }
  187. return asFloat ? ret : absFloor(ret);
  188. }
  189. });
  190. var floor = Math.floor;
  191. var ceil = Math.ceil;
  192. function absFloor(num) {
  193. return num < 0 ? ceil(num) || 0 : floor(num);
  194. }
  195. var unitShorthandMap = {
  196. y: 'year',
  197. M: 'month',
  198. D: 'date',
  199. d: 'day',
  200. h: 'hour',
  201. m: 'minute',
  202. s: 'second',
  203. ms: 'millisecond'
  204. };
  205. var regEndS = /s$/;
  206. function normalizeUnit(unit) {
  207. unit = toStr(unit);
  208. if (unitShorthandMap[unit]) return unitShorthandMap[unit];
  209. return unit.toLowerCase().replace(regEndS, '');
  210. }
  211. function makeGetSet(unit) {
  212. return function(num) {
  213. return isNil(num) ? this['_' + unit] : this.set(unit, num);
  214. };
  215. }
  216. function createAdder(dir) {
  217. return function(num, unit) {
  218. unit = normalizeUnit(unit);
  219. if (unit === 'month') return this.month(this._month + dir * num);
  220. if (unit === 'year') return this.year(this._year + dir * num);
  221. var duration = createDuration(num, unit);
  222. this._d = new Date(this.valueOf() + dir * duration);
  223. return this._init();
  224. };
  225. }
  226. var msMap = {
  227. day: 'd',
  228. hour: 'h',
  229. minute: 'm',
  230. second: 's',
  231. millisecond: ''
  232. };
  233. function createDuration(num, unit) {
  234. return ms(num + msMap[unit]);
  235. }
  236. function monthDiff(a, b) {
  237. var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month());
  238. var anchor = a.clone().add(wholeMonthDiff, 'months');
  239. var anchor2;
  240. var adjust;
  241. if (b - anchor < 0) {
  242. anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
  243. adjust = (b - anchor) / (anchor - anchor2);
  244. } else {
  245. anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
  246. adjust = (b - anchor) / (anchor2 - anchor);
  247. }
  248. return -(wholeMonthDiff + adjust) || 0;
  249. }
  250. module.exports = exports;