Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to associate days (1 to 365.25) to radians in perl?

I have number of days from 1 to 180 days, decreasing and increasing dates from the date $epoch='2020-05-11'. The full period = 365.25 days, an amplitude, a frequency and a phase will be added later in the end to create a sine wave. This is not the whole code attached, but I need that each day to be converted to radians or associated? How to solve this, I have searched via internet just conversion from degrees to radians.

The data input are coming from bat file, just further to easily make changes:

C:\Strawberry\perl\bin\perl.exe D:\perl\ex4444.pl Peri_GPS ZAT1_GPS 2020-05-11 180
pause

and the code itself:

#!/usr/bin/perl
use Math::Random::OO::Normal;
use Time::Local;
use Time::Localtime;
use POSIX qw(strftime);

my $filename = 'D:\perl\program.txt';
    open (FH, '>', $filename) 
        or die $!;
        
my ($station1, $station2, $epoch, $count_day) = @ARGV; 

$day_a2 = -1;
$day_a1 = $day_a2 - $count_day;
$day_a3 = 1;
$day_a4 = $day_a3 + $count_day;

my ($year, $month, $day) = split('-', $epoch);

$epoch = timelocal(0, 0, 0, $day, $month-1, $year-1900);
$day_sec = 60*60*24;
$interval=$count_day*$day_sec;
$epoch1=$epoch-86400;
$epoch2=$epoch1-$interval;
$epoch3=$epoch+86400;
$epoch4=$epoch3+$interval;

@x1=(); @x2=();

for ($d = $day_a1; $d <= $day_a2; $d++){
    $epoch2 += $day_sec;
    push (@x1, $d);
    printf FH scalar(strftime " %Y %m %d %H %M", localtime($epoch2));
    printf FH " %14.4f  \n";
    close $FH;
}
for ($d = $day_a3; $d <= $day_a4; $d++){
    $epoch3 += $day_sec;
    push (@x2, $d);
    print FH scalar(strftime " %Y %m %d %H %M", localtime($epoch3));
    printf FH " %14.4f  \n";
    close $FH; 
}
like image 855
Peri Avatar asked Sep 08 '20 05:09

Peri


1 Answers

You have a range and you want to find a fraction of that range. This is simple multiplication.

use POSIX       qw( strftime );
use Time::Local qw( timelocal );

my $date = '2020-05-11';
my $num_steps = 11;

my ($y, $m, $d) = split(/-/, $date);
my $epoch = timelocal(0, 0, 0, $d, $m-1, $y-1900);

my $range = 365.25 * 24 * 60 * 60 / 2;

for my $step (-$num_steps..$num_steps) {
   my $fraction = $step / $num_steps;
   my $new_epoch = $epoch + $range * $fraction;
   say strftime("%F %T", localtime($new_epoch));
}

For my time zone, that outputs

2019-11-10 08:00:00
2019-11-28 14:18:00
2019-12-16 20:36:00
2020-01-04 02:54:00
2020-01-22 09:12:00
2020-02-09 15:30:00
2020-02-27 21:48:00
2020-03-17 05:06:00
2020-04-04 11:24:00
2020-04-22 17:42:00
2020-05-11 00:00:00
2020-05-29 06:18:00
2020-06-16 12:36:00
2020-07-04 18:54:00
2020-07-23 01:12:00
2020-08-10 07:30:00
2020-08-28 13:48:00
2020-09-15 20:06:00
2020-10-04 02:24:00
2020-10-22 08:42:00
2020-11-09 14:00:00

Notice how $fraction simply varies from -1 to +1? Well, so does sin(x)!

Say we add the following to the program:

use constant PI => 3.14159265359;

$fraction = sin( $fraction * PI );

The builtin sin takes radians as input, so one would expect dates that following the following distribution:

sin(x) from -pi to +pi

The program now outputs the following:

2020-05-11 00:00:00   0
2020-03-15 13:34:42
2020-01-24 14:44:14
2019-12-15 05:04:42
2019-11-19 06:31:09
2019-11-10 08:00:00  -1
2019-11-19 06:31:09
2019-12-15 05:04:42
2020-01-24 14:44:14
2020-03-15 13:34:42
2020-05-11 00:00:00   0
2020-07-06 10:25:17
2020-08-26 08:15:45
2020-10-05 17:55:17
2020-10-31 16:28:50
2020-11-09 14:00:00  +1
2020-10-31 16:28:50
2020-10-05 17:55:17
2020-08-26 08:15:45
2020-07-06 10:25:17
2020-05-10 23:59:59   0
like image 137
ikegami Avatar answered Nov 20 '22 16:11

ikegami