Timezones on discord.js

I created a discord bot a few weeks ago. The idea for it was simple: The user would click on a button, then the bot would create a new channel for them, containing a series of questions which could be urls, select menus, numbers, etc. Once all of the questions had been answered, the bot would send them to another channel as an embed message. Easy, right? However, there was a little issue.

The problem

One of the questions required by the bot was a date and time. I had to get the message content and format it into a Discord timestamp. The code looked like this:

customParseFormat = require('dayjs/plugin/customParseFormat');
const dayjs = require("dayjs");
dayjs.extend(customParseFormat);
/*...*/
const filter = m => m.author.id === interaction.user.id && !m.author.bot;
collector = channel.createMessageCollector({ time: 60000, filter });
p = new Promise((resolve, reject) => {
collector.on("collect", m => {
if(!dayjs(m.content, "DD/MM/YYYY HH:mm").isValid()) return m.delete();
        answers.push({name: q.name, value: `<t:${dayjs(m.content, "DD/MM/YYYY HH:mm").unix()}>`});
resolve(m);
collector.stop();
m.delete();
});
});
await p;
/*...*/

The bot worked just fine to me, but when my client tested it, they got a completely different time!

As it turns out, this is because we were in different timezones. So when my client sent a date, the bot parsed it as-is, without considering time differences. Since my timezone is UTC+3 and theirs is UTC, their time would always be 3 hours different than their original input. This was of course a big problem.

The solution

Sadly, Discord.js currently doesn’t offer any way to get the user’s local time. So the only solution was to get it as an argument, and add or subtract hours depending on the bot’s local time. Fortunately, Day.js lets you parse a date using an input string, and convert the parsed date into a unix timestamp. It also lets you add or subtract from the time. Perfect!

After a little bit of testing, the code ended up like this:

customParseFormat = require('dayjs/plugin/customParseFormat');
const dayjs = require("dayjs");
dayjs.extend(customParseFormat);
/*...*/
const filter = m => m.author.id === interaction.user.id && !m.author.bot;
collector = channel.createMessageCollector({ time: 60000, filter });
p = new Promise((resolve, reject) => {
collector.on("collect", m => {
const localOffset = new Date().getTimezoneOffset() / 60;
let date = m.content.split(" ");
if(date.length !== 3) return m.delete();
const timezone = parseInt(date[date.length - 1]);

date.pop();
date = date.join(" ")
if(!dayjs(date, "DD/MM/YYYY HH:mm").isValid()) return m.delete();
answers.push({name: q.name, value: `<t:${dayjs(m.content, "DD/MM/YYYY HH:mm").add(timezone + localOffset, "h").unix()}>`});
resolve(m);
collector.stop();
m.delete();
});
});
await p;
/*...*/

Note that localOffset will be positive if the bot is on the left of UTC and negative if it is on the right.

Standard timezone map(Wikipedia)

Level Up Coding

Thanks for being a part of our community! More content in the Level Up Coding publication.
Follow: Twitter, LinkedIn, Newsletter
Level Up is transforming tech recruiting ➡️ Join our talent collective


Timezones on discord.js was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.

I created a discord bot a few weeks ago. The idea for it was simple: The user would click on a button, then the bot would create a new channel for them, containing a series of questions which could be urls, select menus, numbers, etc. Once all of the questions had been answered, the bot would send them to another channel as an embed message. Easy, right? However, there was a little issue.

The problem

One of the questions required by the bot was a date and time. I had to get the message content and format it into a Discord timestamp. The code looked like this:

customParseFormat = require('dayjs/plugin/customParseFormat');
const dayjs = require("dayjs");
dayjs.extend(customParseFormat);
/*...*/
const filter = m => m.author.id === interaction.user.id && !m.author.bot;
collector = channel.createMessageCollector({ time: 60000, filter });
p = new Promise((resolve, reject) => {
collector.on("collect", m => {
if(!dayjs(m.content, "DD/MM/YYYY HH:mm").isValid()) return m.delete();
        answers.push({name: q.name, value: `<t:${dayjs(m.content, "DD/MM/YYYY HH:mm").unix()}>`});
resolve(m);
collector.stop();
m.delete();
});
});
await p;
/*...*/

