Countdown Values keep coming out as undefined in JavaScript - javascript

I know there are easier ways to make a countdown Timer, but I need to do it with these three functions.
I tried returning the values of the getRemainingTime function as an Array, but got the same result.
The timer says undefined Tage undefined:undefined:undefined
const ReleaseDate = new Date("April 01, 2020 12:00:00").getTime();
//Calculate Days,Hours,Minutes,Seconds left
function getRemainingTime(CurrentDate, ReleaseDate){
const Differenz = ReleaseDate - CurrentDate;
const d= Math.floor(Differenz / (1000*60*60*24));
const h= Math.floor((Differenz / (1000*60*60*24)) / (1000*60*60));
const m= Math.floor((Differenz / (1000*60*60)) / (1000*60));
const s= Math.floor((Differenz / (1000*60)) / 1000);
//return multiple values as objects
return {d:d, h:h, m:m, s:s};
}
//produce and return strings
function formatDays(days){
return (days + " Tage ");
}
function formatTime(hours, minutes, seconds){
return (hours + ":" + minutes + ":" + seconds);
}
function updateCountdown(){
//repeat every second
const TimerFunction = setInterval(function(){
//calculate time now
const CurrentDate = new Date().getTime();
//call function to calculate days,hours,minutes,seconds
getRemainingTime();
//access Objects
const values = getRemainingTime();
const days = values.d;
const hours = values.h;
const minutes = values.m;
const seconds = values.s;
//call functions to produce strings
formatDays();
formatTime();
document.getElementById("Countdown-Timer").innerText = formatDays() + formatTime();
},1000)
}
//start updateCountdown function
updateCountdown();

