可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
How do you round up/ round down a momentjs moment to nearest minute?
I have checked the docs, but there doesn't appear to be a method for this.
Note that I do not want a string rounded to the nearest minute, I want a moment
returned (or modified in place, either is fine). I prefer not to have to convert to a string, and the convert back too.
Thanks.
As requested, here is some code:
var now = new moment(new Date());
if (now.seconds() > 0) {
now.add('minutes', -1);
}
now.seconds(0);
as you can see, I have managed to manually round down the moment here, but it seems rather hacky. Just after a more elegant way of accomplishing this.
回答1:
To round up, you need to add a minute and then round it down. To round down, just use the startOf
method.
Note the use of a ternary operator to check if the time should be rounded (for instance, 13:00:00 on the dot doesn't need to be rounded).
Round up/down to the nearest minute
var m = moment('2017-02-17 12:01:01');
var roundDown = m.startOf('minute');
console.log(roundDown.toString()); // outputs Tue Feb 17 2017 12:01:00 GMT+0000
var m = moment('2017-02-17 12:01:01');
var roundUp = m.second() || m.millisecond() ? m.add(1, 'minute').startOf('minute') : m.startOf('minute');
console.log(roundUp.toString()); // outputs Tue Feb 17 2017 12:02:00 GMT+0000
Round up/down to the nearest hour
var m = moment('2017-02-17 12:59:59');
var roundDown = m.startOf('hour');
console.log(roundDown.toString()); // outputs Tue Feb 17 2017 12:00:00 GMT+0000
var m = moment('2017-02-17 12:59:59');
var roundUp = m.minute() || m.second() || m.millisecond() ? m.add(1, 'hour').startOf('hour') : m.startOf('hour');
console.log(roundUp.toString()); // outputs Tue Feb 17 2017 13:00:00 GMT+0000
回答2:
Partial answer:
To round down to nearest moment minute:
var m = moment();
m.startOf('minute');
However, the equivalent for rounding up, endOf
, doesn't quite give the expected result.
回答3:
The roundTo feature could make it into a future release.
Examples:
moment().roundTo('minute', 15); // output: 12:45
moment().roundTo('minute', 15, 'down'); // output: 12:30
回答4:
Rounding to the nearest hour can be achieved by adding half an hour and then run .startOf('hour'). This is the same for any time measurement.
var now = moment();
// -> Wed Sep 30 2015 11:01:00
now.add(30, 'minutes').startOf('hour'); // -> Wed Sep 30 2015 11:31:00
// -> Wed Sep 30 2015 11:00:00
var now = moment();
// -> Wed Sep 30 2015 11:31:00
now.add(30, 'minutes').startOf('hour'); // -> Wed Sep 30 2015 12:01:00
// -> Wed Sep 30 2015 12:00:00
回答5:
Rounding Down
Easy. As stated by many others, just use Moment.startOf:
var roundDown = moment('2015-02-17 12:59:59').startOf('hour');
roundDown.format('HH:mm:SS'); // 12:00:00
Importantly, this also works as expected:
var roundDown = moment('2015-02-17 12:00:00').startOf('hour');
roundDown.format('HH:mm:SS'); // 12:00:00
Rounding Up
Slightly trickier, if we want to round up with a proper ceiling function: for example, when rounding up by hour, we want 12:00:00
to round up to 12:00:00
.
This does not work
var roundUp = moment('2015-02-17 12:00:00').add(1, 'hour').startOf('hour');
roundUp.format('HH:mm:SS'); // ERROR: 13:00:00
Solution
function roundUp(momentObj, roundBy){
if (momentObj.millisecond() != 1){
momentObj.subtract(1,'millisecond');
}
return momentObj.add(1, roundBy).startOf(roundBy);
}
var caseA = moment('2015-02-17 12:00:00');
roundUp(caseA, 'minute').format('HH:mm:SS'); // 12:00:00
var caseB = moment('2015-02-17 12:00:00.001');
roundUp(caseB, 'minute').format('HH:mm:SS'); // 12:01:00
var caseC = moment('2015-02-17 12:00:59');
roundUp(caseC, 'minute').format('HH:mm:SS'); // 12:01:00
回答6:
A more precise answer:
t.add(30, 'seconds').startOf('minute')
Case1: Rounding down if seconds < 30
t = moment(); //12:00:05
t.add(30, 'seconds').startOf('minute') //12:00:00
Case2: Rounding up if seconds >= 30
t = moment(); //12:00:33
t.add(30, 'seconds').startOf('minute') //12:01:00
回答7:
This solution worked for me;
function round_up_to_nearest_hour(date = new Date()) {
return moment(date).add(59, 'minutes').startOf('hour').toDate();
}
回答8:
Just another possibility:
var now = moment();
// -> Wed Sep 30 2015 11:57:20 GMT+0200 (CEST)
now.add(1, 'm').startOf('minute');
// -> Wed Sep 30 2015 11:58:00 GMT+0200 (CEST)
回答9:
Copy this file into your project:
// copied from here https://github.com/WebDevTmas/moment-round/blob/1d20ce5d338529c76da8439fe594cc6984505810/src/moment-round.js and modified
import moment from 'moment';
moment.fn.round = function(precision, key, direction='round') {
let keys = ['Hours', 'Minutes', 'Seconds', 'Milliseconds'];
let maxValues = [24, 60, 60, 1000];
// Capitalize first letter
key = key.charAt(0).toUpperCase() + key.slice(1).toLowerCase();
// make sure key is plural
if(key.indexOf('s', key.length - 1) === -1) {
key += 's';
}
let value = 0;
let rounded = false;
let subRatio = 1;
let maxValue;
for(let i=0; i<keys.length; ++i) {
let k = keys[i];
if(k === key) {
value = this._d['get' + key]();
maxValue = maxValues[i];
rounded = true;
} else if(rounded) {
subRatio *= maxValues[i];
value += this._d['get' + k]() / subRatio;
this._d['set' + k](0);
}
}
value = Math[direction](value / precision) * precision;
value = Math.min(value, maxValue);
this._d['set' + key](value);
return this;
};
moment.fn.ceil = function(precision, key) {
return this.round(precision, key, 'ceil');
};
moment.fn.floor = function(precision, key) {
return this.round(precision, key, 'floor');
};
And import it:
import Moment from 'moment';
import '../../moment-round';
Assuming you're using CommonJS/Babel/Webpack.