round up/ round down a momentjs moment to nearest minute - javascript

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.

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

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.

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

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

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){
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

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

I was searching for this same question and found a better solution:
Use the third parameter in diff() function:
moment("2019-05-02 17:10:20").diff("2019-05-02 17:09:30","minutes",true)
By setting third parameter to true, you get the raw value as response that you can round by yourself using Math.round()
See JSFiddle:
https://jsfiddle.net/2wqs4o0v/3/

This solution worked for me;
function round_up_to_nearest_hour(date = new Date()) {
return moment(date).add(59, 'minutes').startOf('hour').toDate();
}

Just another possibility:
const 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)

The simplest solution so far:
function floor(time, floorBy = 'minute') {
return time.startOf(floorBy);
}
function ceil(time, ceilBy = 'minute') {
return time.subtract(1, 'millisecond').add(1, ceilBy).startOf(ceilBy);
}
// The solution is above. The code below is an optional test:
console.log(
floor(moment('2019-01-01 12:00:00.000')).format('H:mm:ss.SSS') === '12:00:00.000',
ceil(moment('2019-01-01 12:00:00.000')).format('H:mm:ss.SSS') === '12:00:00.000',
floor(moment('2019-01-01 12:00:00.001')).format('H:mm:ss.SSS') === '12:00:00.000',
ceil(moment('2019-01-01 12:00:00.001')).format('H:mm:ss.SSS') === '12:01:00.000',
floor(moment('2019-01-01 12:15:16.876'), 'hour' ).format('H:mm:ss.SSS') === '12:00:00.000',
ceil(moment('2019-01-01 12:15:16.876'), 'hour' ).format('H:mm:ss.SSS') === '13:00:00.000',
floor(moment('2019-01-01 12:59:59.999'), 'second').format('H:mm:ss.SSS') === '12:59:59.000',
ceil(moment('2019-01-01 12:59:59.999'), 'second').format('H:mm:ss.SSS') === '13:00:00.000',
floor(moment('2019-01-01 12:00:00.025'), 'ms' ).format('H:mm:ss.SSS') === '12:00:00.025',
ceil(moment('2019-01-01 12:00:00.025'), 'ms' ).format('H:mm:ss.SSS') === '12:00:00.025'
);
<script src="//cdn.jsdelivr.net/npm/moment#2.24.0/min/moment.min.js"></script>

Related

Issues getting the number of weeks between two dates in javascript

This function of mine returns a massive amount of weeks that doesnt make sense
getWeeksToDate(){
var current_date = new Date();
console.log(current_date) //Sat Jan 11 2020 17:07:30 GMT+0100 (Central European Standard Time)
console.log(new Date(555555558555)); //Mon Aug 10 1987 02:59:18 GMT+0200 (Central European Summer Time) [I did set this randomly for the test]
var seconds_to_date = (new Date(current_date) -new Date(555555558555) )
var weeks_to_date = seconds_to_date/60/60/24/7;
console.log("semanas vividas:" +Math.ceil(weeks_to_date));
//Returns lived weeks to date rounded to upper number
return Math.ceil(weeks_to_date); //returns 1691805 weeks, which doesnt make sense since its around 32445 years, when it should equal to around 33 years
}
new Date(...) - new Date(...) returns the timestamp in milliseconds. Thus, you need to additionally divide by 1000 to convert the milliseconds into seconds.
var weeks_to_date = seconds_to_date/1000/60/60/24/7;

JavaScript - Assigning Array Index to Return Value not working

I am trying to assign a return value to an element in an array, and for some reason it is overwriting both elements in the array to the same value instead of just the second element.
The datepicker I'm using for this can be found here, for reference.
http://www.eyecon.ro/datepicker/
function AddDays(date, days)
{
var newDate = new Date(date.setTime( date.getTime() + days * 86400000 ));
return newDate;
}
$('#nights').on('change', function(){
var $dp = $('#date');
var t = $dp.DatePickerGetDate();
console.log(t); // Output 1
t[1] = AddDays(t[0], $(this).val());
console.log(t); // Output 2
});
Output 1 : [Mon Jan 02 2017 00:00:00 GMT-0600 (Central Standard Time), Sun Jan 08 2017 23:59:59 GMT-0600 (Central Standard Time)]
Output 2 : [Mon Jan 09 2017 00:00:00 GMT-0600 (Central Standard Time), Mon Jan 09 2017 00:00:00 GMT-0600 (Central Standard Time)]
As you can see, when I try to assign the second element t[1] to equal the return of AddDays(t[0], $(this).val()) both dates get set the same exact date. However, the second element is supposed to be equal to the first element plus the number of days specified.
I also verified that the element $(this).val() is not zero. In my case that is in fact returning 7 when I run console.log($(this).val()); right before the assignment of t[1].
What am I doing wrong here?
Your function modifies the date that is passed in when you call setTime. You can remove the call to setTime to solve your problem.
function addDays(date, days) {
return new Date(date.getTime() + (days * 86400000));
}
Or make a brand new date object and call setDate or setTime on the copy.
function addDays(date, days) {
var result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}

