How can I calulate the time since 9:30 AM in JavaScript? - javascript

Okay, so I am trying to calculate the time since 9:30 in the morning in Google Apps Script, and I want the output to look like this: XX hrs XX mins. the problem is when I try calculating the minutes since 9:30, of course, it gives me all the minutes, not just the leftover minutes after I've calculated the hours. I need the minutes to be a decimal so I can times it by 60 and display the output in a cell. This is the code I'm currently using:
function CALCTIME() {
const minutes = 1000 * 60;
const hours = minutes * 60;
const days = hours * 24;
const years = days * 365;
var now = new Date(),
then = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate(),
9,30,0),
diff = now.getTime() - then.getTime();
let hrs = diff / hours;
let mins = Math.floor((diff / minutes) % 60);
return Math.floor(hrs) + " hrs " + mins + " mins";
}
The issue is not the hrs, I have that all good. The minutes are the problem because I can't figure out how to replace just an index from a string. I've looked and tried the methods shown on these web pages and Stack Exchange links for answers and I couldn't find any:
https://www.w3schools.com/jsref/jsref_replace.asp
How do I replace a character at a particular index in JavaScript?
Questions: What do you expect these statements to do and why? mins.replaceAt(0, "0."); mins % 60; The first statement I expected to replace the first character in mins with "0." but then, #jabaa pointed out that I couldn't replace a number for a string, which I totally forgot and didn't take into account. The second statement I just forgot to put mins = mins % 60; which probably wouldn't have solved my problem anyway, I just forgot to put that there.
I've answered your questions, but someone has already answered my questions.

The reason it is not working is because you have:
diff = now.getTime() - then.getTime();
That line is going to get the time difference from now and 9:30am.
var hrs = diff / hours;
var mins = diff / minutes;
The two lines above are getting their own things. The first is how many hours and the second is how many minutes. So inherently you will be getting all the minutes and not the leftovers. There are multiple ways to fix it. Below is one way where the hours are right, so we take out every full hour from the minute's section.
Could look something like this:
let hrs = diff / hours;
let mins = (diff / minutes) % 60;
ALSO: The following line of code you have does nothing because you're not giving it anywhere to be stored in.
mins % 60
To fix you can do something like:
let testvar = mins % 60;

Related

How can I understand what this javascript timer means in detail?

