You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
256 lines
6.7 KiB
256 lines
6.7 KiB
var Class = require('./Class'); |
|
var toDate = require('./toDate'); |
|
var dateFormat = require('./dateFormat'); |
|
var isLeapYear = require('./isLeapYear'); |
|
var extend = require('./extend'); |
|
var toStr = require('./toStr'); |
|
var isNil = require('./isNil'); |
|
var ms = require('./ms'); |
|
exports = function(val) { |
|
return new Moment(val); |
|
}; |
|
var Moment = Class({ |
|
initialize: function Moment(val) { |
|
this._d = toDate(val); |
|
this._init(); |
|
}, |
|
_init: function() { |
|
var d = this._d; |
|
extend(this, { |
|
_year: d.getFullYear(), |
|
_month: d.getMonth(), |
|
_date: d.getDate(), |
|
_hour: d.getHours(), |
|
_minute: d.getMinutes(), |
|
_second: d.getSeconds(), |
|
_millisecond: d.getMilliseconds() |
|
}); |
|
return this; |
|
}, |
|
format: function(mask) { |
|
return dateFormat(this._d, mask); |
|
}, |
|
isValid: function() { |
|
return !(this._d.toString() === 'Invalid Date'); |
|
}, |
|
isLeapYear: function() { |
|
return isLeapYear(this._year); |
|
}, |
|
isSame: function(that) { |
|
return this.valueOf() === that.valueOf(); |
|
}, |
|
valueOf: function() { |
|
return this._d.getTime(); |
|
}, |
|
isBefore: function(that) { |
|
return this.valueOf() < that.valueOf(); |
|
}, |
|
isAfter: function(that) { |
|
return this.valueOf() > that.valueOf(); |
|
}, |
|
year: makeGetSet('year'), |
|
month: makeGetSet('month'), |
|
date: makeGetSet('date'), |
|
hour: makeGetSet('hour'), |
|
minute: makeGetSet('minute'), |
|
second: makeGetSet('second'), |
|
millisecond: makeGetSet('millisecond'), |
|
unix: function() { |
|
return floor(this.valueOf() / 1000); |
|
}, |
|
clone: function() { |
|
return new Moment(this); |
|
}, |
|
toDate: function() { |
|
return new Date(this._d); |
|
}, |
|
toArray: function() { |
|
return [ |
|
this._year, |
|
this._month, |
|
this._date, |
|
this._hour, |
|
this._minute, |
|
this._second, |
|
this._millisecond |
|
]; |
|
}, |
|
toJSON: function() { |
|
return this.toISOString(); |
|
}, |
|
toISOString: function() { |
|
return this.toDate().toISOString(); |
|
}, |
|
toObject: function() { |
|
return { |
|
years: this._year, |
|
months: this._month, |
|
date: this._date, |
|
hours: this._hour, |
|
minutes: this._minute, |
|
seconds: this._second, |
|
milliseconds: this._millisecond |
|
}; |
|
}, |
|
toString: function() { |
|
return this._d.toUTCString(); |
|
}, |
|
set: function(unit, num) { |
|
var d = this._d; |
|
unit = normalizeUnit(unit); |
|
switch (unit) { |
|
case 'year': |
|
d.setFullYear(num); |
|
break; |
|
case 'month': |
|
d.setMonth(num); |
|
break; |
|
case 'date': |
|
d.setDate(num); |
|
break; |
|
case 'hour': |
|
d.setHours(num); |
|
break; |
|
case 'minute': |
|
d.setMinutes(num); |
|
break; |
|
case 'second': |
|
d.setSeconds(num); |
|
break; |
|
case 'millisecond': |
|
d.setMilliseconds(num); |
|
break; |
|
} |
|
return this._init(); |
|
}, |
|
startOf: function(unit) { |
|
unit = normalizeUnit(unit); |
|
|
|
/* eslint-disable no-fallthrough */ |
|
switch (unit) { |
|
case 'year': |
|
this.month(0); |
|
case 'month': |
|
this.date(1); |
|
case 'day': |
|
case 'date': |
|
this.hour(0); |
|
case 'hour': |
|
this.minute(0); |
|
case 'minute': |
|
this.second(0); |
|
case 'second': |
|
this.millisecond(0); |
|
} |
|
return this; |
|
}, |
|
endOf: function(unit) { |
|
return this.startOf(unit) |
|
.add(1, unit) |
|
.subtract(1, 'ms'); |
|
}, |
|
daysInMonth: function() { |
|
return this.clone() |
|
.endOf('month') |
|
.date(); |
|
}, |
|
add: createAdder(1), |
|
subtract: createAdder(-1), |
|
diff: function(input, unit, asFloat) { |
|
var that = input instanceof Moment ? input : new Moment(input); |
|
var ret; |
|
unit = normalizeUnit(unit); |
|
var diff = this - that; |
|
switch (unit) { |
|
case 'year': |
|
ret = monthDiff(this, that) / 12; |
|
break; |
|
case 'month': |
|
ret = monthDiff(this, that); |
|
break; |
|
case 'second': |
|
ret = diff / 1e3; |
|
break; |
|
// 1000 |
|
case 'minute': |
|
ret = diff / 6e4; |
|
break; |
|
|
|
case 'hour': |
|
ret = diff / 36e5; |
|
break; |
|
// 1000 * 60 * 60 |
|
case 'day': |
|
ret = diff / 864e5; |
|
break; |
|
|
|
default: |
|
ret = diff; |
|
} |
|
return asFloat ? ret : absFloor(ret); |
|
} |
|
}); |
|
var floor = Math.floor; |
|
var ceil = Math.ceil; |
|
function absFloor(num) { |
|
return num < 0 ? ceil(num) || 0 : floor(num); |
|
} |
|
var unitShorthandMap = { |
|
y: 'year', |
|
M: 'month', |
|
D: 'date', |
|
d: 'day', |
|
h: 'hour', |
|
m: 'minute', |
|
s: 'second', |
|
ms: 'millisecond' |
|
}; |
|
var regEndS = /s$/; |
|
|
|
function normalizeUnit(unit) { |
|
unit = toStr(unit); |
|
if (unitShorthandMap[unit]) return unitShorthandMap[unit]; |
|
return unit.toLowerCase().replace(regEndS, ''); |
|
} |
|
function makeGetSet(unit) { |
|
return function(num) { |
|
return isNil(num) ? this['_' + unit] : this.set(unit, num); |
|
}; |
|
} |
|
function createAdder(dir) { |
|
return function(num, unit) { |
|
unit = normalizeUnit(unit); |
|
if (unit === 'month') return this.month(this._month + dir * num); |
|
if (unit === 'year') return this.year(this._year + dir * num); |
|
var duration = createDuration(num, unit); |
|
this._d = new Date(this.valueOf() + dir * duration); |
|
return this._init(); |
|
}; |
|
} |
|
var msMap = { |
|
day: 'd', |
|
hour: 'h', |
|
minute: 'm', |
|
second: 's', |
|
millisecond: '' |
|
}; |
|
function createDuration(num, unit) { |
|
return ms(num + msMap[unit]); |
|
} |
|
|
|
function monthDiff(a, b) { |
|
var wholeMonthDiff = (b.year() - a.year()) * 12 + (b.month() - a.month()); |
|
var anchor = a.clone().add(wholeMonthDiff, 'months'); |
|
var anchor2; |
|
var adjust; |
|
if (b - anchor < 0) { |
|
anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); |
|
adjust = (b - anchor) / (anchor - anchor2); |
|
} else { |
|
anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); |
|
adjust = (b - anchor) / (anchor2 - anchor); |
|
} |
|
return -(wholeMonthDiff + adjust) || 0; |
|
} |
|
|
|
module.exports = exports;
|
|
|