I need to subtract 2 times with moment.js (get the difference), and then with that result, subtract some additional minutes (simple int). It's for calculating timesheets. A few examples:
Example #1:
Start time: 10:00 AM (represented in js as "10:00")
End time: 2:00 PM (represented in js as "14:00")
Lunch: 30 minutes ("30")
Expected result: "3:30" (10am - 2pm is 4 hours, minus 30 minutes for lunch = 3hrs 30 mins -- and I need it output as "3:30")
Example #2:
Start time: 6:15 AM (represented in js as "6:15")
End time: 4:45 PM (represented in js as "16:45")
Lunch: 0 minutes ("0")
Expected result: "10:30"
I know moment.js can do this but I'm struggling to get expected results. I've been trying this:
function getTimeInterval(startTime, endTime){
return moment(moment(startTime,"hh:mm").diff(moment(endTime,"hh:mm"))).format("hh:mm");
}
The formatting seems right, but I'm getting incorrect values. For example, the result returned for my example #2 is "6:30" instead of "10:30" And then how do I subtract off int minutes for lunch?
Any help is much appreciated.
// parse time using 24-hour clock and use UTC to prevent DST issues
var start = moment.utc(startTime, "HH:mm");
var end = moment.utc(endTime, "HH:mm");
// account for crossing over to midnight the next day
if (end.isBefore(start)) end.add(1, 'day');
// calculate the duration
var d = moment.duration(end.diff(start));
// subtract the lunch break
d.subtract(30, 'minutes');
// format a string result
var s = moment.utc(+d).format('H:mm');
Pay close attention to the casing of the formats. You were using hh which is for a 12-hour clock.
See also: Get the time difference between two datetimes
You can use the diff method to calculate the difference between two dates and the subtract method to subtract time. In your case:
function getTimeInterval(startTime, endTime, lunchTime){
var start = moment(startTime, "HH:mm");
var end = moment(endTime, "HH:mm");
var minutes = end.diff(start, 'minutes');
var interval = moment().hour(0).minute(minutes);
interval.subtract(lunchTime, 'minutes');
return interval.format("HH:mm");
}
Related
I have my current time in seconds and duration time in seconds.
I want to add both seconds to calculate the end time of the song (for example).
But i have a weird format in the result.
Here is my code :
// This is my song's duration
var duration = new Date("Sept 21, 2019 00:03:32");
var durationSeconds = duration.getSeconds();
// Current second
var date = new Date();
var seconds = date.getSeconds();
var differenceSecondsConverted = date.setSeconds(seconds + durationSeconds);
console.log(differenceSecondsConverted);
And the result is something like : 1569102592740
Thanks
Actually the code works as it should, probably, you just miss some concept.
The new Date() is a constructor that returns an instance of Date object.
This object have several properties. When you instantiate it, it returns something like Sun Sep 22 2019 01:21:14 GMT+0200 (CEST) which is string representation of current time.
However, this string representation is not how JS actually "thinks" about the time.
Internally, "time" for JS is number of milliseconds passed from January 1, 1970, 00:00:00.
It looks something like this: 1569108461979.
You may see it if you run Date.now();
Also, if you do any calculations (not directly, but using methods like .setDate) with new Date(), it will be internally calculated as milliseconds passed from 1, 1970, 00:00:00.
So, the main problem in your code is that your duration variable is not actually "duration".
It just contains an object that represents Sept 21, 2019 00:03:32.
It is just a moment in time (3 minutes, 32 seconds after midnight of 20 of September 2019).
To calculate when the song will end if it starts right now, you'd do something like:
let now = Date.now();
// Song duration in milliseconds
let songDuration = 201000;
let songEndTime = now + songDuration;
console.log( new Date(songEndTime) );
You can get a date object for the time in say 3:32 by adding 3 minutes and 32 seconds to the current date, e.g.
// time is minutes and seconds as mm:ss
function nowPlus(time) {
let [m, s] = time.split(':').map(Number);
let now = new Date();
now.setMinutes(now.getMinutes() + m, now.getSeconds() + s);
return now;
}
console.log('In 3:32 it will be: ' + nowPlus('3:32').toLocaleString(undefined, {hour12:false, hour: 'numeric', minute:'2-digit', second:'2-digit'}));
I came across this codepen https://codepen.io/donovanh/pen/JWdyEm, and I was trying to apply it to an older countdown timer I did because this one seemed better.. If I set the countdown date to today then it still says there is 30 days left.
Here is the code where it calculates the difference between dates.
function daysBetween( date1, date2 ) {
//Get 1 day in milliseconds
var one_day=1000*60*60*24;
// Convert both dates to milliseconds
var date1_ms = date1.getTime();
var date2_ms = date2.getTime();
// Calculate the difference in milliseconds
var difference_ms = date2_ms - date1_ms;
// Convert back to days and return
return Math.round(difference_ms/one_day);
}
console.log("Days to end of April = " +
daysBetween(new Date(), new Date("2018-04-30")));
I cannot figure out where the extra days are coming from, any help would be appreciated, thanks
I think that your problem comes from giving wrong month number as argument to Date.UTC. According to docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC, month is a 0-11 number. If you would like to call function for todays date, you have to call it like new Date(2018, 3, 10, 12, 15).
Months start from 0 and go to 11.
The end of April is Date("2018-03-30"), not Date("2018-04-30") that is why you get extra 30 or 31 days
I have time1 = '09:00 AM' and time2 = '06:30 PM'.
How can i subtract these two using moment.js, such a way that i get the result = 9hrs 30mins.
I searched through the internet but couldn't find an apt solution.
Any suggestions are much appreciated.
I suggest programming your own custom function that converts the time to 24 hrs, adding 12 hours if PM, 0 if AM. It then converts the times in to minutes, subtracts the two times, and converts them back into HH:MM AM/PM.
(Pseudocode (reads a bit like javascript))
//ap = am or pm; 0 for am, 1 for pm
define "subtractTimes" (time1, time1ap, time2, time2ap):
//gets the length of time1 and time2
set "time1Length" to (length(time1))
set "time2Length" to (length(time2))
//adds 12 hours if pm, converted to minutes
set "time1InMinutes" to (time1ap * (12 * 60))
set "time2InMinutes" to (time2ap * (12 * 60))
//gets minutes from time1 and time2
//You'd have to program your own function "getLetters"
//Unless there's one that I'm unaware of.
set "time1MM" to (getLetters(time1,(time1Length-1),time1Length))
set "time2MM" to (getLetters(time2,(time2Length-1),time2Length))
//this script makes sure the times are the proper length.
if "time1Length" = (4)
set "time1" to (("0")join(time1)
if "time2Length" = (4)
set "time2" to (("0")join(time2)
//gets hours from time1 and time 2
set "time1HH" to (getLetters(time1,(time1Length-4),time1Length-3))
set "time2HH" to (getLetters(time2,(time2Length-4),time2Length-3))
//puts it all together
set "time1InMinutes" to (time1InMinutes+(time1HH*60)+time1MM)
set "time2InMinutes" to (time2InMinutes+(time2HH*60)+time2MM)
set "newTimeInMinutes" to ((time1InMinutes)-(time2InMinutes))
//converts it to HH:MM AM/PM
set "newTime" to (floor(newTimeInMinutes/60))
set newTimeInMinutes" to (newTimeInMinutes-(newTime*60))
if "newTime" > (12):
set "newTime" to (newTime-12)
set "ap" to (AM)
else
set "ap" to (PM)
set "newTime" to ((newTime)join(":")join(newTimeInMinutes))
set "newTime" to ((newTime)join(" ")join(ap)
//end
This should work. If you have any questions, feel free to ask.
Essentially I have two unix timestamps, representing the first and last days of a given month. Is it possible programmatically determine the timestamps for the first and last of the previous month?
For example, I have the following two timestamps:
1467331201 --> July 1, 2016
1469923201 --> July 31, 2016
Essentially, can I manipulate these two numbers in a consistent way in order to the unix time (or Date object) for June 1, 2016 and June 30, 2016, respectively? Problem that I'm running into is that you cannot simply subtract a given amount because the amount of days in a month is variable.
You could use this function:
function getPreviousMonthRange(unixTime) {
var dt = new Date(unixTime * 1000);
dt.setUTCDate(0); // flips to the last day of previous month
var unixLast = dt.getTime();
dt.setUTCDate(1); // back to the first day of that same month
var unixFirst = dt.getTime();
return [unixFirst / 1000, unixLast / 1000];
}
// given first and last date (only one is really needed)
var unixTimeFirst = 1467331201;
var unixTimeLast = 1469923201;
// get previous month's first & last date
var [first, last] = getPreviousMonthRange(unixTimeFirst);
// output
console.log('previous month first day: ', first, new Date(first*1000));
console.log('previous month last day: ', last, new Date(last*1000));
Take a look at the following example:
// Specify a timestamp
var timestamp = 1467331201;
// Create a date object for the time stamp, the object works with milliseconds so multiply by 1000
var date = new Date(timestamp * 1000);
// Set the date to the previous month, on the first day
date.setUTCMonth(date.getUTCMonth() - 1, 1);
// Explicitly set the time to 00:00:00
date.setUTCHours(0, 0, 0);
// Get the timestamp for the first day
var beginTimestamp = date.getTime() / 1000;
// Increase the month by one, and set the date to the last day of the previous month
date.setUTCMonth(date.getUTCMonth() + 1, 0);
// Explicitly set the time to 23:59:59
date.setUTCHours(23, 59, 59);
// Get the timestamp for the last day
var endTimestamp = date.getTime() / 1000;
// Print the results
console.log('Timestamps for previous month: ');
console.log('Begin timestamp: ' + beginTimestamp);
console.log('End timestamp: ' + endTimestamp);
A timestamp must be specified in the variable on the top, this might be one of the two timestamps you suggested in your question, anywhere in a month.
This code then calculates the begin and end timestamp for the previous month as you've requested, and prints the results to the console.
Please note, that in this example the begin timestamp uses 00:00:00 as time, and the end timestamp uses 23:59:59 as time (the last second of that day). This can be configured the way you'd prefer.
In this case, we're working with the ...UTC... Date functions, because a Unix timestamp is in UTC time, not in the timezone the user is in.
The statement date.setMonth(date.getMonth() + 1, 0); is used to select the last day in the month. The next month is selected first, but because the day is set to 0 (and not 1) one day is subtracted giving you the preferred result. This is described here.
You can consider using Moment.js. I'm sure this is not exactly how you'd end up handling it but see below for an example of some helpful methods.
var lastDayOfJuly = moment(1469923201);
var firstDayOfJuly = lastDayOfJuly.startOf('month');
var lastDayOfJune = firstDayOfJuly.subtract(1, 'day');
var firstDayOfJune = lastDayOfJune.startOf('month");
Moment.js
I need to calculate the number of nights between 2 dates, it works but it's very odd.
If I pick dates like 22,06,2015 and 22,07,2015 it shows me 31 nights, which is wrong since June has only 30 days.
if I pick dates like 01,07,2015 and 31,07,2015 it shows me 30 nights, which is correct.
if I pick dates like 01,07,2015 and 1,08,2015 it shows me 31 nights etc.
if I pick dates like 30,09,2015 and 30,10,2015 it shows me 31.041666666666668 nights which is odd and incorrect.
Hope you can help me with this one. Here's the code:
var date11 = $("#in").val();
var date22 = $("#out").val();
// First we split the values to arrays date1[0] is the year, [1] the month and [2] the day
date111 = date11.split('-');
date222 = date22.split('-');
// Now we convert the array to a Date object, which has several helpful methods
date1 = new Date(date111[2], date111[1], date111[0]);
date2 = new Date(date222[2], date222[1], date222[0]);
// We use the getTime() method and get the unixtime (in milliseconds, but we want seconds, therefore we divide it through 1000)
date1_unixtime = parseInt(date1.getTime() / 1000);
date2_unixtime = parseInt(date2.getTime() / 1000);
// This is the calculated difference in seconds
var timeDifference = date2_unixtime - date1_unixtime;
// in Hours
var timeDifferenceInHours = timeDifference / 60 / 60;
// and finaly, in days :)
var timeDifferenceInDays = timeDifferenceInHours / 24;
Thanks a million!
You aren't subtracting 1 from the calendar month number:
date1 = new Date(date111[2], date111[1] - 1, date111[0]);
--------^^^^
Months are zero indexed. you should probably also round the result as if you cross a daylight saving boundary, the time value won't be an even number of days, it will be out by 1 hour (unless you cross two boundaries…)