I created a countdown / timer a few weeks ago using Javascript. The code is also executed correctly by the browser.
Today I looked at the code again and I make notes (Javascript comments) to understand the code and what exactly it does and to better understand Javascrpit.
I'm stuck at the moment. Here's a small piece of code that I absolutely don't understand.
What does the modulo operator do with time? Seconds, minutes, hours...
What exactly does y do?
and why are tenary operators used?
I would be very grateful if someone could explain to me in their own words what exactly the code does. thanks
function timer() {
let seconds = count % 60;
let minutes = Math.floor(count / 60);
let hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
y = ((minutes>0) ? ((minutes>9) ? minutes : '0'+minutes) + ":" : "")
y += (seconds>9 || minutes == 0) ? seconds : '0'+seconds;
Same Code with my Comments :)
function timer() {
// SET VARIABLE FOR SECONDS = DONT KKNOW WHAT count % 60 means ???
let seconds = count % 60;
// SET VARIABLE FOR MINUTES = DONT KKNOW WHAT Math.floor(count / 60) means ???
let minutes = Math.floor(count / 60);
// SET VARIABLE FOR MINUTES = DONT KKNOW WHAT Math.floor(minutes / 60) ???
let hours = Math.floor(minutes / 60);
// WHY USING %= OPERATER ???
minutes %= 60;
hours %= 60;
// DONT UNDERSTAND Y ??? WHY USING TENARY OPERATORS ???
y = ((minutes>0) ? ((minutes>9) ? minutes : '0'+minutes) + ":" : "")
y += (seconds>9 || minutes == 0) ? seconds : '0'+seconds;
EDIT: count = 3600 SECONDS
You don't explain what count is, but it would appear to be a duration in seconds.
The modulo operator and the floor(a/b) operations are being used to convert the duration in seconds into a base-60 (i. e. Sumerian) representation, i. e., in hours, minutes, and seconds.
y is being built up to show the hours, minutes, and seconds as two decimal digits each, separated with colons, as is conventional to represent a time duration in hours, minutes, and seconds. So, for example, the final value might be "6:01:02" for six hours, one minute, and two seconds. For each base-sixty "digit", we want two decimal digits. The normal conversion of numbers to decimal notation does not include any leading zeros. If the answer were to have only one decimal digit, we have to append one leading zero to the beginning. So, for example, for 8, we would like to see "08".

Convert milliseconds to hours or minute or hour or day in javascript

I am trying to convert milliseconds to ...(sec/min/hours/day) ago,
I have tried like the below code but I am not getting the expected result, the output is showing that 19143.4 Days. It should be 2 or 3 days.
function msToTime(ms) {
let seconds = (ms / 1000).toFixed(1);
let minutes = (ms / (1000 * 60)).toFixed(1);
let hours = (ms / (1000 * 60 * 60)).toFixed(1);
let days = (ms / (1000 * 60 * 60 * 24)).toFixed(1);
if (seconds < 60) return seconds + " Sec";
else if (minutes < 60) return minutes + " Min";
else if (hours < 24) return hours + " Hrs";
else return days + " Days"
}
console.log(msToTime(1653991056493))
In fact here your code seems to work fine.
Reading the Date documentation :
JavaScript Date objects represent a single moment in time in a platform-independent format. Date objects contain a Number that represents milliseconds since 1 January 1970 UTC.
So when you're doing new Date(1653991056493) it's 1653991056493ms after Jan 1st 1970 which is 19143.4 days.
If you want the ms between a date and the current date, you can just substract the current date with the timestamp
new Date() - 1653991056493
function msToTime(ms) {
let seconds = (ms / 1000).toFixed(1);
let minutes = (ms / (1000 * 60)).toFixed(1);
let hours = (ms / (1000 * 60 * 60)).toFixed(1);
let days = (ms / (1000 * 60 * 60 * 24)).toFixed(1);
if (seconds < 60) return seconds + " Sec";
else if (minutes < 60) return minutes + " Min";
else if (hours < 24) return hours + " Hrs";
else return days + " Days"
}
console.log(msToTime(new Date() - 1653991056493))
I interpretted the question slightly differently to the accepted answer and am posting this as it might help people seeking to do what I though was being asked:
namely to reduce an elapsed period of milliseconds to either (rounded) days OR (rounded) hours OR (rounded) minutes OR (rounded) seconds - dependent on which fits the scale of the elapsed duration (as one might want to do where, for example, a page is to report "comment made 2 days ago" or "comment made 10 seconds ago" etc. - just like SO does when reporting when answers or comments were made.
As with the accepted answer, the elapsed time has to first be calculated by subtracting the passed ms value from a new date value (and, since units smaller than seconds will never be needed, the elapsed value converted to seconds by dividing by 1000):
const now = new Date();
const secondsPast = Math.round((now-pastMs)/1000);
This value is then filtered down a series of if checks, each containing a conditional return statement if the relevant time unit has been reached. Thus, if the 'scale' is seconds (i.e the elapsed duration is less than a minute), the function returns the seconds value and exits immeadiately:
if (secondsPast<60) {return `${secondsPast} seconds`} // terminates here if true;
If the seconds value is greater than 60, minutes are checked and a return made if they are less than sixty. The process repeats until larger values are eventually returned as days if no other unit was appropriate. Note the use of Math.floor to only return whole numbers for the relevant unit.
(this is, I think, what the original question was trying to achieve).
function elapsedTime(pastMs) {
const now = new Date();
const secondsPast = Math.round((now-pastMs)/1000);
if (secondsPast<60) {return `${secondsPast} seconds`} // terminates here if true;
const minutesPast = Math.floor(secondsPast/60);
if (minutesPast<60) {return `${minutesPast} minutes`} // terminates here if true;
const hoursPast = Math.floor(minutesPast/60);
if (hoursPast<24) {return `${hoursPast} hours`} // terminates here if true;
return `${Math.floor(hoursPast/24)} days`;
} // end function elapsedTime;
console.log(elapsedTime(1653991056493))

How to display to the nearest hour in moment?

On my project requires this kind of text response on a day and hours.
"2hrs"-- data as milliseconds, If i get 1h 30mins, It should be rounded-up to 2hrs.
i tried so many times but cannot catch the value. now am getting 1 hrs for below function.
can anyone help me to do this ? here is the function which i am using
const milliSec = 85600000;
const hrs = moment(moment.duration(milliSec)._data).format('HH[hrs]');
There are a couple of ways to solve your problem
Simple logic
let milliseconds = 85600000;
let hours = Math.floor(milliseconds/(1000*3600))
let minutes = Math.floor(milliseconds/(1000*60)) - hours * 60
if(minutes > 29){
console.log(hours + 1);
}
console.log(hours)
Using Moment.js
let milliseconds = 85600000
let hours = Math.floor(moment.duration(milliseconds).asHours())
let mins = Math.floor(moment.duration(milliseconds).asMinutes()) - hours * 60;
if(minutes > 29){
console.log(hours + 1);
}
console.log(hours)
Hope this helps you. Feel free for doubts.

How to add numbers in a 'clock-like' way?

I am currently working with hours as numbers, such as 2230 being equivalent to 22:30. I would like to be able to add numbers to it and sum as if they were minutes added to hours
2030 + 60 = 2130 //and not 2090
2330 + 120 = 0230 //and not 2350
Is there a library or function to doing this? Or perhaps I should change the way I am handling hours?
I don't recommend doing this, but if you want to do it, you have to handle the fact that you're pretending an hour is 100 minutes. You do that by extracting the real hours and minutes from the fake value, doing the math on them, and then reassembling them, something along these lines:
function toHoursAndMinutes(value) {
// Get hours: `value` divided by 100
const hours = Math.floor(value / 100);
// Get minutes: the remainder of dividing by 100
const minutes = value % 100;
// Return them
return [hours, minutes];
}
function fromHoursAndMinutes(hours, minutes) {
// Reassemble the number where hours are worth 100
return hours * 100 + minutes;
}
function add(a, b) {
// Get `a`'s hours and minutes
const [ahours, aminutes] = toHoursAndMinutes(a);
// Get `b`'s
const [bhours, bminutes] = toHoursAndMinutes(b);
// Add the hours together, plus any from adding the minutes
const hours = ahours + bhours + Math.floor((aminutes + bminutes) / 60);
// Add the minutes together, ignoring extra hours
const minutes = (aminutes + bminutes) % 60;
// Reassemble
return fromHoursAndMinutes(hours, minutes);
}
Live Example:
function toHoursAndMinutes(value) {
// Get hours: `value` divided by 100
const hours = Math.floor(value / 100);
// Get minutes: the remainder of dividing by 100
const minutes = value % 100;
// Return them
return [hours, minutes];
}
function fromHoursAndMinutes(hours, minutes) {
// Reassemble the number where hours are worth 100
return hours * 100 + minutes;
}
function add(a, b) {
// Get `a`'s hours and minutes
const [ahours, aminutes] = toHoursAndMinutes(a);
// Get `b`'s
const [bhours, bminutes] = toHoursAndMinutes(b);
// Add the hours together, plus any from adding the minutes
// The % 24 wraps around
const hours = (ahours + bhours + Math.floor((aminutes + bminutes) / 60)) % 24;
// Add the minutes together, ignoring extra hours
const minutes = (aminutes + bminutes) % 60;
// Reassemble
return fromHoursAndMinutes(hours, minutes);
}
console.log(add(2030, 60));
console.log(add(2330, 120));
But again, I don't recommend this. Instead, work with time values (Date or just milliseconds-since-the-Epoch, etc.) and convert for display when you need to display it.
Note that 50 rather than 0250, for two reasons: 1. 2330 + 120 is 2450 which is 00:50, not 02:50, and numbers don't have leading spaces except in string representations.
Here's my implementation of it
function add(current, time) {
const hours = Math.floor(time / 60);
const minutes = time % 60;
const currentMinutes = parseInt(current.toString().slice(2));
const currentHours = parseInt(current.toString().slice(0, 2));
const newMinutes = (currentMinutes + minutes) % 60;
const additionalHours = (currentMinutes + minutes) > 60 ? 1 : 0;
const newHours = (currentHours + hours + additionalHours) % 24;
return `${newHours < 10 ? '0' : ''}${newHours}${newMinutes < 10 ? '0' : ''}${newMinutes}`;
}
console.log(add(2030, 60)); // 2130
console.log(add(2330, 120)); // 0130
here is the working code for your clock.
var nowTime = '2350'; //current time in String..
var newMin = 120; // min you want to add in int..
var tMinutes = parseInt(nowTime.toString().slice(2)); //taking out the min
var tHours = parseInt(nowTime.toString().slice(0, 2)); //taking out the hr
var newMinutes = (newMin + tMinutes) % 60;
var newHr = tHours + parseInt(((newMin + tMinutes) / 60));
var newTime = `${newHr >= 24 ? newHr-24 : newHr}${newMinutes}`;
newTime = newTime.length < 4 ? '0'+newTime : newTime;
console.log(newTime);
If you want to handle date math, a library is probably best, because date math is hard, and the source of so many bugs if done wrong. Now, knowing how to do date math is a great thing to learn though, and reading through the source code of date math libraries is a good way to do that. Luxon is a good library with duration objects that can do what you need easily, and has readable source code. Other duration libraries also exist, so take a look at a few of those and see what you like the best. You can also abuse he built-in Date library to act like a duration object, but I don't think that's worth it.
But libraries aside, let's analyze the problem and what you might want to consider in solving it.
First off, I would say your first problem is trying to use a data type that isn't designed for what you want. A single integer is not a good idea for representing two values with different units. That is sort of what T.J. meant when he said it's a presentation concept. You have one object, but it's not really an integer in behavior. And date is close, but not quite right. So let's make a class. Duration seems like a good name:
class Duration { … }
We know it has two parts, hours and minutes. Also, it seems a good idea to just use one unit and convert them. (You wouldn't have to, but it actually makes the math easier if you do the conversion):
class Duration {
constructor ({hours = 0, minutes = 0}) {
this.totalMinutes = hours * 60 + minutes
}
}
Now lets make some getters to get just the minutes section and the hours section:
class Duration {
…
// just minutes that don't fit in hours
get minutes () { return this.totalMinutes % 60 }
get hours () { return Math.floor(this.totalMinutes / 60) }
// and also let's present it as the string you wanted:
asDisplayString() { return `${this.hours*100 + this.minutes}` }
}
Now we need to add them together. Some languages would let you use + for this, but javascript has limits on what we can make + do, so we'll add our own method. Note that because of how our constructor works, we can have more than 60 minutes when we initialize the values. Is this a good idea? Maybe. Depends on how you want the object to behave. (While we'll go with it for this example, there are definite arguments against it, mostly because it is a bit confusing that get minutes doesn't return over 60 - but it's also makes a certain sense at the same time).
class Duration {
…
add (otherDuration) {
return new Duration({minutes: this.totalMinutes + otherDuration.totalMinutes})
}
}
And now we can add our duration objects together, and the math is taken care of for us.
class Duration {
constructor ({hours = 0, minutes = 0}) {
this.totalMinutes = hours * 60 + minutes
}
// just minutes that don't fit in hours
get minutes () { return this.totalMinutes % 60 }
get hours () { return Math.floor(this.totalMinutes / 60) }
// and also let's present it as the string you wanted:
asDisplayString() { return `${this.hours*100 + this.minutes}` }
add (otherDuration) {
return new Duration({minutes: this.totalMinutes + otherDuration.totalMinutes})
}
}
d1 = new Duration({hours:20, minutes: 30})
d2 = new Duration({minutes: 50})
console.log(d1.asDisplayString(), '+', d2.asDisplayString(), '=', d1.add(d2).asDisplayString())

Calculate difference between 2 dates in ISO format in JavaScript/TS

I have 2 dates in ISO format like so:
startDate: "2018-09-14T00:20:12.200Z"
endDate: "2018-09-16T00:18:00.000Z"
What I'm trying to do is calculate the difference between those 2 days. So with the given dates it would be 1 Day, 21 Hours, 47 Minutes and 40 Seconds (pardon me if the subtraction is not correct).
Tried to do using the following:
const start = new Date(startDate).getTime();
const end = new Date(endDate).getTime();
return Math.abs(end - start).toString();
However this doesn't seem to work.
Any clues?
The following works. Things to note:
getTime() is not needed as the new Date() constructor returns the time in milliseconds.
The date should always be in RFC2822 or ISO formats, else it becomes useless across various browsers, even while using moment.js.
If you can use moment.js, Get time difference using moment.
Refer this to know why only the standardized formats need to be used.
var unitmapping = {"days":24*60*60*1000,
"hours":60*60*1000,
"minutes":60*1000,
"seconds":1000};
function floor(value)
{
return Math.floor(value)
}
function getHumanizedDiff(diff)
{
return floor(diff/unitmapping.days)+" days "+
floor((diff%unitmapping.days)/unitmapping.hours)+" hours "+
floor((diff%unitmapping.hours)/unitmapping.minutes)+" minutes "+
floor((diff%unitmapping.minutes)/unitmapping.seconds)+" seconds "+
floor((diff%unitmapping.seconds))+" milliseconds";
}
console.log(getHumanizedDiff(new Date("2018-09-16T00:18:00.000Z") - new Date("2018-09-14T00:20:12.200Z")));
console.log(getHumanizedDiff(new Date("2018-09-16T00:18:00.000Z") - new Date("2018-09-04T00:20:02.630Z")));
console.log(getHumanizedDiff(new Date("2018-09-17T00:16:04.000Z") - new Date("2018-09-14T00:20:12.240Z")));
var startDate = "2018-09-14T00:20:12.200Z"
var endDate = "2018-09-16T00:18:00.000Z"
const start = new Date(startDate).getTime();
const end = new Date(endDate).getTime();
const milliseconds = Math.abs(end - start).toString()
const seconds = parseInt(milliseconds / 1000);
const minutes = parseInt(seconds / 60);
const hours = parseInt(minutes / 60);
const days = parseInt(hours / 24);
const time = days + ":" + hours % 24 + ":" + minutes % 60 + ":" + seconds % 60;
console.log(time)
yBrodsky's suggestion to use moment.js is probably the best idea, but if you're curious how to do the math here, it would go something like this:
const start = new Date(startDate).getTime();
const end = new Date(endDate).getTime();
let seconds = Math.round(Math.abs(end - start) / 1000); // We'll round away millisecond differences.
const days = Math.floor(seconds / 86400);
seconds -= days * 86400;
const hours = Math.floor(seconds / 3600);
seconds -= hours * 3600;
minutes = Math.floor(seconds / 60);
seconds -= minutes * 60;
This leaves you with hours, minutes, and seconds as numbers that you can format into a string result however you like.

Categories

Resources