change date format function - javascript

I am trying to change a date format, would you please help me out to change the date format into this Mon, 12 Feb 2016 11:00?
Here is the code below:
function nicetime(a, out) {
var d = Math.round((+new Date - a) / 1000),
fuzzy = '',
n = 'mins',
d = d < 0 ? 0 : d;
if (out == 1) {
return d;
} else if (out == 0) {
var chunks = new Array();
chunks[0] = [60 * 60 * 24 * 365, 'year', 'years'];
chunks[1] = [60 * 60 * 24 * 30, 'month', 'months'];
chunks[2] = [60 * 60 * 24 * 7, 'week', 'weeks'];
chunks[3] = [60 * 60 * 24, 'day', 'days'];
chunks[4] = [60 * 60, 'hr', 'hrs'];
chunks[5] = [60, 'min', 'mins'];
var i = 0,
j = chunks.length;
for (i = 0; i < j; i++) {
s = chunks[i][0];
if ((xj = Math.floor(d / s)) != 0) {
n = xj == 1 ? chunks[i][1] : chunks[i][2];
break;
}
}
fuzzy += xj == 1 ? '1 ' + n : xj + ' ' + n;
if (i + 1 < j) {
s2 = chunks[i + 1][0];
if (((xj2 = Math.floor((d - (s * xj)) / s2)) != 0)) {
n2 = (xj2 == 1) ? chunks[i + 1][1] : chunks[i + 1][2];
fuzzy += (xj2 == 1) ? ' + 1 ' + n2 : ' + ' + xj2 + ' ' + n2;
}
}
fuzzy += ' ago';
return fuzzy;
}
}

Suppose , your date is "February 04, 2011 19:00:00"
function formatDate(date) {
var d = new Date(date);
var hh = d.getHours();
var m = d.getMinutes();
var s = d.getSeconds();
var dd = "AM";
var h = hh;
if (h >= 12) {
h = hh-12;
dd = "PM";
}
if (h == 0) {
h = 12;
}
m = m<10?"0"+m:m;
s = s<10?"0"+s:s;
/* if you want 2 digit hours:
h = h<10?"0"+h:h; */
var pattern = new RegExp("0?"+hh+":"+m+":"+s);
var replacement = h+":"+m;
/* if you want to add seconds
replacement += ":"+s; */
replacement += " "+dd;
return date.replace(pattern,replacement);
}
alert(formatDate("February 04, 2011 12:00:00"));

Related

Human readable duration format - Codewars

