File tree Expand file tree Collapse file tree 5 files changed +100
-0
lines changed Expand file tree Collapse file tree 5 files changed +100
-0
lines changed Original file line number Diff line number Diff line change @@ -23,6 +23,7 @@ import { tool as energyConverter } from './energy-converter';
23
23
import { tool as areaConverter } from './area-converter' ;
24
24
import { tool as angleConverter } from './angle-converter' ;
25
25
import { tool as floatingPointNumberConverter } from './floating-point-number-converter' ;
26
+ import { tool as snowflakeIdExtractor } from './snowflake-id-extractor' ;
26
27
import { tool as emailNormalizer } from './email-normalizer' ;
27
28
import { tool as bounceParser } from './bounce-parser' ;
28
29
import { tool as codeHighlighter } from './code-highlighter' ;
@@ -361,6 +362,7 @@ export const toolsByCategory: ToolCategory[] = [
361
362
jsonDiff ,
362
363
softwareLicenceCompatibility ,
363
364
safelinkDecoder ,
365
+ snowflakeIdExtractor ,
364
366
apiTester ,
365
367
bounceParser ,
366
368
colorWheel ,
Original file line number Diff line number Diff line change
1
+ import { Id } from '@vicons/tabler' ;
2
+ import { defineTool } from '../tool' ;
3
+
4
+ export const tool = defineTool ( {
5
+ name : 'Snowflake ID extractor' ,
6
+ path : '/snowflake-id-extractor' ,
7
+ description : 'Extract timestamp, machine ID, and sequence number from a Snowflake ID' ,
8
+ keywords : [ 'snowflake' , 'id' , 'extractor' ] ,
9
+ component : ( ) => import ( './snowflake-id-extractor.vue' ) ,
10
+ icon : Id ,
11
+ createdAt : new Date ( '2024-07-22' ) ,
12
+ } ) ;
Original file line number Diff line number Diff line change
1
+ import { describe , expect , it } from 'vitest' ;
2
+ import { extractId , extractMachineId , extractTimestamp } from './snowflake-id-extractor.service' ;
3
+
4
+ describe ( 'snowflake-id-extractor' , ( ) => {
5
+ it ( 'extract id from Snowflake ID' , ( ) => {
6
+ expect ( extractId ( 1263785187301658678n ) ) . toBe ( 54 ) ;
7
+ } ) ;
8
+ it ( 'extract machine id from Snowflake ID' , ( ) => {
9
+ expect ( extractMachineId ( 1263785187301658678n ) ) . toBe ( 65 ) ;
10
+ } ) ;
11
+ it ( 'extract timestamp from Snowflake ID' , ( ) => {
12
+ expect ( extractTimestamp ( 1263785187301658678n , new Date ( 1420070400000 ) ) ) . toStrictEqual ( new Date ( 1721380268646 ) ) ;
13
+ } ) ;
14
+ } ) ;
Original file line number Diff line number Diff line change
1
+ export function extractId ( id : bigint ) {
2
+ return Number ( id & 4095n ) ;
3
+ }
4
+
5
+ export function extractMachineId ( id : bigint ) {
6
+ return Number ( ( id >> 12n ) & 127n ) ;
7
+ }
8
+
9
+ export function extractTimestamp ( id : bigint , epoch : bigint | Date ) {
10
+ return new Date ( Number ( ( id >> 22n ) + getTimestamp ( epoch ) ) ) ;
11
+ }
12
+
13
+ function getTimestamp ( time : bigint | Date ) {
14
+ return typeof time === 'bigint' ? time : BigInt ( new Date ( time ) . getTime ( ) ) ;
15
+ }
Original file line number Diff line number Diff line change
1
+ <script setup lang="ts">
2
+ import { extractId , extractMachineId , extractTimestamp } from ' ./snowflake-id-extractor.service' ;
3
+
4
+ const inputId = ref (' 1263785187301658678' );
5
+ const inputEpoch = ref (' ' );
6
+
7
+ const inputProps = {
8
+ ' labelPosition' : ' left' ,
9
+ ' labelWidth' : ' 170px' ,
10
+ ' labelAlign' : ' right' ,
11
+ ' readonly' : true ,
12
+ ' mb-2' : ' ' ,
13
+ } as const ;
14
+ </script >
15
+
16
+ <template >
17
+ <div >
18
+ <c-card >
19
+ <c-input-text v-model:value =" inputId" label =" Snowflake ID" placeholder =" Put Snowflake ID here (eg. 1263785187301658678)" label-position =" left" label-width =" 110px" mb-2 label-align =" right" />
20
+ <c-input-text v-model:value =" inputEpoch" label =" Epoch" placeholder =" Put Epoch Timestamp here (optional, eg. 1420070400000)" label-position =" left" label-width =" 110px" mb-2 label-align =" right" />
21
+
22
+ <n-divider />
23
+
24
+ <InputCopyable
25
+ label =" Local date"
26
+ v-bind =" inputProps"
27
+ :value =" inputEpoch ? new Date(extractTimestamp(BigInt(inputId.valueOf()), BigInt(inputEpoch.valueOf()))).toLocaleString() : ''"
28
+ placeholder =" Epoch Timestamp will be here..."
29
+ label-position =" left" label-width =" 110px" mb-2 label-align =" right"
30
+ />
31
+
32
+ <InputCopyable
33
+ label =" Timestamp"
34
+ v-bind =" inputProps"
35
+ :value =" inputEpoch ? new Date(extractTimestamp(BigInt(inputId.valueOf()), BigInt(inputEpoch.valueOf()))).getTime() : ''"
36
+ placeholder =" Epoch Timestamp will be here..."
37
+ label-position =" left" label-width =" 110px" mb-2 label-align =" right"
38
+ />
39
+
40
+ <InputCopyable
41
+ label =" Machine ID"
42
+ v-bind =" inputProps"
43
+ :value =" extractMachineId(BigInt(inputId.valueOf()))"
44
+ placeholder =" Machine ID will be here..."
45
+ label-position =" left" label-width =" 110px" mb-2 label-align =" right"
46
+ />
47
+
48
+ <InputCopyable
49
+ label =" Sequence"
50
+ v-bind =" inputProps"
51
+ :value =" extractId(BigInt(inputId.valueOf()))"
52
+ placeholder =" Sequence number will be here..."
53
+ label-position =" left" label-width =" 110px" mb-2 label-align =" right"
54
+ />
55
+ </c-card >
56
+ </div >
57
+ </template >
You can’t perform that action at this time.
0 commit comments