const ReleaseDate = new Date("April 01, 2020 12:00:00").getTime();
function getRemainingTime(CurrentDate, ReleaseDate) {
const Differenz = ReleaseDate - CurrentDate;
const d = Math.floor(Differenz / (1000 * 60 * 60 * 24));
const h = Math.floor((Differenz / (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const m = Math.floor((Differenz / (1000 * 60 * 60)) / (1000 * 60));
const s = Math.floor((Differenz / (1000 * 60)) / 1000);
return {
d: d,
h: h,
m: m,
s: s
};
}
function formatDays(days) {
return (days + " Tage ");
}
function formatTime(hours, minutes, seconds) {
return (hours + ":" + minutes + ":" + seconds);
}
function updateCountdown() {
const TimerFunction = setInterval(function () {
const CurrentDate = new Date().getTime();
getRemainingTime(CurrentDate, ReleaseDate);
const values = getRemainingTime(CurrentDate, ReleaseDate);
const days = values.d;
const hours = values.h;
const minutes = values.m;
const seconds = values.s;
formatDays(days);
formatTime(hours, minutes, seconds);
document.getElementById("Countdown-Timer").innerText = (formatDays(days) + formatTime(hours, minutes, seconds));
}, 1000)
}
updateCountdown();

Related

how to make count timer increase in hour, minute, seconds in javascript?

i want to make count timer from 00:00:00, the count start if "div id = data" is filled with "const date" and the time increase until the code receive stop trigger. how i can achieve that?
here is my current code :
<div id="data"></div>
<p id="demo"></p>
<script>
const api_url = 'json.php'
async function okejson() {
const resp = await fetch(api_url);
const dat = await resp.json();
const awal = (dat[0])
const date = awal.tanggal
document.getElementById("data").innerHtml = date
var distance = 0;
var x = setInterval(function() {
distance +=1;
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById("demo").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
}, 1000); }
</script>
Using setInterval will not yeild accurate results. It is acceptable for short periods and non critical applications. If it may take hours you should consider using system clock. However here is a constructor which you can use to generate an object which has a start (and also stop and reset) method on it. The start method accepts a callback function which it will call each second and passes an object with days, hours, minutes, and seconds properties. You can use it to do whatever you want.
function Timer() {
this.value = 0
this.updateCb = null
this.interval = null
function getTime() {
console.log(this.value)
var seconds = this.value % 60
var minutes = Math.floor(this.value / 60)
var hours = Math.floor(this.value / 3600)
var days = Math.floor(this.value / (3600 * 24))
return { days: days, hours: hours % 24, minutes: minutes % 60, seconds }
}
this.start = function (cb) {
if (cb) this.updateCb = cb
clearInterval(this.interval)
var self = this
interval = setInterval(function () {
self.value += 1
if (self.updateCb) self.updateCb(getTime.bind(self)())
}, 1000)
}
this.stop = function () {
this.clearInterval(interval)
}
this.reset = function () {
this.value = 0
clearInterval(interval)
}
}
var timer = new Timer()
timer.start(function (time) {
console.log(time)
})
You can start the timer on click of a button or whatever other event.

(Django - Javascript) Timer javascript and datetime python variable in html template

I've found a timer countdown in javascript online and it works fine...
I have to pass python variable to it but, although the result is correct, the countdown doesn't run, it shows the correct remaining time but doesn't continue to decrease (at least I refresh the page)...
These are my piece of codes:
views.py
import datetime
auction = Auction.objects.get(id=id)
endDateFormat = auction.endDate.strftime("%Y-%m-%dT%H:%M:%S")
startDateFormat = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
template.html
<script>
// Set the date we're counting down to
var countDownDate = new Date("{{endDateFormat}}").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get today's date and time
var now = new Date("{{startDateFormat}}").getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("demo").innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 1000);
</script>
Thanks to everyone!
Try this! Given a view:
def timer_page_view(request):
auction = Auction.objects.last()
context = {
'start_date': auction.start_date.strftime("%Y-%m-%dT%H:%M:%S"),
'end_date': auction.end_date.strftime("%Y-%m-%dT%H:%M:%S"),
}
return render(request, 'timer_page.html', context=context)
Your timer_page.html template could look like this:
<body>
<p>start date is {{ start_date }}</p>
<p>start date is {{ end_date }}</p>
<div id='demo'>time difference</div>
</body>
<script>
// Set the date we are counting to
var countDownDate = new Date('{{ end_date }}');
// Set the date we are counting from
var countFromDate = new Date("{{ start_date }}");
// Set inital distance in seconds
var distance = (countDownDate.getTime() - countFromDate.getTime()) / 1000;
// Set initial time difference in the DOM
var days = Math.floor((distance / (60 * 60 * 24)));
var hours = Math.floor((distance - (days * (60 * 60 * 24))) / (60 * 60));
var minutes = Math.floor((distance - ((days * (60 * 60 * 24)) + (hours * (60 * 60)))) / 60);
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById("demo").innerHTML = days + ' ' + hours + ' ' + minutes + ' ' + seconds;
// Timer
let active = true;
startTimer = () => {
if (active) {
var timer = document.getElementById("demo").innerHTML;
let nums = timer.split(" ").map(num => parseInt(num))
let day = nums[0];
let hour = nums[1];
let min = nums[2];
let sec = nums[3];
if (sec == 0) {
if (min == 0) {
hour--;
min = 59;
if (hour == 0){
day--;
hour = 23;
}
if (hour < 10) hour = "0" + hour;
} else {
min--;
}
if (min < 10) min = "0" + min;
sec = 59;
} else {
sec--;
console.log(sec)
if (sec < 10) sec = "0" + sec;
}
document.getElementById("demo").innerHTML = day + ' ' + hour + ' ' + min + ' ' + sec;
setTimeout(startTimer, 1000);
}
}
startTimer();
</script>
The timer would start immediately here, but you can play around with that to your liking.

JS coutdown times not show

In my site page I have a simple countdown timer:
{{ $tournaments->end }} is parsed information from MySQL, like this: 2020-07-27 03:17:36 and in MySQL field with time has timestamp format.
At my view blade i use:
function create_target_date() {
var target_date = new Date(`2020-07-27 03:17:36`) // {{$tournaments -> end}}
//target_date.setDate(target_date.getDate()+1);
target_date.setHours(23, 59, 59);
return target_date;
}
function calculation_timer() {
var target_date = create_target_date();
var current_date = new Date();
val_timer = target_date.getTime() - current_date.getTime();
var hours = Math.floor(val_timer / 1000 / 60 / 60);
var minutes = Math.floor((val_timer - hours * 60 * 60 * 1000) / 1000 / 60);
var seconds = Math.floor(((val_timer - hours * 60 * 60 * 1000) - minutes * 60 * 1000) / 1000);
document.getElementById('hours').innerHTML = hours;
document.getElementById('minutes').innerHTML = minutes;
document.getElementById('seconds').innerHTML = seconds;
}
function start_timer() {
calculation_timer();
id_timer = setInterval(calculation_timer, 1000);
}
<body onload='start_timer();'>
(<span id='hours'></span><span id='hours_legend'></span>:<span id='minutes'></span><span id='minutes_legend'>:</span><span id='seconds'></span><span id='seconds_legend'></span>)
</span>
</span>
</body>
But nothing don't show, at my page timer doesn't want to show.
If see the source code, it says Uncaught SyntaxError: missing ) after argument list at line var target_date = new Date({{ $tournaments->end }}); and another error start_timer is not defined but i have start_timer() function.
And if see the page source code, it show:
function create_target_date()
{
var target_date = new Date(2020-07-27 03:17:36);
//target_date.setDate(target_date.getDate()+1);
target_date.setHours(23,59,59);
return target_date;
}
I mean date parse sucessful. How i can make the timer show, where is my mistake?
You needed quotes. Here is a slicker version
const pad = num => ("0" + num).slice(-2);
window.addEventListener("load", function() {
const target_date = new Date(`2020-07-27 03:17:36`) // `{{$tournaments -> end}}`
target_date.setHours(23, 59, 59);
const output = document.getElementById("time");
const id_timer = setInterval(function() {
const current_date = new Date();
const diff = target_date.getTime() - current_date.getTime();
const hours = Math.floor(diff / 1000 / 60 / 60);
const minutes = Math.floor((diff - hours * 60 * 60 * 1000) / 1000 / 60);
const seconds = Math.floor(((diff - hours * 60 * 60 * 1000) - minutes * 60 * 1000) / 1000);
time.innerHTML = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`
}, 1000);
})
<span id="time"></span>

Countdown timer not working in Safari

I have a countdown timer that is working prefect in chrome, however when I view in safari it shows NAN for all the numbers and also if I set the date in the past it will not trigger my model in the else statement. I have looked all over the net for a solution but have found none.
$(document).ready(function() {
$('#popupTimer').delay(1000).fadeIn(600);
// Set the date we're counting down to (*** Set to Apr 9th after testing ***)
var countDownDate = new Date("Apr 3, 2017 24:00:00").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="display"
document.getElementById("display").innerHTML = days + " Days " + hours + " Hours " + minutes + " Minutes " + seconds + " Seconds ";
// If the count down is finished,
if (distance < 0) {
clearInterval(x);
document.getElementById("display").innerHTML = "EXPIRED";
$('#myModal').modal('show');
$(".myDIV").hide();
$('#chooseProductThree').show();
$(".panel-heading").addClass("active-panel");
}
}, 1000);
});
first write below function
function parseDateString (dateString) {
var matchers = [];
matchers.push(/^[0-9]*$/.source);
matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
matchers = new RegExp(matchers.join("|"));
if (dateString instanceof Date) {
return dateString;
}
if (String(dateString).match(matchers)) {
if (String(dateString).match(/^[0-9]*$/)) {
dateString = Number(dateString);
}
if (String(dateString).match(/\-/)) {
dateString = String(dateString).replace(/\-/g, "/");
}
return new Date(dateString);
} else {
throw new Error("Couldn't cast `" + dateString + "` to a date object.");
}
}
↓ ↓ ↓ ↓ ↓ then call this function like below ↓ ↓ ↓ ↓ ↓
var EndTime = "2019-05-10 00:00:00";
countDownDate=Date.parse(_self.parseDateString(EndTime));
I had the same issue and here is what I solved it with:
<script type="text/javascript">
const second = 1000;
const minute = second * 60;
const hour = minute * 60;
const day = hour * 24;
// Have to split time funny for IOS and Safari NAN and timezone bug
var timeParsed = '{{ $startTime }}'.replace(' ', 'T').split(/[^0-9]/);
var countDown = new Date(new Date (timeParsed[0],timeParsed[1]-1,timeParsed[2],timeParsed[3],timeParsed[4],timeParsed[5])).getTime();
let x = setInterval(function() {
let now = new Date().getTime();
let distance = countDown - now;
if(Math.floor(distance / (day)) > 0) {
document.getElementById("days_line").style.display = "inline-block";
} else {
document.getElementById("days_line").style.display = "none";
}
document.getElementById('days').innerText = Math.floor(distance / (day));
document.getElementById('hours').innerText = Math.floor((distance % (day)) / (hour));
document.getElementById('minutes').innerText = Math.floor((distance % (hour)) / (minute));
document.getElementById('seconds').innerText = Math.floor((distance % (minute)) / second);
if (distance < 0) {
clearInterval(x);
$('.counter-container').fadeOut(function() {
$('.counter-message').fadeIn();
});
} else {
$('.counter-container').fadeIn();
}
}, second)
</script>
note {{ startTime }} is not javascript but a PHP import from blade. Just put in your date there.
Have just had this issue and fixed with the following date format (note: the '/' and not a '-' separating the day, month & year...
"2019/05/10T00:00:00Z";
I assume safari cannot parse the date in this line:
var countDownDate = new Date("Apr 3, 2017 24:00:00").getTime();
Change to this:
var countDownDate = Date.parse("Apr 3, 2017 24:00:00");

How to convert time in milliseconds to hours, min, sec format in JavaScript?

I have a time as a number of milliseconds and I want to convert it to a HH:MM:SS format. It should wrap around, with milliseconds = 86400000 I want to get 00:00:00.
How about creating a function like this:
function msToTime(duration) {
var milliseconds = Math.floor((duration % 1000) / 100),
seconds = Math.floor((duration / 1000) % 60),
minutes = Math.floor((duration / (1000 * 60)) % 60),
hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return hours + ":" + minutes + ":" + seconds + "." + milliseconds;
}
console.log(msToTime(300000))
To Convert time in millisecond to human readable format.
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(1000))
console.log(msToTime(10000))
console.log(msToTime(300000))
console.log(msToTime(3600000))
console.log(msToTime(86400000))
I had the same problem, this is what I ended up doing:
function parseMillisecondsIntoReadableTime(milliseconds){
//Get hours from milliseconds
var hours = milliseconds / (1000*60*60);
var absoluteHours = Math.floor(hours);
var h = absoluteHours > 9 ? absoluteHours : '0' + absoluteHours;
//Get remainder from hours and convert to minutes
var minutes = (hours - absoluteHours) * 60;
var absoluteMinutes = Math.floor(minutes);
var m = absoluteMinutes > 9 ? absoluteMinutes : '0' + absoluteMinutes;
//Get remainder from minutes and convert to seconds
var seconds = (minutes - absoluteMinutes) * 60;
var absoluteSeconds = Math.floor(seconds);
var s = absoluteSeconds > 9 ? absoluteSeconds : '0' + absoluteSeconds;
return h + ':' + m + ':' + s;
}
var time = parseMillisecondsIntoReadableTime(86400000);
alert(time);
Here is my solution
let h,m,s;
h = Math.floor(timeInMiliseconds/1000/60/60);
m = Math.floor((timeInMiliseconds/1000/60/60 - h)*60);
s = Math.floor(((timeInMiliseconds/1000/60/60 - h)*60 - m)*60);
// to get time format 00:00:00
s < 10 ? s = `0${s}`: s = `${s}`
m < 10 ? m = `0${m}`: m = `${m}`
h < 10 ? h = `0${h}`: h = `${h}`
console.log(`${s}:${m}:${h}`);
This one returns time like youtube videos
function getYoutubeLikeToDisplay(millisec) {
var seconds = (millisec / 1000).toFixed(0);
var minutes = Math.floor(seconds / 60);
var hours = "";
if (minutes > 59) {
hours = Math.floor(minutes / 60);
hours = (hours >= 10) ? hours : "0" + hours;
minutes = minutes - (hours * 60);
minutes = (minutes >= 10) ? minutes : "0" + minutes;
}
seconds = Math.floor(seconds % 60);
seconds = (seconds >= 10) ? seconds : "0" + seconds;
if (hours != "") {
return hours + ":" + minutes + ":" + seconds;
}
return minutes + ":" + seconds;
}
Output:
getYoutubeLikeToDisplay(129900) = "2:10"
getYoutubeLikeToDisplay(1229900) = "20:30"
getYoutubeLikeToDisplay(21229900) = "05:53:50"
Sorry, late to the party. The accepted answer did not cut it for me, so I wrote it myself.
Output:
2h 59s
1h 59m
1h
1h 59s
59m 59s
59s
Code (Typescript):
function timeConversion(duration: number) {
const portions: string[] = [];
const msInHour = 1000 * 60 * 60;
const hours = Math.trunc(duration / msInHour);
if (hours > 0) {
portions.push(hours + 'h');
duration = duration - (hours * msInHour);
}
const msInMinute = 1000 * 60;
const minutes = Math.trunc(duration / msInMinute);
if (minutes > 0) {
portions.push(minutes + 'm');
duration = duration - (minutes * msInMinute);
}
const seconds = Math.trunc(duration / 1000);
if (seconds > 0) {
portions.push(seconds + 's');
}
return portions.join(' ');
}
console.log(timeConversion((60 * 60 * 1000) + (59 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion((60 * 60 * 1000) + (59 * 60 * 1000) ));
console.log(timeConversion((60 * 60 * 1000) ));
console.log(timeConversion((60 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion( (59 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion( (59 * 1000)));
The above snippets don't work for cases with more than 1 day (They are simply ignored).
For this you can use:
function convertMS(ms) {
var d, h, m, s;
s = Math.floor(ms / 1000);
m = Math.floor(s / 60);
s = s % 60;
h = Math.floor(m / 60);
m = m % 60;
d = Math.floor(h / 24);
h = h % 24;
h += d * 24;
return h + ':' + m + ':' + s;
}
Thanks to https://gist.github.com/remino/1563878
I needed time only up to one day, 24h, this was my take:
const milliseconds = 5680000;
const hours = `0${new Date(milliseconds).getHours() - 1}`.slice(-2);
const minutes = `0${new Date(milliseconds).getMinutes()}`.slice(-2);
const seconds = `0${new Date(milliseconds).getSeconds()}`.slice(-2);
const time = `${hours}:${minutes}:${seconds}`
console.log(time);
you could get days this way as well if needed.
Format as hh:mm:ss with optional padding
(1:59:59 or 01:59:59)
(1:59 or 01:59)
(Default: no padding)
Based loosely on Chand's answer.
function formatMilliseconds(milliseconds, padStart) {
function pad(num) {
return `${num}`.padStart(2, '0');
}
let asSeconds = milliseconds / 1000;
let hours = undefined;
let minutes = Math.floor(asSeconds / 60);
let seconds = Math.floor(asSeconds % 60);
if (minutes > 59) {
hours = Math.floor(minutes / 60);
minutes %= 60;
}
return hours
? `${padStart ? pad(hours) : hours}:${pad(minutes)}:${pad(seconds)}`
: `${padStart ? pad(minutes) : minutes}:${pad(seconds)}`;
}
Tests:
let s = 1000;
let m = 60*s;
let h = 60*m;
console.log(formatMilliseconds(1*h)); // 1:00:00
console.log(formatMilliseconds(1*h, true)); // 01:00:00
console.log(formatMilliseconds(59*m + 59*s)); // 59:59
console.log(formatMilliseconds(59*m + 59*s, true)); // 59:59
console.log(formatMilliseconds(9*m + 9*s)); // 9:09
console.log(formatMilliseconds(9*m + 9*s, true)); // 09:09
console.log(formatMilliseconds(5*s)); // 0:05
console.log(formatMilliseconds(5*s, true)); // 00:05
console.log(formatMilliseconds(2400*s)); // 40:00
console.log(formatMilliseconds(2400*s, true)); // 40:00
.
.
.
If you need millisecond precision, you can get the fractional part using the following:
(asSeconds % 1).toFixed(3).substring(1)
Your returns would end up looking like this (break it up for readability as necessary):
`${padStart ? pad(hours) : hours}:${pad(minutes)}:${pad(seconds)}${(asSeconds % 1).toFixed(3).substring(1)}`
There are probably better ways to do that, but this naive solution gets the job done.
Test:
let asSeconds = 59.5219;
let seconds = Math.floor(asSeconds);
console.log(`${pad(seconds)}${(asSeconds % 1).toFixed(3).substring(1)}`);
// Equivalent to above, without using `pad()`:
//console.log(`${String(seconds).padStart(2, '0')}${(asSeconds % 1).toFixed(3).substring(1)}`);
// Output: 59.522
// The following is written in Typescript, should be easy to translate to JS
function humanReadableDuration(msDuration: int): string {
const h = Math.floor(msDuration / 1000 / 60 / 60);
const m = Math.floor((msDuration / 1000 / 60 / 60 - h) * 60);
const s = Math.floor(((msDuration / 1000 / 60 / 60 - h) * 60 - m) * 60);
// To get time format 00:00:00
const seconds: string = s < 10 ? `0${s}` : `${s}`;
const minutes: string = m < 10 ? `0${m}` : `${m}`;
const hours: string = h < 10 ? `0${h}` : `${h}`;
return `${hours}h ${minutes}m ${seconds}s`;
}
This solution uses one function to split milliseconds into a parts object, and another function to format the parts object.
I created 2 format functions, one as you requested, and another that prints a friendly string and considering singular/plural, and includes an option to show milliseconds.
function parseDuration(duration) {
let remain = duration
let days = Math.floor(remain / (1000 * 60 * 60 * 24))
remain = remain % (1000 * 60 * 60 * 24)
let hours = Math.floor(remain / (1000 * 60 * 60))
remain = remain % (1000 * 60 * 60)
let minutes = Math.floor(remain / (1000 * 60))
remain = remain % (1000 * 60)
let seconds = Math.floor(remain / (1000))
remain = remain % (1000)
let milliseconds = remain
return {
days,
hours,
minutes,
seconds,
milliseconds
};
}
function formatTime(o, useMilli = false) {
let parts = []
if (o.days) {
let ret = o.days + ' day'
if (o.days !== 1) {
ret += 's'
}
parts.push(ret)
}
if (o.hours) {
let ret = o.hours + ' hour'
if (o.hours !== 1) {
ret += 's'
}
parts.push(ret)
}
if (o.minutes) {
let ret = o.minutes + ' minute'
if (o.minutes !== 1) {
ret += 's'
}
parts.push(ret)
}
if (o.seconds) {
let ret = o.seconds + ' second'
if (o.seconds !== 1) {
ret += 's'
}
parts.push(ret)
}
if (useMilli && o.milliseconds) {
let ret = o.milliseconds + ' millisecond'
if (o.milliseconds !== 1) {
ret += 's'
}
parts.push(ret)
}
if (parts.length === 0) {
return 'instantly'
} else {
return parts.join(' ')
}
}
function formatTimeHMS(o) {
let hours = o.hours.toString()
if (hours.length === 1) hours = '0' + hours
let minutes = o.minutes.toString()
if (minutes.length === 1) minutes = '0' + minutes
let seconds = o.seconds.toString()
if (seconds.length === 1) seconds = '0' + seconds
return hours + ":" + minutes + ":" + seconds
}
function formatDurationHMS(duration) {
let time = parseDuration(duration)
return formatTimeHMS(time)
}
function formatDuration(duration, useMilli = false) {
let time = parseDuration(duration)
return formatTime(time, useMilli)
}
console.log(formatDurationHMS(57742343234))
console.log(formatDuration(57742343234))
console.log(formatDuration(5423401000))
console.log(formatDuration(500))
console.log(formatDuration(500, true))
console.log(formatDuration(1000 * 30))
console.log(formatDuration(1000 * 60 * 30))
console.log(formatDuration(1000 * 60 * 60 * 12))
console.log(formatDuration(1000 * 60 * 60 * 1))
Worked for me
msToTime(milliseconds) {
//Get hours from milliseconds
var hours = milliseconds / (1000*60*60);
var absoluteHours = Math.floor(hours);
var h = absoluteHours > 9 ? absoluteHours : '0' + absoluteHours;
//Get remainder from hours and convert to minutes
var minutes = (hours - absoluteHours) * 60;
var absoluteMinutes = Math.floor(minutes);
var m = absoluteMinutes > 9 ? absoluteMinutes : '0' + absoluteMinutes;
//Get remainder from minutes and convert to seconds
var seconds = (minutes - absoluteMinutes) * 60;
var absoluteSeconds = Math.floor(seconds);
var s = absoluteSeconds > 9 ? absoluteSeconds : '0' + absoluteSeconds;
return h == "00" ? m + ':' + s : h + ':' + m + ':' + s;
}
Human-readable code for human-readable output and you can extend this to light years or nanoseconds or what have you very intuitively. Obviously you'd want to convert this to a function and re-use some of those intermediate modulo calls.
second = 1000
minute = second * 60
hour = minute * 60
day = hour * 24
test = 3 * day + 2 * hour + 11 * minute + 58 * second
console.log(Math.floor(test / day))
console.log(Math.floor(test % day / hour))
console.log(Math.floor(test % day % hour / minute))
console.log(Math.floor(test % day % hour % minute / second))
Extending on #Rick's answer, I prefer something like this:
function msToReadableTime(time){
const second = 1000;
const minute = second * 60;
const hour = minute * 60;
let hours = Math.floor(time / hour % 24);
let minutes = Math.floor(time / minute % 60);
let seconds = Math.floor(time / second % 60);
return hours + ':' + minutes + ":" + seconds;
}
Based on #Chand answer. This is the implementation in Typescript. A bit safer than coercing types in JS. If you remove the type annotation should be valid JS. Also using new string functions to normalise the time.
function displayTime(millisec: number) {
const normalizeTime = (time: string): string => (time.length === 1) ? time.padStart(2, '0') : time;
let seconds: string = (millisec / 1000).toFixed(0);
let minutes: string = Math.floor(parseInt(seconds) / 60).toString();
let hours: string = '';
if (parseInt(minutes) > 59) {
hours = normalizeTime(Math.floor(parseInt(minutes) / 60).toString());
minutes = normalizeTime((parseInt(minutes) - (parseInt(hours) * 60)).toString());
}
seconds = normalizeTime(Math.floor(parseInt(seconds) % 60).toString());
if (hours !== '') {
return `${hours}:${minutes}:${seconds}`;
}
return `${minutes}:${seconds}`;
}
I recently ran into this situation. My focus was on clean readability and reusability.
Use
(See function definition below)
timeUnits(86400000) // {days: 1, hours: 0, minutes: 0, seconds: 0, ms: 0}
Then you can use the data to do whatever you want (like build a string).
Other examples:
timeUnits(214870123) // {days: 2, hours: 11, minutes: 41, seconds: 10, ms: 123}
timeUnits('70123') // null
Function
/**
* Converts milliseconds into greater time units as possible
* #param {int} ms - Amount of time measured in milliseconds
* #return {?Object} Reallocated time units. NULL on failure.
*/
function timeUnits( ms ) {
if ( !Number.isInteger(ms) ) {
return null
}
/**
* Takes as many whole units from the time pool (ms) as possible
* #param {int} msUnit - Size of a single unit in milliseconds
* #return {int} Number of units taken from the time pool
*/
const allocate = msUnit => {
const units = Math.trunc(ms / msUnit)
ms -= units * msUnit
return units
}
// Property order is important here.
// These arguments are the respective units in ms.
return {
// weeks: allocate(604800000), // Uncomment for weeks
days: allocate(86400000),
hours: allocate(3600000),
minutes: allocate(60000),
seconds: allocate(1000),
ms: ms // remainder
}
}
It's written in such a way so that you can easily implement other units (for example, where I commented out implementation for weeks) so long as you know their worth in milliseconds.
my solution
var sunriseMills = 1517573074000; // sunrise in NewYork on Feb 3, 2018 - UTC time
var offsetCityMills = -5 * 3600 * 1000; // NewYork delay to UTC
var offsetDeviceMills = new Date().getTimezoneOffset() * 60 * 1000 ; // eg. I live in Romania (UTC+2) >> getTimezoneOffset() = 120
var textTime = new Date(sunriseMills + offsetCityMills + offsetDeviceMills)
.toLocaleTimeString('en-US', { hour: 'numeric', minute: 'numeric' });
textTime will become '7.04 AM'
A Date object can be constructed from milliseconds:
const date = new Date(0, 0, 0, 0, 0, 0, milliseconds);
In your question you say milliseconds seconds should 'wrap around' at 86400000. Since we know there are 86400000 milliseconds in a day, we can simply take the time from the date object, and ignore every other part of the date as irrelevant.
The time can then be obtained in any number of formats. The one you require matches that used in the United Kingdom, locale en-GB:
const hms = d.toLocaleTimeString('en-GB');
If you're using typescript, this could be a good thing for you
enum ETime {
Seconds = 1000,
Minutes = 60000,
Hours = 3600000,
SecInMin = 60,
MinInHours = 60,
HoursMod = 24,
timeMin = 10,
}
interface ITime {
millis: number
modulo: number
}
const Times = {
seconds: {
millis: ETime.Seconds,
modulo: ETime.SecInMin,
},
minutes: {
millis: ETime.Minutes,
modulo: ETime.MinInHours,
},
hours: {
millis: ETime.Hours,
modulo: ETime.HoursMod,
},
}
const dots: string = ":"
const msToTime = (duration: number, needHours: boolean = true): string => {
const getCorrectTime = (divider: ITime): string => {
const timeStr: number = Math.floor(
(duration / divider.millis) % divider.modulo,
)
return timeStr < ETime.timeMin ? "0" + timeStr : String(timeStr)
}
return (
(needHours ? getCorrectTime(Times.hours) + dots : "") +
getCorrectTime(Times.minutes) +
dots +
getCorrectTime(Times.seconds)
)
}
In my implementation I used Moment.js:
export default (value) =>
const duration = moment.duration(value);
const milliseconds = duration.milliseconds();
const seconds = duration.seconds();
const minutes = duration.minutes();
const hours = duration.hours();
const day = duration.days();
const sDay = `${day}d `;
const sHours = (hours < 10) ? `0${hours}h ` : `${hours}h `;
const sMinutes = (minutes < 10) ? `0${minutes}' ` : `${minutes}' `;
const sSeconds = (seconds < 10) ? `0${seconds}" ` : `${seconds}" `;
const sMilliseconds = `${milliseconds}ms`;
...
}
Once got the strings, I composed them as I want.
I works for me as i get milliseconds=1592380675409 using javascript method getTime() which returns the number of milliseconds between midnight of January 1, 1970 and the specified date.
var d = new Date();//Wed Jun 17 2020 13:27:55 GMT+0530 (India Standard Time)
var n = d.getTime();//1592380675409 this value is store somewhere
//function call
console.log(convertMillisecToHrMinSec(1592380675409));
var convertMillisecToHrMinSec = (time) => {
let date = new Date(time);
let hr = date.getHours();
let min = date.getMinutes();
let sec = date.getSeconds();
hr = (hr < 10) ? "0"+ hr : hr;
min = (min < 10) ? "0"+ min : min;
sec = (sec < 10) ? "0"+ sec : sec;
return hr + ':' + min + ":" + sec;//01:27:55
}
A refactor from #dusht to ES6+ and more functional:
const addPrefix = time => time < 10 ? '0' + time : time;
const toHours = time => addPrefix(Math.floor((time / (1000 * 60 * 60)) % 24));
const toMinutes = time => addPrefix(Math.floor((time / (1000 * 60)) % 60));
const toSeconds = (ime => addPrefix(Math.floor((time / 1000) % 60));
const toMiliseconds = time => Math.floor((time % 1000) / 100);
const milisecondToHoursAndMinute = time => {
const hours = toHours(time);
const minutes = toMinutes(time);
const seconds = toSeconds(time);
const miliseconds = toMiliseconds(time);
return `${hours}:${minutes}:${seconds}.${miliseconds}`
}
let dateTimeStr = new Date(1949778000);
dateTimeStr = Math.floor(dateTimeStr/86400000) +' days '+ dateTimeStr.getHours() +' hours '+ dateTimeStr.getMinutes() +' minutes '+ dateTimeStr.getSeconds() +' seconds';
console.log(dateTimeStr);
You don't have to calculate the days if you don't need them
"22 days 16 hours 36 minutes 18 seconds"
I don't see the need for complication in all these answers, it's easy to add zeros by adding a power of 10:
function timeToString(t) {
const value =
((t / 3600_000 % 24) | 0) * 10000 +
((t / 60_000 % 60) | 0) * 100 +
((t / 1_000 % 60) | 0);
return (1000000 + value).toString().replace(/1(..)(..)(..)/, '$1:$2:$3');
}
If anyone still need here's a modified version of one of the code snippets posted above in js by https://stackoverflow.com/a/58826445/20067539
function timeConversion(duration) {
var portions = [];
var msInDay = 1000 * 60 * 60 * 24
var days = Math.trunc(duration / msInDay);
if (days > 0 ) {
portions.push(days + (days === 1 ? " day" : " days"))
duration = duration - (days * msInDay)
}
var msInHour = 1000 * 60 * 60;
var hours = Math.trunc(duration / msInHour);
if (hours > 0) {
portions.push(hours + (hours === 1 ? ' hour' : ' hours'));
duration = duration - (hours * msInHour);
}
var msInMinute = 1000 * 60;
var minutes = Math.trunc(duration / msInMinute);
if (minutes > 0) {
portions.push(minutes + (minutes === 1 ? ' minute' : ' minutes'));
duration = duration - (minutes * msInMinute);
}
var seconds = Math.trunc(duration / 1000);
if (seconds > 0) {
portions.push(seconds + (seconds === 1 ? ' second' : ' seconds'));
}
return portions.join(' ');
}
console.log(timeConversion((60 * 60 * 1000) + (59 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion((60 * 60 * 1000) + (59 * 60 * 1000)));
console.log(timeConversion((60 * 60 * 1000)));
console.log(timeConversion((60 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion((59 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion((59 * 1000)));

Categories