Firefox unexpected bahaviour when dealing with getHours() - javascript

function show_elapsed_time(from)
{
var time_elapsed = new Date().getTime()-from;
var date = new Date(time_elapsed);
var date_elements = (pad(date.getHours()) + ':' + pad(date.getMinutes()) + ':' + pad(date.getSeconds())).split('');
var date_string = '';
for(i = 0; i < date_elements.length; i++)
{
date_string += '<div class="frame">' + date_elements[i] + '</div>';
}
$('#digital_clock').html(date_string);
}
show_elapsed_time(1308446047*1000)
The expected result (at the time of this post) is 0 hours, 2 minutes, .. seconds. This is as well the result given by Opera, Chrome and IE. However, Firefox returns 1 hour, 2 minutes, etc. How to fix it?
Basically:
var date = new Date(1453288); console.log(date.getHours()); // FF: 1, IE: 0, Opera 0
What I am doing is taking: new Date().getTime() - [some timestamp] == time passed
So I need to know time passed from [some timestamp] in hours, minutes and seconds.

Well, the problem is with different locale browser settings. One way to solve the problem is to use UTC specific methods, e.g. getUTCTime(). Instead, I've written this small script to do the math:
var time_elapsed = new Date().getTime()-from;
var hours = Math.floor(time_elapsed/(3600*1000));
time_elapsed -= hours*(3600*1000);
var minutes = Math.floor(time_elapsed/(60*1000));
time_elapsed -= minutes*(60*1000);
var seconds = Math.floor(time_elapsed/1000);

Related

Put clock forward by one hour [duplicate]

