Reputation: 49
I have this code that keeps the time between command !start
and !end
for a time counter command but I want it to send like "Your time was 14:23:02 (hours, minutes, seconds) and the whole time spent is 27:24:32 (hours, minutes, seconds)"
Here is my code:
/**
* A map from user IDs to start timestamps
* @type Map<string, number>
*/
const startTimestamps = new Map()
/**
* Pads a number to 2 digits.
* @param {number} value
* @returns {string}
*/
const pad2Digits = value => String(value).padStart(2, '0')
bot.on('message', async message => {
try {
if (message.content === '!start') {
// Sets the start time. This overrides any existing timers
// Date.now() is equivalent to new Date().getTime()
startTimestamps.set(message.author.id, Date.now())
await message.reply('Timer started.')
} else if (message.content === '!end') {
if (startTimestamps.has(message.author.id)) {
// The user has an existing timer to stop
// Calculate the timer result
const ms = Date.now() - startTimestamps.get(message.author.id)
const totalSecs = Math.floor(ms / 1000)
const totalMins = Math.floor(totalSecs / 60)
const hrs = Math.floor(totalMins / 60)
const mins = totalMins % 60
const secs = totalSecs % 60
// Reply with result
await message.reply(`Your time: ${hrs}:${pad2Digits(mins)}:${pad2Digits(secs)}`)
// Remove timestamp from map
startTimestamps.delete(message.author.id)
} else {
// The user does not have an existing timer
await message.reply('You need to use `!start` first!')
}
}
} catch (error) {
console.error(error)
}
})
Upvotes: 1
Views: 149
Reputation: 23161
If you're using a simple Map to store these timers, you'll lost them every time you restart the bot. You'll need to use some kind of database (preferred) or a JSON file.
If I can understand it correctly, you want to show the time spent in the last session and the total the user spent in different sessions. You can store an array of starting and ending times like this:
/**
* A map from user IDs to start timestamps
* @type Map<string, number>
*/
const timestamps = new Map();
/**
* Pads a number to 2 digits.
* @param {number} value
* @returns {string}
*/
const pad2Digits = (value) => String(value).padStart(2, '0');
/**
* Counts the total number of milliseconds of timers.
* @param {array} timers
* @returns {number}
*/
const countTotalMs = (timers) =>
timers.reduce((acc, curr) => (curr.end ? acc + curr.end - curr.start : acc), 0);
/**
* Converts milliseconds to hours, minutes, and seconds
* @param {number} ms
* @returns {object}
*/
const getTime = (ms) => {
const totalSecs = Math.floor(ms / 1000);
const totalMins = Math.floor(totalSecs / 60);
const hrs = Math.floor(totalMins / 60);
const mins = totalMins % 60;
const secs = totalSecs % 60;
const formatted = `${hrs}:${pad2Digits(mins)}:${pad2Digits(secs)}`;
return { formatted, hrs, mins, secs };
};
client.on('message', async (message) => {
try {
if (message.content === '!start') {
const timers = timestamps.get(message.author.id) || [];
const lastTimer = timers[timers.length - 1];
// Check if the previous one is finished
if (lastTimer && !lastTimer.end) {
return message.reply(
'You need to finish your previous timer first. Use `!end`!',
);
}
timestamps.set(message.author.id, [
...timers,
{ start: Date.now(), end: null },
]);
return message.reply('Timer started.');
}
if (message.content === '!end') {
const timers = timestamps.get(message.author.id);
// The user does not have an existing timer
if (!timers) {
return message.reply('You need to use `!start` first!');
}
const lastTimer = timers[timers.length - 1];
// If the last timer is already finished
if (lastTimer.end) {
return message.reply('You need to use `!start` first!');
}
const currentTime = getTime(Date.now() - lastTimer.start);
lastTimer.end = Date.now();
const totalTimeInMs = countTotalMs(timers);
const totalTime = getTime(totalTimeInMs);
timestamps.set(message.author.id, timers);
return message.reply(
`Your time: ${currentTime.formatted}. Total time: ${totalTime.formatted}`,
);
}
if (message.content.startsWith('!hours')) {
const member = message.mentions.members.first() || message.author;
if (!member) {
return message.channel.send('You need to mention someone');
}
const timers = timestamps.get(member.id) || [];
const totalTimeInMs = countTotalMs(timers);
const totalTime = getTime(totalTimeInMs);
return message.channel.send(
`Total time of ${member}: ${totalTime.formatted}`,
);
}
} catch (error) {
console.error(error);
}
});
Upvotes: 1