File Coverage

blib/lib/Algorithm/Time/ToNumber.pm
Criterion Covered Total %
statement 35 35 100.0
branch 2 2 100.0
condition 8 8 100.0
subroutine 9 9 100.0
pod 5 5 100.0
total 59 59 100.0


line stmt bran cond sub pod time code
1             package Algorithm::Time::ToNumber;
2              
3 6     6   1172781 use 5.006;
  6         34  
4 6     6   24 use strict;
  6         8  
  6         147  
5 6     6   17 use warnings;
  6         14  
  6         281  
6 6     6   1536 use Math::Trig qw(pi);
  6         32805  
  6         3018  
7              
8             =head1 NAME
9              
10             Algorithm::Time::ToNumber - convert time to a number
11              
12             =head1 VERSION
13              
14             Version 0.0.1
15              
16             =cut
17              
18             our $VERSION = '0.0.1';
19              
20             =head1 SYNOPSIS
21              
22             use Algorithm::Time::ToNumber;
23              
24             print "---------------------------------------------------\n";
25             print "------------------noon_fail------------------------\n";
26             print "---------------------------------------------------\n";
27              
28             my $hour=0;
29             while ($hour < 24) {
30             my $time = $hour . ':00';
31             print $time . ' ' . Algorithm::Time::ToNumber->noon_fail($time) . "\n";
32              
33             $time = $hour . ':30';
34             print $time . ' ' . Algorithm::Time::ToNumber->noon_fail($time) . "\n";
35              
36             $hour++;
37             }
38              
39             print "---------------------------------------------------\n";
40             print "----------------midnight_fail----------------------\n";
41             print "---------------------------------------------------\n";
42              
43             $hour=0;
44             while ($hour < 24) {
45             my $time = $hour . ':00';
46             print $time . ' ' . Algorithm::Time::ToNumber->midnight_fail($time) . "\n";
47              
48             $time = $hour . ':30';
49             print $time . ' ' . Algorithm::Time::ToNumber->midnight_fail($time) . "\n";
50              
51             $hour++;
52             }
53              
54             print "---------------------------------------------------\n";
55             print "---------------------circle------------------------\n";
56             print "---------------------------------------------------\n";
57              
58             # this is what you want if you plan to use it with isolation forest
59              
60             $hour=0;
61             while ($hour < 24) {
62             my $time = $hour . ':00';
63             my ($sin_angle, $cos_angle) = Algorithm::Time::ToNumber->circle($time);
64             print $time . ' ' . $sin_angle . ' ' . $cos_angle . "\n";
65              
66             $time = $hour . ':30';
67             ($sin_angle, $cos_angle) = Algorithm::Time::ToNumber->circle($time);
68             print $time . ' ' . $sin_angle . ' ' . $cos_angle . "\n";
69              
70             $hour++;
71             }
72              
73             print "---------------------------------------------------\n";
74             print "----------------------angle------------------------\n";
75             print "---------------------------------------------------\n";
76              
77             $hour=0;
78             while ($hour < 24) {
79             my $time = $hour . ':00';
80             my ($sin_angle) = Algorithm::Time::ToNumber->circle($time);
81             print $time . ' ' . $sin_angle . "\n";
82              
83             $time = $hour . ':30';
84             ($sin_angle, $cos_angle) = Algorithm::Time::ToNumber->circle($time);
85             print $time . ' ' . $sin_angle . "\n";
86              
87             $hour++;
88             }
89              
90             print "---------------------------------------------------\n";
91             print "--------------suricata_to_circle-------------------\n";
92             print "---------------------------------------------------\n";
93              
94             $hour = 0;
95             while ($hour < 24) {
96             my $time = '2026-07-03T' .$hour . ':00:31.121465-0500';
97             my ($sin_angle, $cos_angle) = Algorithm::Time::ToNumber->suricata_to_circle($time);
98             print $time . ' ' . $sin_angle . ' ' . $cos_angle . "\n";
99              
100             $time = '2026-07-03T' .$hour . ':00:31.121465-0500';
101             ($sin_angle, $cos_angle) = Algorithm::Time::ToNumber->suricata_to_circle($time);
102             print $time . ' ' . $sin_angle . ' ' . $cos_angle . "\n";
103              
104             $hour++;
105             }
106              
107             =head1 SUBROUTINES
108              
109             =head2 noon_fail
110              
111             Wraps at 00:00. This will result in a gap at 12:00.
112              
113             my $hour=0;
114              
115             while ($hour < 24) {
116             my $time = $hour . ':00';
117             print $time . ' ' . Algorithm::Time::ToNumber->noon_fail($time) . "\n";
118              
119             $time = $hour . ':30';
120             print $time . ' ' . Algorithm::Time::ToNumber->noon_fail($time) . "\n";
121              
122             $hour++;
123             }
124              
125             =cut
126              
127             sub noon_fail {
128 10     10 1 488 my ($class, $time) = @_;
129 10         28 my ($h, $m, $s) = split(/:/, $time);
130 10   100     39 $s //= 0;
131              
132 10         44 my $hours = $h + $m / 60 + $s / 3600;
133              
134 10 100       22 $hours -= 24 if $hours >= 12;
135              
136 10         36 return $hours;
137             }
138              
139             =head2 midnight_fail
140              
141             Wraps at 12:00. This will result in a gap at 00:00.
142              
143             my $hour=0;
144              
145             while ($hour < 24) {
146             my $time = $hour . ':00';
147             print $time . ' ' . Algorithm::Time::ToNumber->midnight_fail($time) . "\n";
148              
149             $time = $hour . ':30';
150             print $time . ' ' . Algorithm::Time::ToNumber->midnight_fail($time) . "\n";
151              
152             $hour++;
153             }
154              
155             =cut
156              
157             sub midnight_fail {
158 9     9 1 495 my ($class, $time) = @_;
159              
160 9         25 my ($h, $m, $s) = split /:/, $time;
161 9   100     54 $s //= 0;
162              
163 9         46 return $h + $m / 60 + $s / 3600;
164             }
165              
166             =head2 circle
167              
168             This returns two floats.
169              
170             This is suitable for using with isolation forest. When using it with isolation
171             forest one needs to save both returns as their own feature.
172              
173             my $hour=0;
174              
175             while ($hour < 24) {
176             my $time = $hour . ':00';
177             my ($sin_angle, $cos_angle) = Algorithm::Time::ToNumber->circle($time);
178             print $time . ' ' . $sin_angle . ' ' . $cos_angle . "\n";
179              
180             $time = $hour . ':30';
181             ($sin_angle, $cos_angle) = Algorithm::Time::ToNumber->circle($time);
182             print $time . ' ' . $sin_angle . ' ' . $cos_angle . "\n";
183              
184             $hour++;
185             }
186              
187             =cut
188              
189             sub circle {
190 12     12 1 10260 my ($class, $time) = @_;
191              
192 12         44 my ($h, $m, $s) = split( /:/, $time);
193 12   100     48 $s //= 0;
194              
195 12         51 my $angle = 2 * pi * ($h * 3600 + $m * 60 + $s) / 86400;
196              
197 12         90 return (sin($angle), cos($angle));
198             }
199              
200             =head2 angle
201              
202             This returns a continue number, but will result in points overlapping.
203              
204             It is the same as circle, but does not take the time to compute cos.
205              
206             my $hour=0;
207              
208             while ($hour < 24) {
209             my $time = $hour . ':00';
210             my ($sin_angle) = Algorithm::Time::ToNumber->angle($time);
211             print $time . ' ' . $sin_angle . "\n";
212              
213             $time = $hour . ':30';
214             ($sin_angle) = Algorithm::Time::ToNumber->angle($time);
215             print $time . ' ' . $sin_angle . "\n";
216              
217             $hour++;
218             }
219              
220             =cut
221              
222             sub angle {
223 7     7 1 3862 my ($class, $time) = @_;
224            
225 7         19 my ($h, $m, $s) = split( /:/, $time);
226 7   100     26 $s //= 0;
227              
228 7         18 my $angle = 2 * pi * ($h * 3600 + $m * 60 + $s) / 86400;
229              
230 7         53 return sin($angle);
231             }
232              
233             =head2 suricata_to_circle
234              
235             Convert .timestamp from Suricata EVE output to something that
236             circle can parse and return it.
237              
238             my $hour = 0;
239              
240             while ($hour < 24) {
241             my $time = '2026-07-03T' .$hour . ':00:31.121465-0500';
242             my ($sin_angle, $cos_angle) = Algorithm::Time::ToNumber->suricata_to_circle($time);
243             print $time . ' ' . $sin_angle . ' ' . $cos_angle . "\n";
244              
245             $time = '2026-07-03T' .$hour . ':00:31.121465-0500';
246             ($sin_angle, $cos_angle) = Algorithm::Time::ToNumber->suricata_to_circle($time);
247             print $time . ' ' . $sin_angle . ' ' . $cos_angle . "\n";
248              
249             $hour++;
250             }
251              
252             =cut
253              
254             sub suricata_to_circle {
255 5     5 1 4910 my ($class, $time) = @_;
256              
257 5         26 $time =~ s/^.*T//;
258 5         16 $time =~ s/\-.*$//;
259              
260 5         9 return Algorithm::Time::ToNumber->circle($time);
261             }
262              
263             =head1 AUTHOR
264              
265             Zane C. Bowers-Hadley, C<< >>
266              
267             =head1 BUGS
268              
269             Please report any bugs or feature requests to C, or through
270             the web interface at L. I will be notified, and then you'll
271             automatically be notified of progress on your bug as I make changes.
272              
273              
274              
275              
276             =head1 SUPPORT
277              
278             You can find documentation for this module with the perldoc command.
279              
280             perldoc Algorithm::Time::ToNumber
281              
282              
283             You can also look for information at:
284              
285             =over 4
286              
287             =item * RT: CPAN's request tracker (report bugs here)
288              
289             L
290              
291             =item * CPAN Ratings
292              
293             L
294              
295             =item * Search CPAN
296              
297             L
298              
299             =back
300              
301              
302             =head1 ACKNOWLEDGEMENTS
303              
304              
305             =head1 LICENSE AND COPYRIGHT
306              
307             This software is Copyright (c) 2026 by Zane C. Bowers-Hadley.
308              
309             This is free software, licensed under:
310              
311             The GNU Lesser General Public License, Version 2.1, February 1999
312              
313             =cut
314              
315             1; # End of Algorithm::Time::ToNumber