It amazes me that JavaScript's Date object does not implement an add function of any kind.
I simply want a function that can do this:
var now = Date.now();
var fourHoursLater = now.addHours(4);
function Date.prototype.addHours(h) {
// How do I implement this?
}
I would simply like some pointers in a direction.
Do I need to do string parsing?
Can I use setTime?
How about milliseconds?
Like this:
new Date(milliseconds + 4*3600*1000 /* 4 hours in ms */)?
This seems really hackish though - and does it even work?
JavaScript itself has terrible Date/Time API's. Nonetheless, you can do this in pure JavaScript:
Date.prototype.addHours = function(h) {
this.setTime(this.getTime() + (h*60*60*1000));
return this;
}
Date.prototype.addHours= function(h){
this.setHours(this.getHours()+h);
return this;
}
Test:
alert(new Date().addHours(4));
The below code will add 4 hours to a date (example, today's date):
var today = new Date();
today.setHours(today.getHours() + 4);
It will not cause an error if you try to add 4 to 23 (see the documentation):
If a parameter you specify is outside of the expected range, setHours() attempts to update the date information in the Date object accordingly
It is probably better to make the addHours method immutable by returning a copy of the Date object rather than mutating its parameter.
Date.prototype.addHours= function(h){
var copiedDate = new Date(this.getTime());
copiedDate.setHours(copiedDate.getHours()+h);
return copiedDate;
}
This way you can chain a bunch of method calls without worrying about state.
The version suggested by kennebec will fail when changing to or from DST, since it is the hour number that is set.
this.setUTCHours(this.getUTCHours()+h);
will add h hours to this independent of time system peculiarities.
Jason Harwig's method works as well.
Get a date exactly two hours from now, in one line.
You need to pass milliseconds to new Date.
let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));
or
let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );
let nowDate = new Date();
let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));
let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );
console.log('now', nowDate);
console.log('expiry', expiryDate);
console.log('expiry 2', expiryDate2);
You can use the Moment.js library.
var moment = require('moment');
foo = new moment(something).add(10, 'm').toDate();
I also think the original object should not be modified. So to save future manpower here's a combined solution based on Jason Harwig's and Tahir Hasan answers:
Date.prototype.addHours= function(h){
var copiedDate = new Date();
copiedDate.setTime(this.getTime() + (h*60*60*1000));
return copiedDate;
}
If you would like to do it in a more functional way (immutability) I would return a new date object instead of modifying the existing and I wouldn't alter the prototype but create a standalone function. Here is the example:
//JS
function addHoursToDate(date, hours) {
return new Date(new Date(date).setHours(date.getHours() + hours));
}
//TS
function addHoursToDate(date: Date, hours: number): Date {
return new Date(new Date(date).setHours(date.getHours() + hours));
}
let myDate = new Date();
console.log(myDate)
console.log(addHoursToDate(myDate,2))
There is an add in the Datejs library.
And here are the JavaScript date methods. kennebec wisely mentioned getHours() and setHours();
Check if it’s not already defined. Otherwise, define it in the Date prototype:
if (!Date.prototype.addHours) {
Date.prototype.addHours = function(h) {
this.setHours(this.getHours() + h);
return this;
};
}
This is an easy way to get an incremented or decremented data value.
const date = new Date()
const inc = 1000 * 60 * 60 // an hour
const dec = (1000 * 60 * 60) * -1 // an hour
const _date = new Date(date)
return new Date(_date.getTime() + inc)
return new Date(_date.getTime() + dec)
Another way to handle this is to convert the date to unixtime (epoch), then add the equivalent in (milli)seconds, then convert it back. This way you can handle day and month transitions, like adding 4 hours to 21, which should result in the next day, 01:00.
SPRBRN is correct. In order to account for the beginning/end of the month and year, you need to convert to Epoch and back.
Here's how you do that:
var milliseconds = 0; //amount of time from current date/time
var sec = 0; //(+): future
var min = 0; //(-): past
var hours = 2;
var days = 0;
var startDate = new Date(); //start date in local time (we'll use current time as an example)
var time = startDate.getTime(); //convert to milliseconds since epoch
//add time difference
var newTime = time + milliseconds + (1000*sec) + (1000*60*min) + (1000*60*60*hrs) + (1000*60*60*24*days);
var newDate = new Date(newTime); //convert back to date; in this example: 2 hours from right now
Or do it in one line (where variable names are the same as above:
var newDate =
new Date(startDate.getTime() + millisecond +
1000 * (sec + 60 * (min + 60 * (hours + 24 * days))));
For a simple add/subtract hour/minute function in JavaScript, try this:
function getTime (addHour, addMin){
addHour = (addHour ? addHour : 0);
addMin = (addMin ? addMin : 0);
var time = new Date(new Date().getTime());
var AM = true;
var ndble = 0;
var hours, newHour, overHour, newMin, overMin;
// Change form 24 to 12 hour clock
if(time.getHours() >= 13){
hours = time.getHours() - 12;
AM = (hours>=12 ? true : false);
}else{
hours = time.getHours();
AM = (hours>=12 ? false : true);
}
// Get the current minutes
var minutes = time.getMinutes();
// Set minute
if((minutes + addMin) >= 60 || (minutes + addMin) < 0){
overMin = (minutes + addMin) % 60;
overHour = Math.floor((minutes + addMin - Math.abs(overMin))/60);
if(overMin < 0){
overMin = overMin + 60;
overHour = overHour-Math.floor(overMin/60);
}
newMin = String((overMin<10 ? '0' : '') + overMin);
addHour = addHour + overHour;
}else{
newMin = minutes + addMin;
newMin = String((newMin<10 ? '0' : '') + newMin);
}
// Set hour
if((hours + addHour >= 13) || (hours + addHour <= 0)){
overHour = (hours + addHour) % 12;
ndble = Math.floor(Math.abs((hours + addHour)/12));
if(overHour <= 0){
newHour = overHour + 12;
if(overHour == 0){
ndble++;
}
}else{
if(overHour == 0){
newHour = 12;
ndble++;
}else{
ndble++;
newHour = overHour;
}
}
newHour = (newHour<10 ? '0' : '') + String(newHour);
AM = ((ndble + 1) % 2 === 0) ? AM : !AM;
}else{
AM = (hours + addHour == 12 ? !AM : AM);
newHour = String((Number(hours) + addHour < 10 ? '0': '') + (hours + addHour));
}
var am = (AM) ? 'AM' : 'PM';
return new Array(newHour, newMin, am);
};
This can be used without parameters to get the current time:
getTime();
Or with parameters to get the time with the added minutes/hours:
getTime(1, 30); // Adds 1.5 hours to current time
getTime(2); // Adds 2 hours to current time
getTime(0, 120); // Same as above
Even negative time works:
getTime(-1, -30); // Subtracts 1.5 hours from current time
This function returns an array of:
array([Hour], [Minute], [Meridian])
If you need it as a string, for example:
var defaultTime: new Date().getHours() + 1 + ":" + new Date().getMinutes();
I think this should do the trick
var nextHour = Date.now() + 1000 * 60 * 60;
console.log(nextHour)
You can even format the date in desired format using the moment function after adding 2 hours.
var time = moment(new Date(new Date().setHours(new Date().getHours() + 2))).format("YYYY-MM-DD");
console.log(time);
A little messy, but it works!
Given a date format like this: 2019-04-03T15:58
//Get the start date.
var start = $("#start_date").val();
//Split the date and time.
var startarray = start.split("T");
var date = startarray[0];
var time = startarray[1];
//Split the hours and minutes.
var timearray = time.split(":");
var hour = timearray[0];
var minute = timearray[1];
//Add an hour to the hour.
hour++;
//$("#end_date").val = start;
$("#end_date").val(""+date+"T"+hour+":"+minute+"");
Your output would be: 2019-04-03T16:58
The easiest way to do it is:
var d = new Date();
d = new Date(d.setHours(d.getHours() + 2));
It will add 2 hours to the current time.
The value of d = Sat Jan 30 2021 23:41:43 GMT+0500 (Pakistan Standard Time).
The value of d after adding 2 hours = Sun Jan 31 2021 01:41:43 GMT+0500 (Pakistan Standard Time).

Why it happens? Strange behavior w/ JavaScript with Date() subtraction. CodePen + Video

I am new with JavaScript and I am building a simple app to calculate my worked hours at work.
When I am subtracting two dates - it works fine (the result is 1:30, for example), but as soon as I add the third date it has a strange behavior and the result is +1 added hour and minutes are 59 44 29 14 (always -1 minute , while the third date itself is always a 0,15,30,45 minutes). I assume the +1 added hour is -1,but it was converted to an absolute number by Date().
Video link to the problem :
https://youtu.be/EyhaVgwxOpw
CodePen : https://codepen.io/anon/pen/PLNqMa
Code
var startHr,
startMin,
endHr,
endMin,
pause;
$(".start,.end,.pochivka").change(function () {
startHr = Number($('#starthr').children("option:selected").val());
startMin = Number($('#startmin').children("option:selected").val());
endHr = Number($('#endhr').children("option:selected").val());
endMin = Number($('#endmin').children("option:selected").val());
pause = Number($('#pause').children("option:selected").val());
});
$(".calculate").click(function(){
// Refer to starting hours and ending hours which get their value from chosen fields
var secondTime = startHr + ":" + startMin +":00";
var firstTime = endHr + ":" + endMin + ":00";
// breakTime also gets from the same place, but has strange behaviour
var breakTime = "00:" + pause + ":00";
console.log(breakTime);
let startHour = new Date().setHours(...(firstTime.split(":")));
let endHour = new Date().setHours(...(secondTime.split(":")));
let removeBreakHours = new Date().setHours(...(breakTime.split(":")));
// Disable next line (and enable the code with next comments)
// to see how normal it works without the bug
// Maybe it happens because I have 2 subtractions?
let finalHours = new Date(startHour - endHour - removeBreakHours);
// Now enable next line.It is the code without "Break times remove"
// let finalHours = new Date(startHour - endHour);
// ------------
var workedHours = finalHours.getUTCHours() +":"+ finalHours.getUTCMinutes();
$('.workHours').text(workedHours);
})
I've made it working by adding the breaktime as negative minutes
$(".calculate").click(function(){
// Refer to starting hours and ending hours which get their value from chosen fields
var secondTime = startHr + ":" + startMin +":00";
var firstTime = endHr + ":" + endMin + ":00";
let startHour = new Date().setUTCHours(...(firstTime.split(":")));
let endHour = new Date().setUTCHours(...(secondTime.split(":")));
let finalHours = new Date(startHour - endHour);
finalHours.setMinutes(- +pause);
// ------------
var workedHours = finalHours.getUTCHours() +":"+ finalHours.getUTCMinutes();
$('.workHours').text(workedHours);
})
In your example you were subtracting milisseconds (to be precise miliseconds passed since 1st of Jan 1970 UTC), so I guess when JS rounds the results is rounding to lower value, resulting in 1 less minute than expected. But I haven't proved it.

Get times in 15 minute increments up to a specific time

I'm using moment.js and would like to create an array that contains all of the times in 15 minute intervals from the current time. So for example:
Current time is 1:35pm. The next time would be 1:45pm, then 2:00, 2:15, 2:30, 2:45, etc. up until a certain point.
I'm really not sure how to this. Would anyone be able to point me in the right direction?
Try this:
function calculate(endTime) {
var timeStops = [];
var startTime = moment().add('m', 15 - moment().minute() % 15);
while(startTime <= endTime){
timeStops.push(new moment(startTime));
startTime.add('m', 15);
}
return timeStops;
}
usage:
calculate(moment().add('h', 1));
This will return time intervals of every quarter of hour (like you said) h:15, h:30, h:45, h+1:00... It also contains seconds, so you might set seconds to 0, since I was not sure if you need them or not.
You also can see working example on FIDDLE
I'm not as familiar with momentjs but this is relatively easy to do in pure Javascript. To get the closest 15 minutes you can use this solution here. Then if you put that in a date variable you can just add 15 minutes as many times as you want! So the resulting Javascript is:
var d = new Date();
var result = "";
for (var idx = 0; idx < 3; idx++)
{
var m = (((d.getMinutes() + 7.5)/15 | 0) * 15) % 60;
var h = ((((d.getMinutes()/105) + .5) | 0) + d.getHours()) % 24;
d = new Date(d.getYear(), d.getMonth(), d.getDay(), h, m, 0, 0);
if (idx > 0) result += ", ";
result += ("0" + h).slice(-2) + ":" + ("0" + m).slice(-2);
d = addMinutes(d, 15);
}
SEE THIS IN A FIDDLE
Notes - I just added 15 minutes 3 times arbitrarily. You could calculate the difference between the time you want and now if you need a different number of intervals. Also note that I don't know exactly what this would do if it is almost midnight, though that would be easy enough to test and code around.
Best of luck!

Change the time on a specified date with javascript

I want change the time on a specified date, i tried as following js code, but doesn't work if... in line number 11. What do i do?
var interval = self.setInterval("clock()", 1000);
function clock() {
var date = new Date();
var hourOffset = 3;
date.setUTCHours(date.getUTCHours(), date.getUTCMinutes());
var time = date.getTime();
date.setUTCFullYear(date.getUTCFullYear(), 3, 21);
var dstStart = date.getTime();
date.setUTCFullYear(date.getUTCFullYear(), 9, 22);
var dstEnd = date.getTime();
if (time > dstStart && time < dstEnd) hourOffset = 4; // This is line 11
date.setUTCHours(date.getUTCHours() + hourOffset, date.getUTCMinutes() + 30);
var output = date.getUTCHours() + ":" + date.getUTCMinutes() + ":" + date.getUTCSeconds();
document.getElementById("clock").innerHTML = output
}
​
I mean is this line that doesn't work:
if (time > dstStart && time < dstEnd) hourOffset = 4;
DEMO: http://jsfiddle.net/bFzny/
I'm not familiar with the date functions, but I can tell you that time is less than dstStart, which is why hourOffset is staying at 3. Also, months are 0 based indices, not 1 based. March would be 2, while September would be 8. http://jsfiddle.net/bFzny/4/ This might help you some. Remember, when using jsfiddle you don't need to enclose the code in tags.

JavaScript unixtime problem

I get the time from the database in Unix format.
It looks like this: console.log (time);
Result: 1300709088000
Now I want to reformat it and pick out only the time, I found this: Convert a Unix timestamp to time in JavaScript
That did not work as I want. The time I get is this:
1300709088000
9:0:0
1300709252000
6:33:20
1300709316000
0:20:0
1300709358000
12:0:0
1300709530000
11:46:40
It is very wrong times when I know that times are quite different. How can I fix it?
console.log(time);
var date = new Date(time*1000);
// hours part from the timestamp
var hours = date.getHours();
// minutes part from the timestamp
var minutes = date.getMinutes();
// seconds part from the timestamp
var seconds = date.getSeconds();
// will display time in 10:30:23 format
var formattedTime = hours + ':' + minutes + ':' + seconds;
console.log(formattedTime);
It looks like this: console.log (time); Result: 1300709088000
That doesn't look like a Unix timestamp (seconds since The Epoch), it looks like milliseconds since The Epoch. So you wouldn't multiply by 1000 to convert from seconds to milliseconds for JavaScript, it's already in milliseconds (or you're dealing with dates more than 41,000 years from now; which is fair enough).
Test:
var times = [
1300709088000,
1300709252000,
1300709316000,
1300709358000,
1300709530000
];
var index;
for (index = 0; index < times.length; ++index) {
display(times[index] + " => " + new Date(times[index]));
}
Live copy
Update: Or getting the individual parts:
var times = [
1300709088000,
1300709252000,
1300709316000,
1300709358000,
1300709530000
];
var index, dt;
for (index = 0; index < times.length; ++index) {
dt = new Date(times[index]);
display(times[index] +
" => " +
dt +
" (" + formatISOLikeDate(dt) + ")");
}
// Not all implementations have ISO-8601 stuff yet, do it manually
function formatISOLikeDate(dt) {
var day = String(dt.getDate()),
month = String(dt.getMonth() + 1), // Starts at 0
year = String(dt.getFullYear()),
hour = String(dt.getHours()),
minute = String(dt.getMinutes()),
second = String(dt.getSeconds());
return zeroPad(year, 4) + "-" +
zeroPad(month, 2) + "-" +
zeroPad(day, 2) + " " +
zeroPad(hour, 2) + ":" +
zeroPad(minute, 2) + ":" +
zeroPad(second, 2);
}
function zeroPad(str, width) {
while (str.length < width) {
str = "0" + str;
}
return str;
}
Live copy ...but if you're going to be doing much of anything with dates, I'd look at DateJS.
Your time stamps are not in Unix format, they're already in the Javascript millisecond resolution format.
Hence you shouldn't be multiplying by 1000 when you create your Date object.
I've tried to do something like this:
console.log (time);
where date = new Date (time);
/ / hours party from the timestamp
was hours = date.getHours ();
/ / party minutes from the timestamp
Every minute = date.getMinutes ();
/ / Seconds Party From The timestamp
where seconds = date.getSeconds ();
/ / Will display time up 10:30:23 format
was formattedTime = hours + ':' + minutes + ':' + seconds;
console.log (formattedTime);
The result is this:
1300709088000
NaN: NaN: NaN

Categories