refactor(Dates): save timestamps everywhere and use Date.parse (#7108)

This commit is contained in:
Jan
2022-01-08 12:41:20 +01:00
committed by GitHub
parent d06d70ccf2
commit 55e21f5366
18 changed files with 60 additions and 61 deletions

View File

@@ -162,11 +162,10 @@ class Client extends BaseClient {
this.application = null; this.application = null;
/** /**
* Time at which the client was last regarded as being in the `READY` state * Timestamp of the time the client was last `READY` at
* (each time the client disconnects and successfully reconnects, this will be overwritten) * @type {?number}
* @type {?Date}
*/ */
this.readyAt = null; this.readyTimestamp = null;
} }
/** /**
@@ -183,12 +182,13 @@ class Client extends BaseClient {
} }
/** /**
* Timestamp of the time the client was last `READY` at * Time at which the client was last regarded as being in the `READY` state
* @type {?number} * (each time the client disconnects and successfully reconnects, this will be overwritten)
* @type {?Date}
* @readonly * @readonly
*/ */
get readyTimestamp() { get readyAt() {
return this.readyAt?.getTime() ?? null; return this.readyTimestamp && new Date(this.readyTimestamp);
} }
/** /**
@@ -197,7 +197,7 @@ class Client extends BaseClient {
* @readonly * @readonly
*/ */
get uptime() { get uptime() {
return this.readyAt ? Date.now() - this.readyAt : null; return this.readyTimestamp && Date.now() - this.readyTimestamp;
} }
/** /**

View File

@@ -374,7 +374,7 @@ class WebSocketManager extends EventEmitter {
triggerClientReady() { triggerClientReady() {
this.status = Status.READY; this.status = Status.READY;
this.client.readyAt = new Date(); this.client.readyTimestamp = Date.now();
/** /**
* Emitted when the client becomes ready to start working. * Emitted when the client becomes ready to start working.

View File

@@ -4,7 +4,7 @@ const { Events } = require('../../../util/Constants');
module.exports = (client, { d: data }) => { module.exports = (client, { d: data }) => {
const channel = client.channels.cache.get(data.channel_id); const channel = client.channels.cache.get(data.channel_id);
const time = data.last_pin_timestamp ? new Date(data.last_pin_timestamp).getTime() : null; const time = data.last_pin_timestamp ? Date.parse(data.last_pin_timestamp) : null;
if (channel) { if (channel) {
// Discord sends null for last_pin_timestamp if the last pinned message was removed // Discord sends null for last_pin_timestamp if the last pinned message was removed

View File

@@ -16,7 +16,7 @@ function parseResponse(res) {
} }
function getAPIOffset(serverDate) { function getAPIOffset(serverDate) {
return new Date(serverDate).getTime() - Date.now(); return Date.parse(serverDate) - Date.now();
} }
function calculateReset(reset, resetAfter, serverDate) { function calculateReset(reset, resetAfter, serverDate) {
@@ -24,7 +24,7 @@ function calculateReset(reset, resetAfter, serverDate) {
if (resetAfter) { if (resetAfter) {
return Date.now() + Number(resetAfter) * 1_000; return Date.now() + Number(resetAfter) * 1_000;
} }
return new Date(Number(reset) * 1_000).getTime() - getAPIOffset(serverDate); return Number(reset) * 1_000 - getAPIOffset(serverDate);
} }
/* Invalid request limiting is done on a per-IP basis, not a per-token basis. /* Invalid request limiting is done on a per-IP basis, not a per-token basis.
@@ -242,7 +242,7 @@ class RequestHandler {
// https://github.com/discord/discord-api-docs/issues/182 // https://github.com/discord/discord-api-docs/issues/182
if (!resetAfter && request.route.includes('reactions')) { if (!resetAfter && request.route.includes('reactions')) {
this.reset = new Date(serverDate).getTime() - getAPIOffset(serverDate) + 250; this.reset = Date.parse(serverDate) - getAPIOffset(serverDate) + 250;
} }
// Handle retryAfter, which means we have actually hit a rate limit // Handle retryAfter, which means we have actually hit a rate limit

View File

@@ -66,7 +66,7 @@ class BaseGuildTextChannel extends GuildChannel {
* The timestamp when the last pinned message was pinned, if there was one * The timestamp when the last pinned message was pinned, if there was one
* @type {?number} * @type {?number}
*/ */
this.lastPinTimestamp = data.last_pin_timestamp ? new Date(data.last_pin_timestamp).getTime() : null; this.lastPinTimestamp = data.last_pin_timestamp ? Date.parse(data.last_pin_timestamp) : null;
} }
if ('default_auto_archive_duration' in data) { if ('default_auto_archive_duration' in data) {

View File

@@ -47,7 +47,7 @@ class DMChannel extends Channel {
* The timestamp when the last pinned message was pinned, if there was one * The timestamp when the last pinned message was pinned, if there was one
* @type {?number} * @type {?number}
*/ */
this.lastPinTimestamp = new Date(data.last_pin_timestamp).getTime(); this.lastPinTimestamp = Date.parse(data.last_pin_timestamp);
} else { } else {
this.lastPinTimestamp ??= null; this.lastPinTimestamp ??= null;
} }

View File

@@ -329,7 +329,7 @@ class Guild extends AnonymousGuild {
* The timestamp the client user joined the guild at * The timestamp the client user joined the guild at
* @type {number} * @type {number}
*/ */
this.joinedTimestamp = new Date(data.joined_at).getTime(); this.joinedTimestamp = Date.parse(data.joined_at);
} }
if ('default_message_notifications' in data) { if ('default_message_notifications' in data) {

View File

@@ -84,9 +84,9 @@ class GuildMember extends Base {
} else if (typeof this.avatar !== 'string') { } else if (typeof this.avatar !== 'string') {
this.avatar = null; this.avatar = null;
} }
if ('joined_at' in data) this.joinedTimestamp = new Date(data.joined_at).getTime(); if ('joined_at' in data) this.joinedTimestamp = Date.parse(data.joined_at);
if ('premium_since' in data) { if ('premium_since' in data) {
this.premiumSinceTimestamp = data.premium_since ? new Date(data.premium_since).getTime() : null; this.premiumSinceTimestamp = data.premium_since ? Date.parse(data.premium_since) : null;
} }
if ('roles' in data) this._roles = data.roles; if ('roles' in data) this._roles = data.roles;
this.pending = data.pending ?? false; this.pending = data.pending ?? false;
@@ -186,7 +186,7 @@ class GuildMember extends Base {
* @readonly * @readonly
*/ */
get joinedAt() { get joinedAt() {
return this.joinedTimestamp ? new Date(this.joinedTimestamp) : null; return this.joinedTimestamp && new Date(this.joinedTimestamp);
} }
/** /**
@@ -204,7 +204,7 @@ class GuildMember extends Base {
* @readonly * @readonly
*/ */
get premiumSince() { get premiumSince() {
return this.premiumSinceTimestamp ? new Date(this.premiumSinceTimestamp) : null; return this.premiumSinceTimestamp && new Date(this.premiumSinceTimestamp);
} }
/** /**

View File

@@ -66,18 +66,18 @@ class GuildTemplate extends Base {
if ('created_at' in data) { if ('created_at' in data) {
/** /**
* The time when this template was created at * The timestamp of when this template was created at
* @type {Date} * @type {number}
*/ */
this.createdAt = new Date(data.created_at); this.createdTimestamp = Date.parse(data.created_at);
} }
if ('updated_at' in data) { if ('updated_at' in data) {
/** /**
* The time when this template was last synced to the guild * The timestamp of when this template was last synced to the guild
* @type {Date} * @type {number}
*/ */
this.updatedAt = new Date(data.updated_at); this.updatedTimestamp = Date.parse(data.updated_at);
} }
if ('source_guild_id' in data) { if ('source_guild_id' in data) {
@@ -180,21 +180,21 @@ class GuildTemplate extends Base {
} }
/** /**
* The timestamp of when this template was created at * The time when this template was created at
* @type {number} * @type {Date}
* @readonly * @readonly
*/ */
get createdTimestamp() { get createdAt() {
return this.createdAt.getTime(); return new Date(this.createdTimestamp);
} }
/** /**
* The timestamp of when this template was last synced to the guild * The time when this template was last synced to the guild
* @type {number} * @type {Date}
* @readonly * @readonly
*/ */
get updatedTimestamp() { get updatedAt() {
return this.updatedAt.getTime(); return new Date(this.updatedTimestamp);
} }
/** /**

View File

@@ -192,12 +192,12 @@ class Invite extends Base {
* The timestamp this invite was created at * The timestamp this invite was created at
* @type {?number} * @type {?number}
*/ */
this.createdTimestamp = new Date(data.created_at).getTime(); this.createdTimestamp = Date.parse(data.created_at);
} else { } else {
this.createdTimestamp ??= null; this.createdTimestamp ??= null;
} }
if ('expires_at' in data) this._expiresTimestamp = new Date(data.expires_at).getTime(); if ('expires_at' in data) this._expiresTimestamp = Date.parse(data.expires_at);
else this._expiresTimestamp ??= null; else this._expiresTimestamp ??= null;
if ('stage_instance' in data) { if ('stage_instance' in data) {
@@ -227,7 +227,7 @@ class Invite extends Base {
* @readonly * @readonly
*/ */
get createdAt() { get createdAt() {
return this.createdTimestamp ? new Date(this.createdTimestamp) : null; return this.createdTimestamp && new Date(this.createdTimestamp);
} }
/** /**
@@ -263,8 +263,7 @@ class Invite extends Base {
* @readonly * @readonly
*/ */
get expiresAt() { get expiresAt() {
const { expiresTimestamp } = this; return this.expiresTimestamp && new Date(this.expiresTimestamp);
return expiresTimestamp ? new Date(expiresTimestamp) : null;
} }
/** /**

View File

@@ -186,7 +186,7 @@ class Message extends Base {
* The timestamp the message was last edited at (if applicable) * The timestamp the message was last edited at (if applicable)
* @type {?number} * @type {?number}
*/ */
this.editedTimestamp = new Date(data.edited_timestamp).getTime(); this.editedTimestamp = Date.parse(data.edited_timestamp);
} else { } else {
this.editedTimestamp ??= null; this.editedTimestamp ??= null;
} }
@@ -424,7 +424,7 @@ class Message extends Base {
* @readonly * @readonly
*/ */
get editedAt() { get editedAt() {
return this.editedTimestamp ? new Date(this.editedTimestamp) : null; return this.editedTimestamp && new Date(this.editedTimestamp);
} }
/** /**
@@ -943,8 +943,8 @@ class Message extends Base {
if (equal && rawData) { if (equal && rawData) {
equal = equal =
this.mentions.everyone === message.mentions.everyone && this.mentions.everyone === message.mentions.everyone &&
this.createdTimestamp === new Date(rawData.timestamp).getTime() && this.createdTimestamp === Date.parse(rawData.timestamp) &&
this.editedTimestamp === new Date(rawData.edited_timestamp).getTime(); this.editedTimestamp === Date.parse(rawData.edited_timestamp);
} }
return equal; return equal;

View File

@@ -87,6 +87,7 @@ class MessageEmbed {
* The timestamp of this embed * The timestamp of this embed
* @type {?number} * @type {?number}
*/ */
// Date.parse() cannot be used here because data.timestamp might be a number
this.timestamp = 'timestamp' in data ? new Date(data.timestamp).getTime() : null; this.timestamp = 'timestamp' in data ? new Date(data.timestamp).getTime() : null;
/** /**
@@ -240,7 +241,7 @@ class MessageEmbed {
* @readonly * @readonly
*/ */
get createdAt() { get createdAt() {
return this.timestamp ? new Date(this.timestamp) : null; return this.timestamp && new Date(this.timestamp);
} }
/** /**
@@ -514,7 +515,7 @@ class MessageEmbed {
type: 'rich', type: 'rich',
description: this.description, description: this.description,
url: this.url, url: this.url,
timestamp: this.timestamp && new Date(this.timestamp), timestamp: this.createdAt?.toISOString(),
color: this.color, color: this.color,
fields: this.fields, fields: this.fields,
thumbnail: this.thumbnail, thumbnail: this.thumbnail,

View File

@@ -271,7 +271,7 @@ class Activity {
* Creation date of the activity * Creation date of the activity
* @type {number} * @type {number}
*/ */
this.createdTimestamp = new Date(data.created_at).getTime(); this.createdTimestamp = Date.parse(data.created_at);
} }
/** /**

View File

@@ -99,7 +99,7 @@ class ThreadChannel extends Channel {
* created</info> * created</info>
* @type {?number} * @type {?number}
*/ */
this.archiveTimestamp = new Date(data.thread_metadata.archive_timestamp).getTime(); this.archiveTimestamp = Date.parse(data.thread_metadata.archive_timestamp);
} else { } else {
this.locked ??= null; this.locked ??= null;
this.archived ??= null; this.archived ??= null;
@@ -133,7 +133,7 @@ class ThreadChannel extends Channel {
* The timestamp when the last pinned message was pinned, if there was one * The timestamp when the last pinned message was pinned, if there was one
* @type {?number} * @type {?number}
*/ */
this.lastPinTimestamp = data.last_pin_timestamp ? new Date(data.last_pin_timestamp).getTime() : null; this.lastPinTimestamp = data.last_pin_timestamp ? Date.parse(data.last_pin_timestamp) : null;
} else { } else {
this.lastPinTimestamp ??= null; this.lastPinTimestamp ??= null;
} }
@@ -192,8 +192,7 @@ class ThreadChannel extends Channel {
* @readonly * @readonly
*/ */
get archivedAt() { get archivedAt() {
if (!this.archiveTimestamp) return null; return this.archiveTimestamp && new Date(this.archiveTimestamp);
return new Date(this.archiveTimestamp);
} }
/** /**

View File

@@ -33,7 +33,7 @@ class ThreadMember extends Base {
} }
_patch(data) { _patch(data) {
if ('join_timestamp' in data) this.joinedTimestamp = new Date(data.join_timestamp).getTime(); if ('join_timestamp' in data) this.joinedTimestamp = Date.parse(data.join_timestamp);
if ('flags' in data) { if ('flags' in data) {
/** /**
@@ -59,7 +59,7 @@ class ThreadMember extends Base {
* @readonly * @readonly
*/ */
get joinedAt() { get joinedAt() {
return this.joinedTimestamp ? new Date(this.joinedTimestamp) : null; return this.joinedTimestamp && new Date(this.joinedTimestamp);
} }
/** /**

View File

@@ -120,7 +120,7 @@ class VoiceState extends Base {
* The time at which the member requested to speak. This property is specific to stage channels only. * The time at which the member requested to speak. This property is specific to stage channels only.
* @type {?number} * @type {?number}
*/ */
this.requestToSpeakTimestamp = new Date(data.request_to_speak_timestamp).getTime(); this.requestToSpeakTimestamp = Date.parse(data.request_to_speak_timestamp);
} else { } else {
this.requestToSpeakTimestamp ??= null; this.requestToSpeakTimestamp ??= null;
} }

