Javascript Moment Time add Time Calculation wrong - javascript

I am using Moment library in Javascript
I would like to add time, so I tried:
var time1 = moment("10:00:00", "HH:mm:ss");
var time2 = moment("00:03:15", "HH:mm:ss");
var add = time1.add(time2);
let format = moment.utc(add).format("HH:mm:ss")
console.log(format);
I will expected my format will be 10:03:15 but turns out it gave me 18:03:15
I wonder why it add another 8 hours for me, well considered as .utc problem, I try to perform without .utc as follows:
let format = moment(add).format("HH:mm:ss")
It return 02:03:15.
It kinda frustrated I dunno what is happening
*By the way
var add1 = time3.add(5588280, 'ms');
*it works fine by adding with h, m, s, ms to it

Ciao, with moment add you could add time in 3 ways:
moment().add(Number, String);
moment().add(Duration);
moment().add(Object);
This is the version moment().add(Number, String);
var time1 = moment("10:00:00", "HH:mm:ss");
var time2 = moment("00:03:15", "HH:mm:ss");
var add = moment(time1).add(time2.minutes(), "minutes").add(time2.seconds(), "seconds");
let format = add.format("HH:mm:ss");
console.log(format); // without utc
let formatUtc = moment.utc(add).format("HH:mm:ss");
console.log(formatUtc); // with utc
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
This is the version moment().add(Object);
var time1 = moment("10:00:00", "HH:mm:ss");
var time2 = moment("00:03:15", "HH:mm:ss");
var add = moment(time1).add({minutes: time2.minutes()}).add({seconds: time2.seconds()});
let format = add.format("HH:mm:ss");
console.log(format); // without utc
let formatUtc = moment.utc(add).format("HH:mm:ss");
console.log(formatUtc); // with utc
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
You already know the third version :)

add is the two-argument function with the need first argument as the number and second argument is number type in time laps.
i.e it is working with microseconds
time3.add(5588280, 'ms')
Here you can do for your problem
const time1 = moment("10:00:00", "HH:mm:ss");
const time2 = moment("00:03:15", "HH:mm:ss");
// get hours from time2 and add in time1
const add = time1.add(time2.format('mm'), 'hours')
// add minutes using chain
.add(time2.format('mm'), 'minutes')
// add seconds using add method from moment
.add(time2.format('ss'), 'seconds');
const format = moment(add).format("HH:mm:ss")
By using UTC on the moment it converts time into UTC and format make it as
time string format
moment(add).format("HH:mm:ss")
// Your required time:- 13:03:15
moment.utc(add).format("HH:mm:ss")
// required time in UTC:- 07:33:15

You can simply use moment duration function to add two times together we do not use to use extra lines code (like minutes, seconds, or hours) here to get the results you want.
Just add two times with duration and get them as milliseconds and then format them as you like to.
Live Demo:
let time1 = "10:00:00"; //string
let time2 = "00:03:15"; //string
let addTwoTimes = moment.duration(time1).add(moment.duration(time2)) //add two times
let format = moment.utc(addTwoTimes.as('milliseconds')).format("HH:mm:ss") //format
console.log(format); //10:03:15
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js" integrity="sha512-rmZcZsyhe0/MAjquhTgiUcb4d9knaFc7b5xAfju483gbEXTkeJRUMIPk6s3ySZMYUHEcjKbjLjyddGWMrNEvZg==" crossorigin="anonymous"></script>

Related

Time changes after toLocaleTimeString()

I'm using a google sheets script, which on the click of a button will add values to two fields.
The first will contain the date, the second the time.
For this, I use this piece of code:
var timestamp = new Date();
var date = Utilities.formatDate(timestamp, "GMT+1", "dd/MM/yyyy");
var time = timestamp.toLocaleTimeString('nl-BE');
Now, the issue is that the time is off by 6 hours.
The timestamp value does contain the correct time, the date variable gets the correct date, but the time seems to differ 6 hours after the 'toLocaleTimeString() function.
Use Utilities.formatDate() for time as well, like this:
const timezone = SpreadsheetApp.getActive().getSpreadsheetTimeZone(); // or 'GMT+1'
const timestamp = new Date();
const dateString = Utilities.formatDate(timestamp, timezone, 'dd/MM/yyyy');
const timeString = Utilities.formatDate(timestamp, timezone, 'HH:mm:ss');
console.log(`date and time in ${timezone}: ${dateString} ${timeString}`);

How to check if the time is in between given range using moment.js?