How to set date always to eastern time regardless of user's time zone

I have a date given to me by a server in unix time: 1458619200000
NOTE: the other questions you have marked as "duplicate" don't show how to get there from UNIX TIME. I am looking for a specific example in javascript.
However, I find that depending on my timezone I'll have two different results:
d = new Date(1458619200000)
Mon Mar 21 2016 21:00:00 GMT-0700 (Pacific Daylight Time)
// Now I set my computer to Eastern Time and I get a different result.
d = new Date(1458619200000)
Tue Mar 22 2016 00:00:00 GMT-0400 (Eastern Daylight Time)
So how can I show the date: 1458619200000 ... to always be in eastern time (Mar 22) regardless of my computer's time zone?
You can easily take care of the timezone offset by using the getTimezoneOffset() function in Javascript. For example,
var dt = new Date(1458619200000);
console.log(dt); // Gives Tue Mar 22 2016 09:30:00 GMT+0530 (IST)
dt.setTime(dt.getTime()+dt.getTimezoneOffset()*60*1000);
console.log(dt); // Gives Tue Mar 22 2016 04:00:00 GMT+0530 (IST)
var offset = -300; //Timezone offset for EST in minutes.
var estDate = new Date(dt.getTime() + offset*60*1000);
console.log(estDate); //Gives Mon Mar 21 2016 23:00:00 GMT+0530 (IST)
Though, the locale string represented at the back will not change. The source of this answer is in this post. Hope this helps!
Moment.js (http://momentjs.com/timezone) is your friend.
You want to do something like this:
var d = new Date(1458619200000);
var myTimezone = "America/Toronto";
var myDatetimeFormat= "YYYY-MM-DD hh:mm:ss a z";
var myDatetimeString = moment(d).tz(myTimezone).format(myDatetimeFormat);
console.log(myDatetimeString); // gives me "2016-03-22 12:00:00 am EDT"
For daylight saving, Eastern time become 4 hours behind UTC. That's why its offset is -4x60 = -240 minutes. So when daylight is not active the offset will be -300. The offset variable's value is the key point to be noted here. Kindly see this code in action in attached image.
var offset = new Date().getTimezoneOffset();// getting offset to make time in gmt+0 zone (UTC) (for gmt+5 offset comes as -300 minutes)
var date = new Date();
date.setMinutes ( date.getMinutes() + offset);// date now in UTC time
var easternTimeOffset = -240; //for dayLight saving, Eastern time become 4 hours behind UTC thats why its offset is -4x60 = -240 minutes. So when Day light is not active the offset will be -300
date.setMinutes ( date.getMinutes() + easternTimeOffset);

Compare dates issue - javascript

I need to compare dates in javascript.
After attempt many ways...
I choose:
var endDate = new Date(secondDate.getYear(), secondDate.getMonth(), secondDate.getDate(), 0, 0, 0,0);
var startDate = new Date(firstDate.getYear(), firstDate.getMonth(), firstDate.getDate(), 0, 0, 0, 0);
if (endDate.getTime() >= startDate.getTime()) {
isValid = true;
}
else {
isValid = false;
}
In my situation:
---startDate = Tue Apr 01 1997 00:00:00 GMT+0200 (Jerusalem Standard Time) (i.e, 01/04/1997)
---endDate = Thu Jul 26 114 00:00:00 GMT+0200 (Jerusalem Standard Time) (i.e, 26/07/2014)
You see? startDate is small then endDate, right?
But:
---endDate.getTime() returns: -58551904800000
---startTime.getTime() returns: 859845600000
so, endDate.getTime() >= startDate.getTime() returns false...
In other situation, it works well:
---startDate: Sat Jul 21 114 00:00:00 GMT+0200 (Jerusalem Standard Time) (i.e, 21/07/2014)
---endDate: Sat Jul 28 114 00:00:00 GMT+0200 (Jerusalem Standard Time) (i.e, 28/07/2014)
---startDate.getTime() returns -58552336800000
---endDate.getTime() returns -58551732000000
so, endDate.getTime() >= startDate.getTime() returns true...
It seems like that javascript functions have another behavior for dates after year 2000.
What should I do? which code will be match to all of the optional situations?
Thanks.
Yeah like ghusse said, there is a problem with your end time if you fixed it so it was 2014 you would get a result such as 1406329200000 instead of -58551904800000
I found a solution, after I read Josh and ghusse answers and advice:
Use getFullYear(), instead getYear(), and all will work O.K.
Apparently, you have a problem with your end dates :
Thu Jul 26 114 00:00:00 GMT+0200
Does not mean 21/07/2014 but 21/07/114
According to the doc, here are 2 correct ways of creating your date:
var endDate = new Date(21, 6, 2014);
// Or a string corresponding to a version of ISO8601
var endDate = new Date('2014-07-21T00:00:00z+3');

Converting a .NET DateTime to a Javascript Date

I have a WCF service that serves some dates to my javascript. I want to manipulate the date, but it arrives in the javascript looking like this:
/Date(1361145600000+0000)/
I know this is the miliseconds since 1970/01/01, but I havent been able to figure out how to convert it to a javascript Date.
Do I need to use a regex or trim the text to extract the miliseconds, and then use it like this:
new Date(miliseconds)
Surely there must be an easier way?
If the '+0000' is a standard timezone offset, the first 2 digits are hours, the last two, minutes.
Presumably it is not always '0000'-
You need to add(or subtract) the milliseconds difference from UTC to the first integral part to return the correct Date.
function timeconvert(ds){
var D, dtime, T, tz, off,
dobj= ds.match(/(\d+)|([+-])|(\d{4})/g);
T= parseInt(dobj[0]);
tz= dobj[1];
off= dobj[2];
if(off){
off= (parseInt(off.substring(0, 2), 10)*3600000)+
(parseInt(off.substring(2), 10)*60000);
if(tz== '-') off*= -1;
}
else off= 0;
return new Date(T+= off).toUTCString();
}
timeconvert('Date(1361145600000)+0000');
//returned value: (String UTC)
Mon, 18 Feb 2013 00:00:00 GMT
If the Dates ARE always in UTC ('+0000') you can just pull the significant digits from the string-
function timeconvert(ds){
var d=ds.match(/(\d+)/)[1];
return new Date(+d).toUTCString();
}
timeconvert('Date(1361145600000)+0000)');
// returned value: (String UTC)
Mon, 18 Feb 2013 00:00:00 GMT
Code proposed by kennebec has a bug with a dates, that lower than 1 January 1970.
For example, Date(-124054000000+0300) is Wed Jan 26 1966 07:33:20
Fixed code :
http://output.jsbin.com/cejolu/3/edit?js,console
function timeconvert(ds){
var D, dtime, T, tz, off,
dobj = ds.match(/(-?\d+)|([+-])|(\d{4})/g);
T = parseInt(dobj[0], 10);
tz = dobj[1];
off = dobj[2];
if (off) {
off = (parseInt(off.substring(0, 2), 10) * 3600000) + (parseInt(off.substring(2), 10) * 60000);
if(tz == '-') off *= -1;
}
else off= 0;
return new Date(T += off).toUTCString();
}
Test for the newest changes :
console.log(timeconvert("Date(-124054000000+0300)"));
console.log(timeconvert('Date(1361145600000)+0000'));
console.log(timeconvert("Date(0+0300)"));
console.log(timeconvert("Date(-2+0200)"));
console.log(timeconvert("Date(-860000000000+1100)"));
/* Output */
"Wed, 26 Jan 1966 07:33:20 GMT"
"Mon, 18 Feb 2013 00:00:00 GMT"
"Thu, 01 Jan 1970 03:00:00 GMT"
"Thu, 01 Jan 1970 01:59:59 GMT"
"Thu, 01 Oct 1942 18:06:40 GMT"
You can create javascript dates using code such as:
var d = new Date("1/1/2012")
So it should be a matter of simply providing your .Net date as a format of:
new DateTime().ToString("M/d/yyyy")
I found another way of doing it, slightly adapted from kennebec's answer:
function timeConvert(date){
var miliseconds = date.replace(/(^.*\()|([+-].*$)/g, '');
miliseconds = parseInt(miliseconds);
return new Date(miliseconds);
}
var x = timeConvert("/Date(1361145600000+0000)/");
console.log(x);

Categories

Resources