View File

@@ -49,7 +49,7 @@ class TextBasedChannel {
* @readonly * @readonly
*/ */
get lastPinAt() { get lastPinAt() {
return this.lastPinTimestamp ? new Date(this.lastPinTimestamp) : null; return this.lastPinTimestamp && new Date(this.lastPinTimestamp);
} }
/** /**

View File

@@ -545,8 +545,8 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
public readonly emojis: BaseGuildEmojiManager; public readonly emojis: BaseGuildEmojiManager;
public guilds: GuildManager; public guilds: GuildManager;
public options: ClientOptions; public options: ClientOptions;
public readyAt: If<Ready, Date>; public readonly readyAt: If<Ready, Date>;
public readonly readyTimestamp: If<Ready, number>; public readyTimestamp: If<Ready, number>;
public sweepers: Sweepers; public sweepers: Sweepers;
public shard: ShardClientUtil | null; public shard: ShardClientUtil | null;
public token: If<Ready, string, string | null>; public token: If<Ready, string, string | null>;
@@ -1200,8 +1200,8 @@ export class GuildScheduledEvent<S extends GuildScheduledEventStatus = GuildSche
export class GuildTemplate extends Base { export class GuildTemplate extends Base {
private constructor(client: Client, data: RawGuildTemplateData); private constructor(client: Client, data: RawGuildTemplateData);
public readonly createdTimestamp: number; public createdTimestamp: number;
public readonly updatedTimestamp: number; public updatedTimestamp: number;
public readonly url: string; public readonly url: string;
public code: string; public code: string;
public name: string; public name: string;
@@ -1209,8 +1209,8 @@ export class GuildTemplate extends Base {
public usageCount: number; public usageCount: number;
public creator: User; public creator: User;
public creatorId: Snowflake; public creatorId: Snowflake;
public createdAt: Date; public readonly createdAt: Date;
public updatedAt: Date; public readonly updatedAt: Date;
public guild: Guild | null; public guild: Guild | null;
public guildId: Snowflake; public guildId: Snowflake;
public serializedGuild: APITemplateSerializedSourceGuild; public serializedGuild: APITemplateSerializedSourceGuild;