Related
i need to convert input value: ":2" to 'HH:mm' format.
":2" it should be converted to "00:20". All this process should be done with moment.js
let timeString = ":2";
const time = document.getElementById('time');
time.innerHTML = moment(timeString).format('HH:mm');
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
<span id="time"></span>
I didn't put input, because my problem is to get or convert correct format.
As stated before, you will have to convert the input yourself before passing it to momentjs - the following could work for you, depending on what the result for other values should be. I assumed:
":3" -> "00:30",
":21" -> "00:21",
"2:2" -> "02:20"
let timeString = ":2";
const hours = timeString.split(":")[0] || "00";
let minutes = timeString.split(":")[1];
if (minutes.length === 1) {
minutes = minutes * 10;
}
const parsedTime = hours + ":" + minutes;
const time = document.getElementById('time');
time.innerHTML = moment(parsedTime, "HH:mm").format("HH:mm");
I'm trying to add hours to time in the format of 24 hours say '23:59:59'. I need to add, for example, 2.5 hours so the time should roll to the next day and be shown as '02:30:00'.
What I have tried so far works until it reaches '23:59:59'. I need to show the next day time if it exceeds '23:59:59'. Here is what I have tried so far:
var time = $('#starttime').val().split(':');
var d = new Date();
d.setHours(+time[0]);
d.setMinutes(time[1]);
d.setSeconds(time[2]);
var time2 = $('#endtime').val().split(':');
var endtimeval = new Date();
endtimeval.setHours(+time2[0]);
endtimeval.setMinutes(time2[1]);
endtimeval.setSeconds(time2[2]);
var str = d.getHours() + parseInt($('#noofhours').val()) + ":" + time2[1] + ":" + time2[2];
$('#endtime').val(str);
Using a Date Object here is possibly unnecessary, modulo arithmetic should suffice.
const pad = n => {
const s = String(n);
return s.length > 1 ? s : '0' + s;
};
const addHours = (timeVal, numHours) => {
const [hr, min, sec] = timeVal.split(':').map(Number);
const [,lefty, righty] = String(numHours).match(/(\d+)(?:(\.\d+))?/).map(Number);
const hours = (hr + lefty) % 24;
const minutes = righty === undefined ?
min :
((righty * 60 | 0) + min) % 60;
return [hours, minutes, sec].map(pad).join(':');
};
addHours('23:59:59', 2.5) // "01:29:59"
Note that since there's no dates involved it will not accurately handle e.g. daylight savings time. Also note that minutes are in this example rounded down, you could repeat the logic for seconds if desired.
Note that your approach using Date objects will give different answers for the same inputs depending on when/where the logic runs, for the same reasons.
Make a custom date adder?
const add = (time, hours) => {
let [hh, mm, ss] = time.split(':');
const seconds = hours * 60 * 60;
ss = ss * 1 + seconds;
if (ss >= 60) {
mm = mm * 1 + ss / 60;
ss = (ss % 60).toPrecision(2).padStart(2, '0');
}
if (mm >= 60) {
hh = hh * 1 + mm / 60;
mm = (mm % 60).toPrecision(2).padStart(2, '0');
}
hh = (Math.floor(hh) % 24).toString().padStart(2, '0');
return hh + ':' + mm + ':' + ss;
}
console.log(add("23:59:59", 2.5));
you may apply DRY principle and refactor the code yourself. But it will get the job done according to your requirement.
The simple trick that I did is just converted the hours entered as float/int to a minute value by multiplying to 60 and created a date, with this just added the time I already have.
Here the solution with minimal steps:
var time = $('#endtime').val().split(':');
var d = new Date();
d.setHours(+time[0]);
d.setMinutes(time[1]);
d.setSeconds(time[2]);
var addeddate = new Date();
addeddate.setMinutes(parseFloat($('#noofhours').val()) * 60);
$('#endtime').val(("0" + (addeddate.getHours())).slice(-2) + ":" + ("0" + (addeddate.getMinutes())).slice(-2) + ":" + ("0" + (addeddate.getSeconds())).slice(-2)); //The answer that I needed in endtime id value.
You can use vanilla JavaScript Date methods fairly easily here. Most of the work is parsing the time string inputs and then concatenating the time string output. For example:
const start = '23:59:59';
const add = '2.5';
const [hh, mm, ss] = start.split(':').map(x => parseInt(x));
const d = new Date(new Date().setHours(hh, mm + (add * 60), ss));
const end = `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`;
console.log(end);
// 2:29:59
In my application, I need to create live clock according to different timezones which are stored into database.
I have almost succeeded it.
But now I'm facing negative time in clock, and I'm out of ideas to figure out a solution.
I'm getting UTC time with the help of new Date() and calculating time with provided timezone from database.
Case 1: 0:31 (UTC time) + 5:30 (timezone) = '06:01'
Case 2: 06:31 (UTC time) - 6:30 (timezone) = '00:01'
Case 3: 5:0 (UTC time) - 7:0 (timezone) = '-02:00'
Case 1 and 2 is working properly but I'm getting negative value in 3rd case which is wrong.
I have tried to add comments in code to have better understanding of what I'm doing here. I hope it helps.
Any help will be highly appreciated.
function runClock() {
setInterval(function() {
//debugger
var time = new Date();
// take timezone from HTML element
// ex: +:5:30
var getTimezone = "-:7:0" //$("#timeZone").text();
// split into array to get oparator (Positive and Negative Timezone)
var oparator = getTimezone.split(":")[0];
var timezone = getTimezone.split(":")[1] + ":" + getTimezone.split(":")[2];
// get UTC hours
var hours = 5 //time.getUTCHours();
var minutes = 0 //time.getUTCMinutes();
var UTCTIME = timeStringToFloat(hours + ":" + minutes);
var TIMEZONEOFFSETTIME = timeStringToFloat(timezone);
var finalTime = "";
// Convert time folloed by Colon into decimals
// ex: 1:45 = 1.75
function timeStringToFloat(time) {
var hoursMinutes = time.split(/[.:]/);
var hh = parseInt(hoursMinutes[0], 10);
var mm = hoursMinutes[1] ? parseInt(hoursMinutes[1], 10) : 0;
return hh + mm / 60;
}
// Convert time folloed by float into Colon
// ex: 1.75 = 1:45
function floatToTime(FT) {
var splittedTime = FT.toString().split(".");
var hh = splittedTime[0];
var mm = "";
if (splittedTime[1]) {
mm = Math.round((splittedTime[1] / 100) * 60);
} else {
mm = "0";
}
finalTime = hh + ":" + ((mm < 10) ? ("0" + mm) : mm);
}
// Calculate time (UTC + or - Timezone)
// Ex: 00:15 (UTC) + 5:30 = 5:45
function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
if (oparator == "+") {
var FT = UTCTIME + TIMEZONEOFFSETTIME;
FT = FT.toFixed(2);
floatToTime(FT);
} else {
var FT = UTCTIME - TIMEZONEOFFSETTIME;
FT = FT.toFixed(2);
floatToTime(FT);
}
}
// Parse Seconds
function seconds() {
var j = "";
if (time.getUTCSeconds() < 10) {
j = "0" + time.getUTCSeconds();
} else {
j = time.getUTCSeconds()
}
return j;
}
CalcTime(UTCTIME, TIMEZONEOFFSETTIME);
$("#clockTime").text(finalTime + ":" + seconds());
}, 1000);
}
runClock();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<b id="clockTime"></b>
You should just be "looping back" to 23:59 when you go negative. You can just add something to check if it goes negative then just re-add the missing time:
function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
if (oparator == "+") {
var FT = UTCTIME + TIMEZONEOFFSETTIME;
FT = FT.toFixed(2);
floatToTime(FT);
} else {
var FT = UTCTIME - TIMEZONEOFFSETTIME;
// Offset any negative times;
if (FT < 0) {
FT += 24;
}
FT = FT.toFixed(2);
floatToTime(FT);
}
}
But ideally you really don't want to be handling these kinds of Timezone issues as other libraries are already handling it, i.e. moment.js
function runClock() {
setInterval(function() {
//debugger
var time = new Date();
// take timezone from HTML element
// ex: +:5:30
var getTimezone = "-:7:0" //$("#timeZone").text();
// split into array to get oparator (Positive and Negative Timezone)
var oparator = getTimezone.split(":")[0];
var timezone = getTimezone.split(":")[1] + ":" + getTimezone.split(":")[2];
// get UTC hours
var hours = 5 //time.getUTCHours();
var minutes = 0 //time.getUTCMinutes();
var UTCTIME = timeStringToFloat(hours + ":" + minutes);
var TIMEZONEOFFSETTIME = timeStringToFloat(timezone);
var finalTime = "";
// Convert time folloed by Colon into decimals
// ex: 1:45 = 1.75
function timeStringToFloat(time) {
var hoursMinutes = time.split(/[.:]/);
var hh = parseInt(hoursMinutes[0], 10);
var mm = hoursMinutes[1] ? parseInt(hoursMinutes[1], 10) : 0;
return hh + mm / 60;
}
// Convert time folloed by float into Colon
// ex: 1.75 = 1:45
function floatToTime(FT) {
var splittedTime = FT.toString().split(".");
var hh = splittedTime[0];
var mm = "";
if (splittedTime[1]) {
mm = Math.round((splittedTime[1] / 100) * 60);
} else {
mm = "0";
}
finalTime = hh + ":" + ((mm < 10) ? ("0" + mm) : mm);
}
// Calculate time (UTC + or - Timezone)
// Ex: 00:15 (UTC) + 5:30 = 5:45
function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
if (oparator == "+") {
var FT = UTCTIME + TIMEZONEOFFSETTIME;
FT = FT.toFixed(2);
floatToTime(FT);
} else {
var FT = UTCTIME - TIMEZONEOFFSETTIME;
// Offset any negative times;
if (FT < 0) {
FT += 24;
}
FT = FT.toFixed(2);
floatToTime(FT);
}
}
// Parse Seconds
function seconds() {
var j = "";
if (time.getUTCSeconds() < 10) {
j = "0" + time.getUTCSeconds();
} else {
j = time.getUTCSeconds()
}
return j;
}
CalcTime(UTCTIME, TIMEZONEOFFSETTIME);
$("#clockTime").text(finalTime + ":" + seconds());
}, 1000);
}
runClock();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<b id="clockTime"></b>
You want to recover/display the time for a given timezone offset? Unless you like doing this for a hobby, stay away from string methods and use the date functions, no?
var offsetMS = -5.5 * 3600000
var myDate = new Date()
var dateWithOffset = new Date( myDate.getTime() + offsetMS )
var formatted = dateWithOffset.toLocaleString("en-GB",{timeZone:"UTC",hour:"numeric",minute:"numeric"})
console.log(formatted)
Even manipulating timezone offset directly is to be avoided. If you can, use toLocaleString with a real timezone name, then issues like daylight saving will be handled for you. Modern browsers support all iana timezones, so let them do the work.
Add 24 to your FT value and take division remain of 24:
function CalcTime(UTCTIME, TIMEZONEOFFSETTIME) {
if (oparator == "+") {
var FT = UTCTIME + TIMEZONEOFFSETTIME;
} else {
var FT = UTCTIME - TIMEZONEOFFSETTIME + 24;
FT = FT % 24;
}
FT = FT.toFixed(2);
floatToTime(FT);
}
Working sample: https://codepen.io/anon/pen/VqQqoo
If you do not want to use a library like moment.js that comes with time zone handling and simply need to add/subtract hours from a given date, how about converting them to a common time unit and operating on that?
const timezoneString = '-:12:30';
const parts = timezoneString.split(':');
const timezone = (parts[0] === '-' ? -1 : 1) * (parseInt(parts[1]) + (parseInt(parts[2]) / 60.0));
const timeZoneMillis = timezone * 3600 * 1000;
const now = new Date();
const inZone = new Date(now.getTime() + timeZoneMillis);
console.log(now, inZone);
Something like this would convert them to a millisecond timestamp and subtract that many hours and convert it back to a date.
I have a function that will calculate time between two date / time but I am having a small issue with the return.
Here is the way I collect the information.
Start Date
Start Time
Ending Date
Ending Time
Hours
And here is the function that calculates the dates and times:
function calculate (form) {
var d1 = document.getElementById("date1").value;
var d2 = document.getElementById("date2").value;
var t1 = document.getElementById("time1").value;
var t2 = document.getElementById("time2").value;
var dd1 = d1 + " " + t1;
var dd2 = d2 + " " + t2;
var date1 = new Date(dd1);
var date2 = new Date(dd2);
var sec = date2.getTime() - date1.getTime();
if (isNaN(sec)) {
alert("Input data is incorrect!");
return;
}
if (sec < 0) {
alert("The second date ocurred earlier than the first one!");
return;
}
var second = 1000,
minute = 60 * second,
hour = 60 * minute,
day = 24 * hour;
var hours = Math.floor(sec / hour);
sec -= hours * hour;
var minutes = Math.floor(sec / minute);
sec -= minutes * minute;
var seconds = Math.floor(sec / second);
var min = Math.floor((minutes * 100) / 60);
document.getElementById("result").value = hours + '.' + min;
}
If I put in todays date for both date fields and then 14:30 in the first time field and 15:35 in the second time field the result is shown as 1.8 and it should be 1.08
I didn't write this function but I am wondering if someone could tell me how to make that change?
Thank you.
If I understand correctly, the only issue you are having is that the minutes are not padded by zeroes. If this is the case, you can pad the value of min with zeroes using this little trick:
("00" + min).slice(-2)
I can't see why 15:35 - 14:30 = 1.08 is useful?
Try this instead:
function timediff( 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;
//take out milliseconds
difference_ms = difference_ms/1000;
var seconds = Math.floor(difference_ms % 60);
difference_ms = difference_ms/60;
var minutes = Math.floor(difference_ms % 60);
difference_ms = difference_ms/60;
var hours = Math.floor(difference_ms % 24);
var days = Math.floor(difference_ms/24);
return [days,hours,minutes,seconds];
}
function calculate (form) {
var d1 = document.getElementById("date1").value;
var d2 = document.getElementById("date2").value;
var t1 = document.getElementById("time1").value;
var t2 = document.getElementById("time2").value;
var dd1 = d1 + " " + t1;
var dd2 = d2 + " " + t2;
var date1 = new Date(dd1);
var date2 = new Date(dd2);
var diff = timediff(date1, date2);
document.getElementById("result").value = diff[1] + ':' + diff[2];
}
Verify if number of minutes is less than 10 and if it is then append an additional zero in front. Follow similar approach for seconds.
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).