Writing a command in djs that should display my uptime. When i run it, it displays the total number of seconds, minutes, hours, etc, but it doesn't limit seconds and minutes to seconds, or hours to 24.
const seconds = Math.floor(message.client.uptime / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if(command === "uptime") {
message.channel.send(`The bot has been up for` + ` ` + `${days} days,` + ` ` + `${hours} hours,` + ` ` + `${minutes} minutes` + ` ` + `${seconds} seconds.`)
return;
}
Why would division limit numbers? 5678000 / 1000 will always give 5678. What you want to do is modulo (%) instead of division (/).
const seconds = message.client.uptime % 1000;
const minutes = Math.floor((message.client.uptime / 1000)) % 60;
const hours = Math.floor((message.client.uptime / (60 * 1000))) % 60;
const days = Math.floor(message.client.uptime / (60 * 1000 * 60 * 24));
if(command === "uptime") {
message.channel.send(`The bot has been up for` + ` ` + `${days} days,` + ` ` + `${hours} hours,` + ` ` + `${minutes} minutes` + ` ` + `${seconds} seconds.`)
return;
}
There is a better solution, though. Convert number to Date format, and use it to directly get minutes, hours, days, etc. - the only downside of it is it gives day of the month, not the days passed since JS Epoch time, hence (unless there is an even cleaner solution I am not aware of) you need to initialize one more variable.
Also, why concatenate strings, if you can simply pass a single string with params?
Anyway, here is my solution to your problem:
var uptime = new Date(message.client.uptime);
const days = Math.floor(message.client.uptime / (60 * 1000 * 60 * 24));
if(command === "uptime") {
message.channel.send(`The bot has been up for ${days} days, ${uptime.getHours()} hours, ${uptime.getMinutes()} minutes ${uptime.getSeconds()} seconds.`)
return;
}
Related
I have some code that simulates a timer that will look at the start time, store that into localStorage and compare that to Date.now() and will correctly simulate a working timer by updating a state variable that increments on a setInterval every 1 second. It works well even after page reload.
Naturally the timer counts up in milliseconds, so i wrote a function that formats the time into hours:minutes:seconds. The issue now is that the counter, which was updating in real time when unformatted, now that it goes into a function to format, what is returned is correctly formatted but does not increment in real time, i suspect something to do with function not being called again even though the state is being incremented every second.
My question would be is there a way to call the function every time the state changes like a useEffect? Maybe a custom hook?
Here's my code:
const date = new Date()
const [time, setTime] = useState(date.getTime())
//starts timer on button click
function startTimer() {
setStart(true)
localStorage.setItem('startTime', date.getTime())
}
//converts ms time into hours:minutes:seconds
function msToTime(duration) {
let 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
}
//the interval that updates time state every second
useEffect(() => {
const timer = setInterval(() => {
setTime(prev => prev+1)
},1000)
return () => {
clearInterval(timer)
}
},[time])
//return the difference between start and time state and formats it
return <h3>{msToTime(Math.abs(+localStorage.getItem('startTime') - time))}</h3>
Everything is fine in your code except that you have overseen one compatibility issue. In your setTime function, the prev argument is in milliseconds, but you're adding only one millisecond to it every second. Change it to the following:
setTime(prev => prev + 1000)
You can also use:
setTime(date.getTime())
I want to count how many hours and minutes between two timestamp which are generated by Date.parse. After I get the difference, I need to convert it into hours and minutes like 2.10 (means, 2 hours and 10 minutes). Once I have read that to do it you need to divide it with 3600 so I tried this code but it just gives me 0.89 instead of 1.26.
var now = new Date();
var endTime = Date.parse(now)/1000;
var startTime = Date.parse("2018-03-16 10:29:17")/1000;
$scope.timestamp_difference = startTime - endTime;
$scope.hours = $scope.timestamp_difference/3600;
How to do it right?
In case you haven't heard, Momentjs makes working with dates and times pretty damn easy in javascript i updated code for you may hope it will helps you now
var date1 = moment('03/15/2018 11:00', 'MM/DD/YYYY hh:mm'),
date2 = moment('03/16/2018 10:00', 'MM/DD/YYYY hh:mm');
var duration = moment.duration(date2.diff(date1));
//you will get 23 hours 00 minute
alert(duration.asHours().toFixed(2))
http://jsfiddle.net/dp7rzmw5/9771/
Output: 23:00 hrs
function getTimeDifference(timestampDifference) {
var hours = ~~(timestampDifference / 3600);
var minuts = ~~((timestampDifference - hours * 3600) / 60);
var seconds = timestampDifference - hours * 3600 - minuts * 60;
return hours + '.' + minuts + '.' + seconds;
}
var minutes = "0" + Math.floor(timestampDifference / 60);
// get minutes
var seconds = "0" + Math.floor(timestampDifference - minutes * 60);
// get seconds
var hour = "0" + Math.floor(timestampDifference / 3600);
//get hour
if ( hour > 1 ) {
return hour.substr(-2) + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
} else {
return minutes.substr(-2) + ":" + seconds.substr(-2);
}
// check if the hour is greater then 1 than return time with hour else return minutes.
I'd like to start by stating I have very little experience with Angular as this is the first project I've worked on that uses it.
Within the controller I make an AJAX call which returns a json. One of the json objects is minutes in the following format: 1385
I'd like to convert this number into something like this: 8d 15h 0m using an Angular filter
Im wondering how this would be possible?
Answer
Yes. It is 100% possible. Create a filter like below and add your specific date calculation
inside the filter.
How to do the date calculation:
In terms of the actual date calculation, it will be nothing more than regular JavaScript logic. Here you have a few options:
The native Date() object will expose various .getSomething()
functions
MomentJS is also good, as its a library designed for these things specifically
Manual calculation
If you'd like to know how to do this manually. Conceptually the calculation is something like below... the idea is, a rolling calculation where you get the higher time unit, then keep subtracting it from the next calculation, carrying the leftover time along.
Input = Original Minute value
Days = Input / 60 [mins in an hour] / 24 [total hours in day]
Hours = Leftover / 60 [mins in an hour]
Mins = Leftover
A quick search on SO yielded this solution for a custom calculation of sorts. I used the linked calculation on my sample below.
Example
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {})
.filter('myDateFilter', ['$filter',
function($filter) {
return function(input) {
// set minutes to seconds
var seconds = input * 60
// calculate (and subtract) whole days
var days = Math.floor(seconds / 86400);
seconds -= days * 86400;
// calculate (and subtract) whole hours
var hours = Math.floor(seconds / 3600) % 24;
seconds -= hours * 3600;
// calculate (and subtract) whole minutes
var minutes = Math.floor(seconds / 60) % 60;
return days + 'd ' + hours + 'h ' + minutes + 'm ';
}
}
]);
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl">
1385 minutes = {{ 1385 | myDateFilter }}
</body>
</html>
I suggest a slightly shorter version as an alternative, that uses new Date() object and gets its components individually with predefined methods. It works the same way and uses less computations.
Here is a demo:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {});
app.filter('myDateFilter', ['$filter',
function($filter) {
return function(input) {
var inp = new Date(0, 0, 0, 0, input, 0); // assumes minutes as an input
var m = inp.getMinutes();
var h = inp.getHours();
var d = inp.getDay();
return d + 'd ' + h + 'h ' + m + 'm ';
}
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl">
1385 minutes = {{ 1385 | myDateFilter }}
</div>
Here is a pipe you can copy/paste for angular 6+. I made it a bit more robust too:
import { Pipe, PipeTransform } from '#angular/core';
/**
* Format a value in minutes as [x(d| days)] y(h| hours) z(m| minutes)
*
* Usage:
* value | hoursMinutes // 0d 3h 20m
* value | hoursMinutes: 'long':false // 3 hours 20 minutes
*/
#Pipe({
name: 'hoursMinutes'
})
export class HoursMinutesPipe implements PipeTransform {
transform(minutes: number, format = 'short', includeDays = true): any {
let formatted = '';
// set minutes to seconds
let seconds = minutes * 60;
// calculate (and subtract) whole days
let days = 0;
if (includeDays) {
days = Math.floor(seconds / 86400);
seconds -= days * 86400;
formatted = `${days}d `;
}
// calculate (and subtract) whole hours
const hours = Math.floor(seconds / 3600) % 24;
seconds -= hours * 3600;
// calculate (and subtract) whole minutes
const min = Math.floor(seconds / 60) % 60;
formatted += `${hours}h ${min}m`;
if ('long' === format) {
formatted = formatted.replace('d', ' days');
formatted = formatted.replace('h', ' hours');
formatted = formatted.replace('m', ' minutes');
}
return formatted;
}
}
I'm trying to get the difference between a datetime and a current datetime using cakephp . I succeeded to get it but I want to convert it to only hours ,minutes and seconds .
here is my code :
$currDateTime = Time::now();
$date1 = $plan->start_day->format('Y-m-d');
$date2 = $currDateTime->format('Y-m-d');
$diff = abs(strtotime($date1) - strtotime($date2));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24)) ;
$time1 = $plan->start_day->format('H:i:s');
$time2 = $currDateTime->format('H:i:s');
$seconds = abs(strtotime($time1) - strtotime($time2));
$hours = floor($seconds / 3600);
$mins = floor(($seconds - ($hours*3600)) / 60);
$secs = floor($seconds % 60);
the result is a difference in years, months, days, hours, minutes and seconds.
how can I convert it to only H:m:s ??
There's no need for all these calculations, simply create a DateInterval diff using the diff() method provided by the time object, and use the days, h, i, and s values it provides to create your desired output. The only calculation that would be required, would be to add the days in hours.
$diff = $currDateTime->diff($plan->start_day);
$formatted = sprintf('%02d:%02d:%02d', ($diff->days * 24) + $diff->h, $diff->i, $diff->s);
See also
PHP Manual > Date/Time > DateTimeInterface > DateTimeInterface::diff
PHP Manual > Date/Time > DateInterval
I have been looking through this code but cant really find any
tried to use angular filtering {{bla.bla | date:'HH:mm:ss'}}
but it doesnt work.
can anybody help me please? thanks!
filter('songTime',function(){
return function (s) {
var ms = s % 1000;
s = (s - ms) / 1000;
var secs = s % 60;
s = (s - secs) / 60;
var mins = s % 60;
var hrs = (s - mins) / 60;
return hrs + ':' + mins + ':' + secs + ':' + ms;
};
}
and use it like {{bla.bla | songTime }} . You can beautify the date inside the filter.
I just came across this question looking for an answer, but couldn't find a good solution, so I made my own filter that does this, if anyone needs it.
app.filter('formatDuration', function () {
return function (input) {
var totalHours, totalMinutes, totalSeconds, hours, minutes, seconds, result='';
totalSeconds = input / 1000;
totalMinutes = totalSeconds / 60;
totalHours = totalMinutes / 60;
seconds = Math.floor(totalSeconds) % 60;
minutes = Math.floor(totalMinutes) % 60;
hours = Math.floor(totalHours) % 60;
if (hours !== 0) {
result += hours+':';
if (minutes.toString().length == 1) {
minutes = '0'+minutes;
}
}
result += minutes+':';
if (seconds.toString().length == 1) {
seconds = '0'+seconds;
}
result += seconds;
return result;
};
});
Here's an example of it in use:
{{247000 | formatDuration}} --> Result: 4:07
{{4748000 | formatDuration}} --> Result: 1:19:08
This will work with any amount of hours, minutes, and seconds, and includes leading zeros on numbers when necessary.