It's a task to build a String with time values and units, separated with ", "
link to Codewars
I'm stuck at the end. I wrote this code:
function formatDuration (seconds) {
// return now if seconds = 0
if (seconds == 0) {
return "now";
}
// count values of each unit
let Y = Math.floor(seconds / 31536000);
let D = Math.floor(seconds / 86400 - Y * 365);
let H = Math.floor(seconds / 3600 - D * 24 - Y * 8760);
let M = Math.floor(seconds / 60 - H * 60 - D * 1440 - Y * 525600);
let S = seconds - M * 60 - H * 3600 - D * 86400 - Y * 31536000;
// build time values + units
let YY = Y + " year";
if (Y != 1) {
YY += "s"
}
let DD = D + " day";
if (D != 1) {
DD += "s"
}
let HH = H + " hour";
if (H != 1) {
HH += "s"
}
let MM = M + " minute";
if (M != 1) {
MM += "s"
}
let SS = S + " second";
if (S != 1) {
SS += "s"
}
let timeDigits = [S, M, H, D, Y];
let timeWhole = [SS, MM, HH, DD, YY];
// check which units are not 0's
let notZeros = [];
for (let i in timeDigits) {
if (timeDigits[i] != 0) {
notZeros += i;
}
}
// iterate notZeros through timeWhole and build the answer
let format = "";
for (let j = 0; j < notZeros.length; j++) {
if (notZeros.length != 1) {
// if it's the last unit
if (j == notZeros[0]) {
format = " and " + timeWhole[notZeros[j]] + format;
}
// if it's another unit
else if (j != notZeros[notZeros.length-1]){
format = ", " + timeWhole[notZeros[j]] + format;
}
// if it's the first unit
else {
format = timeWhole[notZeros[j]] + format;
}
}
// if it's a single unit
else {
format = timeWhole[notZeros[j]];
}
}
return format;
}
It works in most cases. on 100/110 tests made by Codewars results are green:
Test Passed: Value == '6 years, 192 days, 13 hours, 3 minutes and 54 seconds'
But on 10 of them I get this:
Expected: '4 years, 68 days, 3 hours and 4 minutes', instead got: ', 4 years, 68 days and 3 hours, 4 minutes'
Expected: '97 days, 10 hours and 26 seconds', instead got: ', 97 days, 10 hours and 26 seconds'
Expected: '33 days, 59 minutes and 55 seconds', instead got: ', 33 days, 59 minutes and 55 seconds'
Expected: '114 days, 46 minutes and 34 seconds', instead got: ', 114 days, 46 minutes and 34 seconds'
Problem is the ", " in the beginning of these, but I can't find any regularity in it.
Also on the failed test with Years unit, Hours and Minutes are shuffled.
I think an easier approach would be, instead of the whole last section, construct an array of strings - eg ['6 years', '192 days', ...] - then pop the last off, join the rest by a comma, then add on and to the final one (if there's any of them other than the final one):
const Y = Math.floor(seconds / 31536000);
const D = Math.floor(seconds / 86400 - Y * 365);
const H = Math.floor(seconds / 3600 - D * 24 - Y * 8760);
const M = Math.floor(seconds / 60 - H * 60 - D * 1440 - Y * 525600);
const S = seconds - M * 60 - H * 3600 - D * 86400 - Y * 31536000;
const plural = num => num === 1 ? '' : 's';
const YY = Y ? Y + ' year' + plural(Y) : null;
const DD = D ? D + ' day' + plural(D) : null;
const HH = H ? H + ' hour' + plural(H) : null;
const MM = M ? M + ' minute' + plural(M) : null;
const SS = S ? S + ' second' + plural(S) : null;
const nonNullValues = [YY, DD, HH, MM, SS].filter(Boolean);
const last = nonNullValues.pop();
return nonNullValues.length === 0
? last
: nonNullValues.join(', ') + ' and ' + last;
function formatDuration (seconds) {
if(!seconds) return 'now';
const units = {
year : 24 * 60 * 60 * 1 * 365,
day : 24 * 60 * 60 * 1,
hour : 60 * 60 * 1,
minute: 60 * 1,
second: 1
}
const sequence = ['year','day','hour','minute','second']
const calculateTime = (s) => {
let remaningTime = s
return sequence.reduce((acc,key) => {
if(remaningTime >= units[key]) {
acc[key] = Math.floor(remaningTime/units[key])
remaningTime = (remaningTime % units[key])
}
return acc
},{})
}
const displayUnit = (num,str) => `${num} ${str}` + ((num == 1) ? '' : 's')
const displayString = (timeObj) => {
let result = ''
let lastResult = ''
let objKeys = Object.keys(timeObj)
if (objKeys.length <= 1) return displayUnit(timeObj[objKeys[0]],objKeys[0]);
objKeys.forEach(v => {
if (result && lastResult) {
result += `, ${lastResult}`
} else if(lastResult) {
result += `${lastResult}`
}
lastResult = displayUnit(timeObj[v] , v)
})
return `${result} and ${lastResult}`
}
const obj = calculateTime(seconds)
return displayString(obj)
}

Problem with subtracting dates in real time with use setinterval

In this script I use some functions and xDate library for create true format dates. I am trying to make a small script, that show the difference between two dates with a times in real time, but I do not see an error in the code that does not allow this to be done. Where is the error?
jQuery(window).on("load", function() {
function parseISOLocal(s) {
// Split string into its parts
var b = s.split(/\D/);
// Create and return a date object
return new Date(b[0], b[1] - 1, b[2], b[3], b[4], b[5]);
}
// Convert a millisecond value to days, hours, minutes and seconds
function formatDHMS(ms) {
// Helper to add 's' to a number if other than 1
function addS(n) {
return n == 1 ? '' : 's';
}
var d = ms / 8.64e7 | 0;
var h = (ms % 8.64e7) / 3.6e6 | 0;
var m = (ms % 3.6e6) / 6e4 | 0;
var s = (ms % 6e4) / 1e3 | 0;
dd = (d != 0) ? d + ' day' + addS(d) + ', ' : "";
hh = (h != 0) ? h + ' hours' + addS(h) + ', ' : "";
mm = (m != 0) ? m + ' minute' + addS(m) + ', ' : "";
ss = (s != 0) ? s + ' second' + addS(s) + ' ' : "";
return ((d + h + m + s) > 0) ? dd + hh + mm + ss : "Time is over";
}
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
var date = new Date("2020-05-01 12:24:23");
var d1 = new XDate(date.addDays(2));
future_time = d1.toString("yyyy-MM-dd HH:mm:ss");
var d = new XDate();
current_time = d.toString("yyyy-MM-dd HH:mm:ss");
var someDate = new Date();
someDate.setDate(someDate.getDate() + 15); //number of days to add, e.x. 15 days
var dateFormated = someDate.toISOString().substr(0, 10);
console.log(dateFormated);
function Repeat() {
setInterval(function() {
current_time = d.toString("yyyy-MM-dd HH:mm:ss");
$('#timeForSign').html(formatDHMS(parseISOLocal(future_time) - parseISOLocal(current_time)));
}, 100);
}
setTimeout(Repeat, 500);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://www.outsourcer.info/xdate.js"></script>
<div id="timeForSign"></div>
The issue is because you only ever compare the d value within the interval, and that never changes. To fix this you simply need to change d with new Date(), or new XDate(), if you'd prefer to use that library:
current_time = new XDate().toString("yyyy-MM-dd HH:mm:ss");
In addition there's quite a few variables in your JS which aren't necessary and can be removed. Try this:
jQuery(window).on("load", function() {
let future_time = parseISOLocal(new XDate(new Date("2020-05-01 12:24:23").addDays(2)).toString("yyyy-MM-dd HH:mm:ss"));
function Repeat() {
setInterval(function() {
let current_time = new XDate().toString("yyyy-MM-dd HH:mm:ss");
$('#timeForSign').html(formatDHMS(future_time - parseISOLocal(current_time)));
}, 100);
}
setTimeout(Repeat, 500);
});
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
function parseISOLocal(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1] - 1, b[2], b[3], b[4], b[5]);
}
function formatDHMS(ms) {
let addS = (n) => n == 1 ? '' : 's';
let d = ms / 8.64e7 | 0;
let h = (ms % 8.64e7) / 3.6e6 | 0;
let m = (ms % 3.6e6) / 6e4 | 0;
let s = (ms % 6e4) / 1e3 | 0;
let t = [
d + ' day' + addS(d),
h + ' hour' + addS(m),
m + ' minute' + addS(h),
s + ' second' + addS(s)
];
return ms > 0 ? t.join(', ') : "Time is over";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xdate#0.8.2/src/xdate.js"></script>
<div id="timeForSign"></div>

Convert seconds to days, hours, minutes and seconds

I have a Javascript timing event with an infinite loop with a stop button.
It will display numbers when start button is click.Now I want this numbers converted to something like 4 hours, 3 minutes , 50 seconds
var c = 0;
var t;
var timer_is_on = 0;
function timedCount() {
document.getElementById('txt').value = c;
c = c + 1;
t = setTimeout(function() {
timedCount()
}, 1000);
}
function doTimer() {
if (!timer_is_on) {
timer_is_on = 1;
timedCount();
}
}
function stopCount() {
clearTimeout(t);
timer_is_on = 0;
}
$(".start").on("click", function() {
//var start = $.now();
//alert(start);
//console.log(start);
doTimer();
$(".end").show();
$(".hide_div").show();
});
$(".end").on("click", function() {
stopCount();
});
.hide_div {
display: none;
}
.end {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="start">Start</p>
<p class="end">End</p>
<p class="hide_div">
<input type="text" id="txt" />//display numbers eg 12345
</p>
How to convert numbers like 123456 to 1 day, 4 hours, 40 min, 45 seconds?
I suggest doing this way!:
function secondsToDhms(seconds) {
seconds = Number(seconds);
var d = Math.floor(seconds / (3600*24));
var h = Math.floor(seconds % (3600*24) / 3600);
var m = Math.floor(seconds % 3600 / 60);
var s = Math.floor(seconds % 60);
var dDisplay = d > 0 ? d + (d == 1 ? " day, " : " days, ") : "";
var hDisplay = h > 0 ? h + (h == 1 ? " hour, " : " hours, ") : "";
var mDisplay = m > 0 ? m + (m == 1 ? " minute, " : " minutes, ") : "";
var sDisplay = s > 0 ? s + (s == 1 ? " second" : " seconds") : "";
return dDisplay + hDisplay + mDisplay + sDisplay;
}
Use Math like this way, Second param in parseInt is for base, which is optional
var seconds = parseInt(123456, 10);
var days = Math.floor(seconds / (3600*24));
seconds -= days*3600*24;
var hrs = Math.floor(seconds / 3600);
seconds -= hrs*3600;
var mnts = Math.floor(seconds / 60);
seconds -= mnts*60;
console.log(days+" days, "+hrs+" Hrs, "+mnts+" Minutes, "+seconds+" Seconds");
Your given seconds 123456 would be 1 days, 10 Hrs, 17 Minutes, 36 Seconds not 1 days, 4 Hrs, 40 Minutes, 45 Seconds
function countdown(s) {
const d = Math.floor(s / (3600 * 24));
s -= d * 3600 * 24;
const h = Math.floor(s / 3600);
s -= h * 3600;
const m = Math.floor(s / 60);
s -= m * 60;
const tmp = [];
(d) && tmp.push(d + 'd');
(d || h) && tmp.push(h + 'h');
(d || h || m) && tmp.push(m + 'm');
tmp.push(s + 's');
return tmp.join(' ');
}
// countdown(3546544) -> 41d 1h 9m 4s
// countdown(436654) -> 5d 1h 17m 34s
// countdown(3601) -> 1h 0m 1s
// countdown(121) -> 2m 1s
My solution with map() and reduce():
const intervalToLevels = (interval, levels) => {
const cbFun = (d, c) => {
let bb = d[1] % c[0],
aa = (d[1] - bb) / c[0];
aa = aa > 0 ? aa + c[1] : '';
return [d[0] + aa, bb];
};
let rslt = levels.scale.map((d, i, a) => a.slice(i).reduce((d, c) => d * c))
.map((d, i) => ([d, levels.units[i]]))
.reduce(cbFun, ['', interval]);
return rslt[0];
};
const TimeLevels = {
scale: [24, 60, 60, 1],
units: ['d ', 'h ', 'm ', 's ']
};
const secondsToString = interval => intervalToLevels(interval, TimeLevels);
If you call secondsToString(123456), you can get "1d 10h 17m 36s "
Here is my solution, a simple function that will round to the nearest second!
var returnElapsedTime = function(epoch) {
//We are assuming that the epoch is in seconds
var hours = epoch / 3600,
minutes = (hours % 1) * 60,
seconds = (minutes % 1) * 60;
return Math.floor(hours) + " hours, " + Math.floor(minutes) + " minutes, " + Math.round(seconds) + " seconds";
}
Came up with my own variation to some of the solutions suggested in this thread.
if (!Number.prototype.secondsToDHM) {
Number.prototype.secondsToDHM = function() {
const secsPerDay = 86400;
const secsPerHour = 3600;
const secsPerMinute = 60;
var seconds = Math.abs(this);
var minus = (this < 0) ? '-' : '';
var days = Math.floor(seconds / secsPerDay);
seconds = (seconds % secsPerDay);
var hours = Math.floor(seconds / secsPerHour);
seconds = (seconds % secsPerHour);
var minutes = Math.floor(seconds / secsPerMinute);
seconds = (seconds % secsPerMinute);
var sDays = new String(days).padStart(1, '0');
var sHours = new String(hours).padStart(2, '0');
var sMinutes = new String(minutes).padStart(2, '0');
return `${minus}${sDays}D ${sHours}:${sMinutes}`;
}
}
var a = new Number(50000).secondsToDHM();
var b = new Number(100000).secondsToDHM();
var c = new Number(200000).secondsToDHM();
var d = new Number(400000).secondsToDHM();
console.log(a);
console.log(b);
console.log(c);
console.log(d);
This answer builds upon on Andris' approach to this question, but it doesn't have trailing commas if lesser units are not present.
It also borrows from this answer dealing with joining array values only if truthy:
https://stackoverflow.com/a/19903063
I'm not a javascript god and it's probably horribly over-engineered, but hopefully readable and correct!
function sformat(s) {
// create array of day, hour, minute and second values
var fm = [
Math.floor(s / (3600 * 24)),
Math.floor(s % (3600 * 24) / 3600),
Math.floor(s % 3600 / 60),
Math.floor(s % 60)
];
// map over array
return $.map(fm, function(v, i) {
// if a truthy value
if (Boolean(v)) {
// add the relevant value suffix
if (i === 0) {
v = plural(v, "day");
} else if (i === 1) {
v = plural(v, "hour");
} else if (i === 2) {
v = plural(v, "minute");
} else if (i === 3) {
v = plural(v, "second");
}
return v;
}
}).join(', ');
}
function plural(value, unit) {
if (value === 1) {
return value + " " + unit;
} else if (value > 1) {
return value + " " + unit + "s";
}
}
console.log(sformat(60)); // 1 minute
console.log(sformat(3600)); // 1 hour
console.log(sformat(86400)); // 1 day
console.log(sformat(8991)); // 2 hours, 29 minutes, 51 seconds
If you needed to convey the duration more 'casually' in words, you could also do something like:
var remaining_duration = sformat(117);
// if a value is returned, add some prefix and suffix
if (remaining_duration !== "") {
remaining_duration = "about " + remaining_duration + " left";
}
$(".remaining_duration").text(remaining_duration);
// returns 'about 1 minute, 57 seconds left'
I further tweaked the code by Svetoslav as follows:
function convertSecondsToReadableString(seconds) {
seconds = seconds || 0;
seconds = Number(seconds);
seconds = Math.abs(seconds);
const d = Math.floor(seconds / (3600 * 24));
const h = Math.floor(seconds % (3600 * 24) / 3600);
const m = Math.floor(seconds % 3600 / 60);
const s = Math.floor(seconds % 60);
const parts = [];
if (d > 0) {
parts.push(d + ' day' + (d > 1 ? 's' : ''));
}
if (h > 0) {
parts.push(h + ' hour' + (h > 1 ? 's' : ''));
}
if (m > 0) {
parts.push(m + ' minute' + (m > 1 ? 's' : ''));
}
if (s > 0) {
parts.push(s + ' second' + (s > 1 ? 's' : ''));
}
return parts.join(', ');
}
Short answer:
var s = (Math.floor(123456/86400) + ":" + (new Date(123456 * 1000)).toISOString().substr(11, 8)).split(":");
console.log(`${s[0]} days, ${s[1]} hours, ${s[2]} minutes, ${s[3]} seconds` )
Edit:
Let me break it down in parts :
Math.floor(123456/86400)
86400 is the the total seconds in a day (60 seconds * 60 minutes * 24 hours). Dividing the inputted seconds by this value gives us number of days. We just need the whole part so we use Math.floor because the fractional piece is handled by this part:
(new Date(123456 * 1000)).toISOString().substr(11, 8)
the explanation can be found here:
Convert seconds to HH-MM-SS with JavaScript?
It just outputs hh:mm:ss, no days. So the first part and this part is a perfect combination
We concatenate using a colon (:) as a separator. The string looks like this:
'1:10:17:36'
We split it into an array with .split(":");. Then finally, we format the elements of the array for the desired output.
I've tweaked the code that Andris posted https://stackoverflow.com/users/3564943/andris
// https://stackoverflow.com/questions/36098913/convert-seconds-to-days-hours-minutes-and-seconds
function app_ste_36098913_countdown_seconds_to_hr(seconds) {
seconds = seconds || 0;
seconds = Number(seconds);
seconds = Math.abs(seconds);
var d = Math.floor(seconds / (3600*24));
var h = Math.floor(seconds % (3600*24) / 3600);
var m = Math.floor(seconds % 3600 / 60);
var s = Math.floor(seconds % 60);
var parts = new Array();
if (d > 0) {
var dDisplay = d > 0 ? d + ' ' + (d == 1 ? "day" : "days") : "";
parts.push(dDisplay);
}
if (h > 0) {
var hDisplay = h > 0 ? h + ' ' + (h == 1 ? "hour" : "hours") : "";
parts.push(hDisplay)
}
if (m > 0) {
var mDisplay = m > 0 ? m + ' ' + (m == 1 ? "minute" : "minutes") : "";
parts.push(mDisplay)
}
if (s > 0) {
var sDisplay = s > 0 ? s + ' ' + (s == 1 ? "second" : "seconds") : "";
parts.push(sDisplay)
}
return parts.join(', ', parts);
}
You will probably find using epoch timestamps more straightforward: As detailed in Convert a Unix timestamp to time in JavaScript, the basic method is like so:
<script>
// Create a new JavaScript Date object based on the timestamp
// multiplied by 1000 so that the argument is in milliseconds, not seconds.
var date1 = new Date();
alert ('easy trick to waste a few seconds...' + date1);
// var date = date2 - date1;
// Hours part from the timestamp
var hours1 = date1.getHours();
// Minutes part from the timestamp
var minutes1 = "0" + date1.getMinutes();
// Seconds part from the timestamp
var seconds1 = "0" + date1.getSeconds();
var date2 = new Date();
// Hours part from the timestamp
var hours2 = date2.getHours();
// Minutes part from the timestamp
var minutes2 = "0" + date2.getMinutes();
// Seconds part from the timestamp
var seconds2 = "0" + date2.getSeconds();
// Will display time in 10:30:23 format
// var formattedTime = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
var elapsedHrs = hours2 - hours1;
var elapsedMin = minutes2.substr(-2) -minutes1.substr(-2);
var elapsedSec = seconds2.substr(-2) - seconds1.substr(-2);
var elapsedTime = elapsedHrs + ' hours, ' + elapsedMin + ' minutes, ' + elapsedSec + ' seconds';
alert ('time between timestamps: ' + elapsedTime);
</script>
Be warned that this script needs some work since for now it will give negative values for things like date1 = 12:00:00 and date2 = 12:00:05, but I'll leave that to you fo now.
You should rewrite your code to take a timestamp ( var x = new Date(); ) at the start of your timer and one whenever you are done/want to check elapsed time, and subtract the two before parsing out elapsed seconds, minutes, hours etc as required.
This is my take at the question, even if it is an old topic.
You can use a loop to compute everything for you :
function time_remaining(date1, date2) {
let seconds = (date2 - date1) / 1000
let units = ["years", "days", "h", "min", "s"]
let limit_units = [365, 24, 60, 60, 1]
const reducer = (accumulator, curr) => accumulator * curr;
let time = []
for (let i = 0; i < units.length; i++) {
let divisor = limit_units.slice(i).reduce(reducer)
let value = Math.floor(seconds / divisor)
seconds = seconds - value * divisor
time.push(value)
}
return clean_time(time, units)
}
// at this point, you have your answer. However,
// we can improve the result by removing all none
// significative null units (i.e, if your countdown is
// only about hours, minutes and seconds, it is not
// going to include years and days.)
function clean_time(time, units) {
time = time.reverse()
while (time[time.length - 1] == 0) {
time.pop()
}
return [time.reverse(), units.slice(-time.length)]
}
let date1 = Date.parse("2023-07-09T17:50:33")
console.log(time_remaining(Date.now(), date1))

Interval Array not creating

I found this code but when insert anytime between x:15 - x:45 (x being any associated time) I do not get the intervals for those times.
var setIntervals = function (start, end, inc, oc) {
start = start.toString().split(':');
end = end.toString().split(':');
inc = parseInt(inc, 10);
oc = oc;
var pad = function (n) { return (n < 10) ? '0' + n.toString() : n; },
startHr = parseInt(start[0], 10),
startMin = parseInt(start[1], 10),
endHr = parseInt(end[0], 10),
endMin = parseInt(end[1], 10),
currentHr = startHr,
currentMin = startMin,
previous = currentHr + ':' + pad(currentMin),
current = '',
r = [];
do {
currentMin += inc;
if ((currentMin % 60) === 0 || currentMin > 60) {
currentMin = (currentMin === 60) ? 0 : currentMin - 60;
currentHr += 1;
}
current = currentHr + ':' + pad(currentMin);
r.push({"end":current, "start":previous, "OpenClosed":oc});
previous = current;
} while (currentHr !== endHr);
return r;
};
var closedTime=setIntervals("<?php echo $close_now ?>","<?php echo $close_end ?>","15", "closed");
var closeArray = [];
closeArray.push(closedTime);
Currently I only get the times from 1:30 - 2:00 but not up to 2:30... If I do 2:00 to 3:00 I get all the intervals.
https://jsfiddle.net/pbbsoxrz/
Added the issue into jsfiddle
Courteous of JavaScript Setting Time Difference through Loop In Array
Just change the while condition and add the part for the minutes with logical or.
while (currentHr !== endHr || currentMin !== endMin);
var setIntervals = function (start, end, inc, oc) {
start = start.toString().split(':');
end = end.toString().split(':');
inc = parseInt(inc, 10);
oc = oc;
var pad = function (n) { return (n < 10) ? '0' + n.toString() : n; },
currentHr = parseInt(start[0], 10),
currentMin = parseInt(start[1], 10),
endHr = parseInt(end[0], 10),
endMin = parseInt(end[1], 10),
previous = currentHr + ':' + pad(currentMin),
current = '',
r = [];
do {
currentMin += inc;
currentHr += currentMin / 60 | 0;
currentMin %= 60;
current = currentHr + ':' + pad(currentMin);
r.push({ start: previous, end: current, OpenClosed: oc });
previous = current;
} while (currentHr !== endHr || currentMin !== endMin); // <----------- change this!
return r;
};
var closedTime = setIntervals("12:15", "14:45", "15", "closed");
var closeArray = [];
closeArray.push(closedTime);
document.write('<pre>' + JSON.stringify(closeArray, 0, 4) + '</pre>');
Here's what you want:
var setIntervals = function(start, end, inc, oc) {
var date1 = new Date('2015-1-1 ' + start),
date2 = new Date('2015-1-1 ' + end),
r = [],
current,
previous;
// Make sure we increment is a positive number so we don't have an infinite loop
inc = Math.abs(parseInt(inc, 10));
do {
previous = ('0' + date1.getHours()).slice(-2) + ':' + ('0' + date1.getMinutes()).slice(-2);
date1.setTime(date1.getTime() + inc * 60 * 1000);
current = ('0' + date1.getHours()).slice(-2) + ':' + ('0' + date1.getMinutes()).slice(-2);
r.push({
"end": current,
"start": previous,
"OpenClosed": oc
});
} while (date1.getTime() < date2.getTime());
return r;
};
var closeArray = [setIntervals("13:30", "14:30", "15", "closed")];
console.log(closeArray);
The while condition of your original code causes the loop to end every time the two hours are equal.
This approach simplify things a bit.

Averaging Times using Javascript

I am building an app using Phonegap and JQuery.
The app stores ( using window.localStorage ) a set of times (no more than 10) in the format.
HH:MM:SS.mm
There are a number of 'Zero' times in the list eg '00:00:00.00' which iphonegap, javascript
eliminate using..
function removeA(arr){
var what, a= arguments, L= a.length, ax;
while(L> 1 && arr.length){
what= a[--L];
while((ax= arr.indexOf(what))!= -1){
arr.splice(ax, 1);
}
}
return arr;
}
scores.sort();
removeA(scores,'00:00:00.00');
so that i'm left with the fastest time first, and only the times that have a value.
I need to produce from the remaining values the average of those times.
eg: 00:00:03.00
00:00:05.00
00:00:02.00
00:00:06.00
= 00:00:04.00
thanks in advance :)
var times= [ '00:00:03.00', '00:00:05.00', '00:00:02.00', '00:00:06.00'],
date = 0,
result = '';
function offsetify(t){
return t < 10 ? '0' + t : t;
}
for(var x = 0; x < times.length; x++ ) {
var tarr = times[x].split(':');
date += new Date(0, 0, 0, tarr[0], tarr[1], tarr[2].split('.')[0], tarr[2].split('.')[1]).getTime();
}
var avg = new Date(date/times.length);
result = offsetify(avg.getHours()) + ':' + offsetify(avg.getMinutes()) + ':' + offsetify(avg.getSeconds()) + '.' + offsetify(avg.getMilliseconds());
DEMO
if you are going to also have millisecond values and you want to consider them, then convert the times into millisecond. Now, add them and divide them by the number of records. Else, convert everything to seconds and find the average - you get the answer in seconds, of course.
The conversion is quite simple if take little time to think over it. Here's how to convert.
To milliseconds:
function convertToMS(timeStr) { // timeStr in format 'HH:MM:SS.mm'
var I = parseInt; // for brevity
var t = timeStr,
h = I( t.substr(0,2) ),
m = I( t.substr(3,2) ),
s = I( t.substr(6,2) ),
ms = I( t.substr(9,2) );
return h * 3600000 + m * 60000 + s * 1000 + ms;
}
To seconds:
function convertToS(timeStr) { // timeStr in format 'HH:MM:SS[.mm]' -- .mm is ignored.
var I = parseInt; // for brevity
var t = timeStr,
h = I( t.substr(0,2) ),
m = I( t.substr(3,2) ),
s = I( t.substr(6,2) );
return h * 3600 + m * 60 + s;
}
After the conversion's done, add them up and find the average.
UPDATE:
To convert back to the format 'HH:MM:SS.mm', we change back the time into 'chunks' of hours, minutes, seconds and (if applicable) milliseconds.
function chunkifyFromSec(time) { // time in s
var t = "",
h = Math.floor(time / 3600),
m = Math.floor( (t - (h * 3600)) / 60 ),
s = t - (h * 3600) - (m * 60);
return {
HH: h, MM: m, SS: s, mm: 0
};
}
function chunkifyFromMS(time) { // time in ms
var t = "",
h = Math.floor(time / 3600000),
m = Math.floor( (t - (h * 3600000)) / 60000 ),
s = Math.floor( (t - (h * 3600000) - (m * 60000)) / 1000 ),
mm = t - (h * 3600000) - (m * 600000) - (s * 1000);
return {
HH: h, MM: m, SS: s, mm: mm
};
}
Then, we return the string in the format 'HH:MM:SS.mm' using this:
function toTimeStr(chunks) {
return
(chunks.HH < 0 ? '0' : '') + chunks.HH + ":"
+= (chunks.MM < 0 ? '0' : '') + chunks.MM + ":"
+= (chunks.SS < 0 ? '0' : '') + chunks.SS + "."
+= (chunks.mm < 0 ? '0' : '') + chunks.mm
}
I don't have much experience with Javascript so I might have some syntax errors but I think you could do something like
var i = 0;
var totalTime = 0.0;
for (i=0; i < scores.length; i++) {
var hours = parseFloat(scores[i].substring(0, 2)); //get numeric value for hours
var minutes = parseFloat(scores[i].substring(3,5)); //get numeric value for minutes
var seconds = parseFloat(scores[i].substring(6)); //get numeric for the seconds
var time = ((hours * 60) + minutes) * 60 + seconds; //60 minutes in an hour, 60 seconds in a minute
totalTime += time;
}
var avgTime = totalTime/scores.length;
var avgHours = Math.floor(avgTime / 3600); //60*60
var avgHoursStr = String(avgHours);
var avgMinutes = Math.floor((avgTime % 3600) / 60); //mod to get rid of the hours
var avgMinutesStr = String(avgMinutes);
var avgSeconds = avgTime - avgHours*3600 - avgMinutes*60; //get the remainder. Can't use mod due to decimal
var avgSeconds = String(avgSeconds);
//Concat strings. Add the ":" spacers. Where necessary, add leading 0
var avgStr = (avgHoursStr.length > 1 ? "" : "0") + avgHoursStr + ":" + (avgMinutesStr.length > 1 ? "" : "0") + avgMinuteStr + ":" + avgSecondsStr;
[EDIT - Thanks to Parth Thakkar for point out my problem]
To return the answer in milliseconds or seconds:
var times = ["00:00:03.00", "00:00:05.00", "00:00:02.00", "00:00:06.00"];
function averageTimes(times,unit) {
if (!times) {
return false;
}
else {
var totalMilliseconds = 0, hours, minutes, seconds, milliseconds, parts;
for (var i = 0, len = times.length; i < len; i++) {
parts = times[i].split(':');
hours = parseInt(parts[0], 10) * 3600000;
minutes = parseInt(parts[1], 10) * 60000;
seconds = parseInt(parts[2].split('.')[0], 10) * 1000;
milliseconds = parseInt(parts[2].split('.')[1], 10);
totalMilliseconds += (hours + minutes + seconds + milliseconds);
}
if (!unit || unit.toLowerCase() == 'ms'){
return totalMilliseconds/times.length + ' milliseconds';
}
else if (unit.toLowerCase() == 's') {
return (totalMilliseconds/1000)/times.length + ' seconds';
}
}
}
// parameters:
// times: an array of times in your supplied format, 'HH:MM:SS:mm',
// unit: a string ('ms' or 's'), denoting whether to return milliseconds or seconds.
var average = averageTimes(times,'s');
console.log(average);​
JS Fiddle demo.
References:
for(){/*...*/} loop.
parseInt().
split().
toLowerCase().

Categories