I am using moment.js library for time.
I want to check if the time I am getting from the backend is in between 8AM to Noon (12PM). I want to store all the objects whose time is in between 8AM to 12PM.
I am getting date in this format - "2022-04-04T21:43:59Z". I want to use timezone"America/Detroit".
Here is what I have tried but this didn't work;
//this code is inside forEach loop
moment.tz.setDefault($scope.userData.account.timeZone);
var format = 'hh:mm:ss'
var time = moment(response.date,format),
beforeTime = moment('08:00:00', format),
afterTime = moment('11:59:59', format);
if (time.isBetween(beforeTime, afterTime)) {
console.log('is between')
} else {
console.log('is not between')
}
In the output I am getting is not between for all the data but in real there is some data which is having date and time falling under 8am - 12pm.
Is there anything wrong because of timezone?
The reason why your compare isn't working it's because it's not only using time but also the date.
You should first extrapolate the time from the input datetime and use that data to make the comparison like this:
let datetime = moment('2022-04-04T10:00:00Z', 'YYYY-MM-DDTHH:mm:ssZ');
moment({
hour:datetime.hour(),
minute:datetime.minute(),
second:datetime.second()
}).isBetween(beforeTime, afterTime);
//returns bool true or false
That's because all those 3 datetimes will lay in the same solar day and only time will be relevant to the comparison.
Plus you incorrectly dealt with formats when parsing both your input datetimes and times used for before and after.
This is a working solution showing the concept:
//those are the formats your input uses for datetimes and times
const datetime_format = 'YYYY-MM-DDTHH:mm:ssZ';
const time_format = 'HH:mm:ss';
//this is your input crafted as objects having the prop date
var response_timeYESInBetween = {date : "2022-04-04T10:00:00Z"};
var response_timeNOTInBetween = {date : "2022-04-04T21:43:59Z"};
//moment.tz.setDefault($scope.userData.account.timeZone);
//this is where you parse those timestamp strings as moment datetime
var datetime_YESInBetween = moment(response_timeYESInBetween.date, datetime_format);
var datetime_NOTInBetween = moment(response_timeNOTInBetween.date, datetime_format);
//this is where those moment datetime get used to create new datetimes holding those same time but laying on today instead of their original dates
var timeonly_YESinBetween = moment({hour:datetime_YESInBetween.hour(), minute:datetime_YESInBetween.minute(), second:datetime_YESInBetween.second()});
var timeonly_NOTinBetween = moment({hour:datetime_NOTInBetween.hour(), minute:datetime_NOTInBetween.minute(), second:datetime_NOTInBetween.second()});
//this is where we create datetimes (ignoring to pass the date, sets them at today)
var beforeTime = moment('08:00:00', time_format);
var afterTime = moment('11:59:59', time_format);
//we make the comparison to know which times are between beforeTime and afterTime
//note: now all those datetimes are all in the same day and only time will affect the comparison result
var firstComparison = timeonly_YESinBetween.isBetween(beforeTime, afterTime);
var secondComparison = timeonly_NOTinBetween.isBetween(beforeTime, afterTime)
console.log( firstComparison );
//outputs: true
console.log( secondComparison );
//outputs: false
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script>
And if we wanted to better factor the parts:
console.log( isBetween('2022-04-04T10:00:00Z', '08:00:00', '11:59:59') );
//true
console.log( isBetween('2022-04-04T21:43:59Z', '08:00:00', '11:59:59') );
//false
function isBetween(datetime, before, after){
const datetime_format = 'YYYY-MM-DDTHH:mm:ssZ';
const time_format = 'HH:mm:ss';
let originalDatetime = moment(datetime, datetime_format);
let transformed = moment({hour:originalDatetime.hour(), minute:originalDatetime.minute(), second:originalDatetime.second()});
var beforeTime = moment(before, time_format);
var afterTime = moment(after, time_format);
return transformed.isBetween(beforeTime, afterTime);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script>

Comparing two times in MomentJS in the format HH:mm?

Here I need to compare two times and have to check whether the current time is sameOrBefore the given time.
var workingDayTime = '1900'
var currentTime = moment().format("HH:mm")
var endTime = moment(workingDayTime,"HHmm").format("HH:mm")
console.log(currentTime) // 08:21
console.log(endTime) // 19:00
Assume the value of workingDayTime is coming from API in the format of ``HHMM`. I have checked the moment docs. And used something like endTime.isSameOrAfter(currentTime).
But it is returning endTime.isSameOrAfter is not a function . I believe this is because the current time and endTime have formatted to string this is not a function anymore. Is there any way to achieve the functionality I am looking for. Please help me with your suggestion and feedback
Compare the moment objects without the string formatting:
const workingDayTime = '1900'
const currentMoment = moment()
const currentTime = currentMoment.format('HH:mm')
const endMoment = moment(workingDayTime,"HHmm")
const endTime = endMoment.format("HH:mm")
const msg = (endMoment.isSameOrAfter(currentMoment))
? 'after'
: 'before'
console.log(`${endTime} is ${msg} ${currentTime}`)
Don't format dates before you compare them
import moment from "moment";
var workingDayTime = '1900'
var currentTime = moment()
var endTime = moment(workingDayTime,"HHmm")
console.log(endTime.isSameOrAfter(currentTime)) // true

How do I limit my moment js duration values to only 2 digits?

I am using moment.js to work with date times which are calculated from distance/speed. I am also using the moment duration format plugin. When I pass the value to moment.duration and then format it some of the values are more than 2 digits, i.e.
39:3452:98762
I would like this to format correctly as HH:mm:ss. Here is my code.
var point1Time = 19.188019795;
var d1 = moment.duration(point1Time, 'hours');
var d1Hours = d1.format('HH');
var d1Mins = d1.format('mm', {forceLength: true });
var d1Secs = d1.format('ss', {forceLength: true });
As you can see the point1Time (which I've entered as a number for the sake of this example) is miles/speed, I then pass this value to moment as a duration in hours. After that I try to separate the HH:mm:ss using format. The value that is returned is something like d1Hours: 19, d1Mins: 1151, d1Secs: 69076.
I thought that adding forceLength would help keep the digits down to two only but it didn't work as I can't see where to define that limit.
Can anyone assist with this?
You can use 'HH:mm:ss' as template in format() method to get the desired output.
d1.format('mm') and d1.format('ss') give the output of asSeconds and asMinutes while I think that you need the output of minutes() and seconds().
Here a live sample:
var point1Time = 19.188019795;
var d1 = moment.duration(point1Time, 'hours');
console.log(d1.format('HH:mm:ss'));
console.log(d1.minutes(), d1.asMinutes());
console.log(d1.seconds(), d1.asSeconds());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>
You can convert the duration into seconds then it's easy to find the format that you want
var d1 = moment.duration(point1Time, 'hours');
var asSecs = d1.asSeconds()
var HHMMSS = secondsToHHMMSS(asSecs)
function pad(num) {
return ("0"+num).slice(-2);
}
function secondsToHHMMSS(secs) {
var hours = Math.floor(secs / 3600);
secs = secs%3600;
var minutes = Math.floor(secs / 60);
secs = secs%60;
return pad(hours)+":"+pad(minutes)+":"+pad(secs);
}

How to add one second to a time string with javascript/jquery

I am trying to create a timer with Javascript but I don't know how to add one second to a time string.
Time string: 03:31:15
function updateWorked() {
var time = $("#worked").html();
???
$("#worked").html(wtime);
}
$(document).ready(function() {
setInterval('updateWorked()', 1000);
});
What should I write in "???" to make this work?
Assuming you are using something like PHP to get the time string in the first place, and you can't keep track of the date/time as a number as suggested by Marc B, you can parse the string yourself like this:
var $worked = $("#worked");
var myTime = $worked.html();
var ss = myTime.split(":");
var dt = new Date();
dt.setHours(ss[0]);
dt.setMinutes(ss[1]);
dt.setSeconds(ss[2]);
var dt2 = new Date(dt.valueOf() + 1000);
var ts = dt2.toTimeString().split(" ")[0];
$worked.html(ts);
Edit: Working jsFiddle here of this code.
Here's the code with a timer: jsFiddle
Below is an example on how to add a second to a time string. You can use the date object to print out the string in any format that you would like, in this example i'm just using the build in toTimeString method.
var timeString = "10/09/2012 14:41:08";
// start time
var startTime = new Date(timeString);
// prints 14:41:08 GMT-0400 (EDT)
console.log(startTime.toTimeString())
// add a second to the start time
startTime.setSeconds(startTime.getSeconds() + 1);
// prints 14:41:09 GMT-0400 (EDT)
console.log(startTime.toTimeString())
If you're trying to keep a counter in real time, you should use new Date() to get the time, and then format it:
function updateWorked() {
var time = new Date(),
wtime = formatDate(time);
$("#worked").html(wtime);
}
However, if you're trying to keep a specific time, then you should up-scope a Date object and use that:
var time = new Date(/* your starting time */);
function updateWorked() {
time.setTime(time.getTime()+1000);
var wtime = formatDate(time);
$("#worked").html(wtime);
}
Also, you'd want to add a formatDate function:
function formatDate(date) {
var hours = date.getHours().toString();
if (hours.length < 2) hours = '0'+hours;
var minutes = date.getMinutes().toString();
if (minutes.length < 2) minutes = '0'+minutes;
var seconds = date.getSeconds().toString();
if (seconds.length < 2) seconds = '0'+seconds;
return hours+':'+minutes+':'+seconds;
}
Using mixture of jquery and javascript you can achieve this example.
I tired to achive what you looking for, first created a date object and get all the values of time, minute and second and then replaced the value.
Please have a look at jsfiddle
DEMO
http://jsfiddle.net/saorabhkr/xtrpK/

Categories

Resources