The bot worked just fine to me, but when my client tested it, they got a completely different time!

As it turns out, this is because we were in different timezones. So when my client sent a date, the bot parsed it as-is, without considering time differences. Since my timezone is UTC+3 and theirs is UTC, their time would always be 3 hours different than their original input. This was of course a big problem.

The solution

Sadly, Discord.js currently doesn’t offer any way to get the user’s local time. So the only solution was to get it as an argument, and add or subtract hours depending on the bot’s local time. Fortunately, Day.js lets you parse a date using an input string, and convert the parsed date into a unix timestamp. It also lets you add or subtract from the time. Perfect!

After a little bit of testing, the code ended up like this:

customParseFormat = require('dayjs/plugin/customParseFormat');
const dayjs = require("dayjs");
dayjs.extend(customParseFormat);
/*...*/
const filter = m => m.author.id === interaction.user.id && !m.author.bot;
collector = channel.createMessageCollector({ time: 60000, filter });
p = new Promise((resolve, reject) => {
collector.on("collect", m => {
const localOffset = new Date().getTimezoneOffset() / 60;
let date = m.content.split(" ");
if(date.length !== 3) return m.delete();
const timezone = parseInt(date[date.length - 1]);

date.pop();
date = date.join(" ")
if(!dayjs(date, "DD/MM/YYYY HH:mm").isValid()) return m.delete();
answers.push({name: q.name, value: `<t:${dayjs(m.content, "DD/MM/YYYY HH:mm").add(timezone + localOffset, "h").unix()}>`});
resolve(m);
collector.stop();
m.delete();
});
});
await p;
/*...*/

Note that localOffset will be positive if the bot is on the left of UTC and negative if it is on the right.

Standard timezone map(Wikipedia)

Level Up Coding

Thanks for being a part of our community! More content in the Level Up Coding publication.
Follow: Twitter, LinkedIn, Newsletter
Level Up is transforming tech recruiting ➡️ Join our talent collective


Timezones on discord.js was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


Print Share Comment Cite Upload Translate
APA
Gabriel Ferreira | Sciencx (2024-03-29T05:52:36+00:00) » Timezones on discord.js. Retrieved from https://www.scien.cx/2022/06/22/timezones-on-discord-js/.
MLA
" » Timezones on discord.js." Gabriel Ferreira | Sciencx - Wednesday June 22, 2022, https://www.scien.cx/2022/06/22/timezones-on-discord-js/
HARVARD
Gabriel Ferreira | Sciencx Wednesday June 22, 2022 » Timezones on discord.js., viewed 2024-03-29T05:52:36+00:00,<https://www.scien.cx/2022/06/22/timezones-on-discord-js/>
VANCOUVER
Gabriel Ferreira | Sciencx - » Timezones on discord.js. [Internet]. [Accessed 2024-03-29T05:52:36+00:00]. Available from: https://www.scien.cx/2022/06/22/timezones-on-discord-js/
CHICAGO
" » Timezones on discord.js." Gabriel Ferreira | Sciencx - Accessed 2024-03-29T05:52:36+00:00. https://www.scien.cx/2022/06/22/timezones-on-discord-js/
IEEE
" » Timezones on discord.js." Gabriel Ferreira | Sciencx [Online]. Available: https://www.scien.cx/2022/06/22/timezones-on-discord-js/. [Accessed: 2024-03-29T05:52:36+00:00]
rf:citation
» Timezones on discord.js | Gabriel Ferreira | Sciencx | https://www.scien.cx/2022/06/22/timezones-on-discord-js/ | 2024-03-29T05:52:36+00:00
https://github.com/addpipe/simple-recorderjs-demo