-
Notifications
You must be signed in to change notification settings - Fork 3
/
nosotime.pas
144 lines (124 loc) · 3.4 KB
/
nosotime.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
unit NosoTime;
{
Nosotime 1.0
December 3th, 2022
Noso Time Unit for time synchronization on Noso project.
Requires indy package. (To-do: remove this dependancy)
Changes:
- Random use of NTP servers.
}
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, IdSNTP, DateUtils, strutils;
Type
TThreadUpdateOffeset = class(TThread)
private
Hosts: string;
protected
procedure Execute; override;
public
constructor Create(const CreatePaused: Boolean; const THosts:string);
end;
Function GetNetworkTimestamp(hostname:string):int64;
function TimestampToDate(timestamp:int64):String;
Function GetTimeOffset(NTPServers:String):int64;
Function UTCTime:Int64;
Function UTCTimeStr:String;
Procedure UpdateOffset(NTPServers:String);
function TimeSinceStamp(Lvalue:int64):string;
Var
NosoT_TimeOffset : int64 = 0;
NosoT_LastServer : string = '';
NosoT_LastUpdate : int64 = 0;
IMPLEMENTATION
constructor TThreadUpdateOffeset.Create(const CreatePaused: Boolean; const THosts:string);
begin
inherited Create(CreatePaused);
Hosts := THosts;
end;
procedure TThreadUpdateOffeset.Execute;
var
TimeToRun : int64;
TFinished : boolean = false;
Begin
GetTimeOffset(Hosts);
End;
Function GetNetworkTimestamp(hostname:string):int64;
var
NTPClient: TIdSNTP;
begin
result := 0;
NTPClient := TIdSNTP.Create(nil);
TRY
NTPClient.Host := hostname;
NTPClient.Active := True;
NTPClient.ReceiveTimeout:=500;
result := DateTimeToUnix(NTPClient.DateTime);
if result <0 then result := 0;
EXCEPT on E:Exception do
result := 0;
END; {TRY}
NTPClient.Free;
end;
function TimestampToDate(timestamp:int64):String;
begin
result := DateTimeToStr(UnixToDateTime(TimeStamp));
end;
Function GetTimeOffset(NTPServers:String):int64;
var
Counter : integer = 0;
ThisNTP : int64;
MyArray : array of string;
RanNumber : integer;
Begin
Result := 0;
NTPServers := StringReplace(NTPServers,':',' ',[rfReplaceAll, rfIgnoreCase]);
NTPServers := Trim(NTPServers);
MyArray := SplitString(NTPServers,' ');
Rannumber := Random(length(MyArray));
For Counter := 0 to length(MyArray)-1 do
begin
ThisNTP := GetNetworkTimestamp(MyArray[Rannumber]);
if ThisNTP>0 then
begin
Result := ThisNTP - DateTimeToUnix(Now);
NosoT_LastServer := MyArray[Rannumber];
NosoT_LastUpdate := UTCTime;
break;
end;
Inc(RanNumber);
If RanNumber >= length(MyArray)-1 then RanNumber := 0;
end;
NosoT_TimeOffset := Result;
End;
Function UTCTime:Int64;
Begin
Result := DateTimeToUnix(Now, False) +NosoT_TimeOffset;
End;
{Implemented for easy compatibility with nosowallet}
Function UTCTimeStr:String;
Begin
Result := InttoStr(DateTimeToUnix(Now, False) +NosoT_TimeOffset);
End;
Procedure UpdateOffset(NTPServers:String);
var
LThread : TThreadUpdateOffeset;
Begin
LThread := TThreadUpdateOffeset.Create(true,NTPservers);
LThread.FreeOnTerminate:=true;
LThread.Start;
End;
function TimeSinceStamp(Lvalue:int64):string;
var
Elapsed : Int64 = 0;
Begin
Elapsed := UTCTime - Lvalue;
if Elapsed div 60 < 1 then result := '<1m'
else if Elapsed div 3600 < 1 then result := IntToStr(Elapsed div 60)+'m'
else if Elapsed div 86400 < 1 then result := IntToStr(Elapsed div 3600)+'h'
else if Elapsed div 2592000 < 1 then result := IntToStr(Elapsed div 86400)+'d'
else if Elapsed div 31536000 < 1 then result := IntToStr(Elapsed div 2592000)+'M'
else result := IntToStr(Elapsed div 31536000)+' Y';
end;
END. // END UNIT