Implement snowflakes

This commit is contained in:
zontreck 2024-07-10 02:09:10 -07:00
parent 660b7df562
commit 662b93e011
4 changed files with 103 additions and 25 deletions

View file

@ -0,0 +1,69 @@
class Snowflake implements Comparable<Snowflake> {
/// Discord Epoch
static final DiscordEpoch = DateTime.utc(2015, 1, 1, 0, 0, 0);
/// Aria's Creations Epoch
static final ACEpoch = DateTime.utc(2024, 7, 9, 23, 0, 0);
final DateTime epoch;
final int value;
static final ZERO = Snowflake(epoch: DiscordEpoch, value: 0);
Snowflake({required this.epoch, required this.value});
DateTime get timestamp =>
epoch.add(Duration(milliseconds: millisecondsSinceEpoch));
int get millisecondsSinceEpoch => value >> 22;
int get workerId => (value & 0x3E0000) >> 17;
int get processId => (value & 0x1F000) >> 12;
int get increment => value & 0xFFF;
bool get isZero => value == 0;
factory Snowflake.parse(dynamic value, DateTime epoch) {
int val = int.parse(value.toString());
return Snowflake(epoch: epoch, value: val);
}
factory Snowflake.now(DateTime epoch) =>
Snowflake.fromDateTime(DateTime.now(), epoch);
factory Snowflake.fromDateTime(DateTime dt, DateTime epoch) {
return Snowflake(
epoch: epoch, value: dt.difference(epoch).inMilliseconds << 22);
}
bool isBefore(Snowflake other) => timestamp.isBefore(other.timestamp);
bool isAfter(Snowflake other) => timestamp.isAfter(other.timestamp);
bool isAtSameMomentAs(Snowflake other) =>
timestamp.isAtSameMomentAs(other.timestamp);
Snowflake operator +(Duration duration) =>
Snowflake.fromDateTime(timestamp.add(duration), epoch);
Snowflake operator -(Duration duration) =>
Snowflake.fromDateTime(timestamp.subtract(duration), epoch);
@override
int compareTo(Snowflake other) => value.compareTo(other.value);
bool operator <(Snowflake other) => isBefore(other);
bool operator >(Snowflake other) => isAfter(other);
@override
bool operator ==(Object other) =>
identical(this, other) || (other is Snowflake && other.value == value);
@override
int get hashCode => value.hashCode;
@override
String toString() => value.toString();
}