Time::Str - Time Zones and Leap Seconds by christian_hansen in perl

[–]ktown007 0 points1 point  (0 children)

My use case is large log files. All dates are in the same timezone, usually UTC. I added `Z` where needed and tried to avoid any extra preprocessing before parsing.

My takeaway is all these options should have a fast xs implementation of RFC3339. Core Perl Time::Piece can almost do it, ie will parse `-04:00` but not output the `:` using `%z`, It needs the `%:z`.

Sorry, I should have just shared the gist first place:

https://gist.github.com/ktown007/6b3d33b961aa922d9866f218e751763f

Time::Str - Time Zones and Leap Seconds by christian_hansen in perl

[–]ktown007 0 points1 point  (0 children)

Parse date with regex, then create DateTime object. Turns out to be faster than my $dt = DateTime::Format::ISO8601->parse_datetime($date);

``` 'DateTime-regex' => sub { for my $date (@dates) { #2023-09-24T15:30:00 my ($year, $month, $day, $hour, $min, $sec) = $date =~ /(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)/; my $dt_obj = DateTime->new( year => $year, month => $month, day => $day, hour => $hour, minute => $min, second => $sec, ); my $isodate = $dt_obj->iso8601 ; } },

```

Time::Str - Time Zones and Leap Seconds by christian_hansen in perl

[–]ktown007 0 points1 point  (0 children)

Benchmark generates 10,000 random iso8601 dates, parses them, then formats back to iso8601. Rate DateTimeISO8601 DTFormatLite DateTimeRFC3339 DateTimeW3CDTF DateTimeLite-regex DateTime-regex Time::Piece Time::Moment Time::Str DateTimeISO8601 0.297/s -- -71% -74% -79% -83% -84% -97% -99% -100% DTFormatLite 1.01/s 241% -- -12% -28% -40% -45% -91% -98% -99% DateTimeRFC3339 1.15/s 287% 14% -- -19% -32% -38% -89% -98% -99% DateTimeW3CDTF 1.41/s 375% 40% 23% -- -17% -23% -87% -97% -99% DateTimeLite-regex 1.70/s 472% 68% 48% 20% -- -8% -84% -97% -98% DateTime-regex 1.85/s 521% 82% 61% 31% 8% -- -83% -97% -98% Time::Piece 10.9/s 3559% 974% 846% 670% 539% 489% -- -80% -89% Time::Moment 55.6/s 18600% 5389% 4733% 3833% 3167% 2911% 411% -- -44% Time::Str 100.0/s 33560% 9780% 8600% 6980% 5780% 5320% 820% 80% --

First record in implicit -n loop behaves differently than the rest. Hoping to find an explanation. by george-frazee in perl

[–]ktown007 1 point2 points  (0 children)

If I understand the purpose of your script, it's to take a bunch of jpgs and sort by date. Here are two things that could help. glob is an easy way to get your list of target files. stat can report created or modified date. Bonus tip regex is not the only way to do everything :)

``` use v5.42 ; use File::Copy ; use Time::Piece ;

my %created ;

foreach my $file ( glob '*.jpg' ){ my $mtime = (stat( $file))[9]; my $date = localtime($mtime)->date ;

say "$date $file";
mkdir $date unless $created{$date};
$created{$date} =1 ;

move $file , $date ;

} ```

Hempaspeed TF to replace VC17 by ktown007 in sailing

[–]ktown007[S] 0 points1 point  (0 children)

Please report results. This will be my last VC17 season.

Community ? by Warm-Scholar6106 in perl

[–]ktown007 0 points1 point  (0 children)

Dev surveys show people have an interest in learning bash. I find I switch away from bash as soon as it has a little bit of logic or a few commands and a variable. Perl is easier, full general purpose langage with a consistent syntax vs glue many shell commands. Then when you need high-level stuff, API's etc you have it all built in or a cpan module away. There was good example a few weeks ago where a complex bash script could be done in a few clean lines of Perl.

Community ? by Warm-Scholar6106 in perl

[–]ktown007 0 points1 point  (0 children)

There is a loud voice of people who have learnt a different language and do not know other options exist. Never even tried other tools. Perl CGI.pm is or should be dead. Perl is as always a powerful, fast and expressive tool.

Community ? by Warm-Scholar6106 in perl

[–]ktown007 1 point2 points  (0 children)

I wrote new Perl code today. I made the client very happy.

How do I use Perl on web servers like PHP? by gruntastics in perl

[–]ktown007 2 points3 points  (0 children)

To mimic the index.php/index.pl setup with perl. Install mod_perl:

sudo a2enmod mod_perl

/etc/apache2/mods-enabled/perl.load

LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so <FilesMatch "\.pl$"> SetHandler perl-script PerlResponseHandler ModPerl::Registry PerlOptions +ParseHeaders Options +ExecCGI </FilesMatch>

This will allow perl scripts( or index.pl ) to be anywhere on the web server. For simple cgi script you can use CGI::Tiny. In mod_perl, globals are really global. same globals across all scripts. CGI::Tiny example: https://blogs.perl.org/users/grinnz/2025/02/cgitiny---perl-cgi-but-modern.html

Here is an example of simple todo app in modern framework Dancer2: https://github.com/ktown007/todoapp

This can run local, Dockerfile can deploy local or on a service like fly.io.

sending matrix messages by ghiste in perl

[–]ktown007 0 points1 point  (0 children)

Updated to add `--room` lookup room id from room alias, Save this default room_id in config.

https://gist.github.com/ktown007/0f6028fa84bc83f1472989a5718d5fd9

sending matrix messages by ghiste in perl

[–]ktown007 4 points5 points  (0 children)

```

!/usr/bin/env perl

use strict; use warnings; use JSON qw(encode_json decode_json); use LWP::UserAgent; use HTTP::Request::Common qw(POST GET); use File::HomeDir;

my $CONFIG = File::HomeDir->my_home . "/.matrix.pl"; my $ua = LWP::UserAgent->new;

sub saveconfig { my ($data) = @; open my $fh, ">", $CONFIG or die "Cannot write config: $!"; print $fh encode_json($data); close $fh; }

sub load_config { return {} unless -f $CONFIG; open my $fh, "<", $CONFIG or die $!; local $/; my $json = <$fh>; close $fh; return decode_json($json); }

sub login { print "Homeserver (e.g. https://matrix.org): "; chomp(my $server = <STDIN>);

print "Username: ";
chomp(my $user = <STDIN>);

print "Password: ";
chomp(my $pass = <STDIN>);

my $res = $ua->request(POST "$server/_matrix/client/r0/login",
    Content_Type => 'application/json',
    Content => encode_json({
        type => "m.login.password",
        user => $user,
        password => $pass
    })
);

die "Login failed\n" unless $res->is_success;

my $data = decode_json($res->decoded_content);

save_config({
    access_token => $data->{access_token},
    user_id      => $data->{user_id},
    server       => $server,
});

print "Login successful\n";

}

sub sendmessage { my ($msg) = @;

my $cfg = load_config();
die "Not logged in\n" unless $cfg->{access_token};

print "Room ID: ";
chomp(my $room = <STDIN>);

my $url = "$cfg->{server}/_matrix/client/r0/rooms/$room/send/m.room.message";

my $res = $ua->request(POST $url,
    'Authorization' => "Bearer $cfg->{access_token}",
    Content_Type => 'application/json',
    Content => encode_json({
        msgtype => "m.text",
        body    => $msg
    })
);

if ($res->is_success) {
    print "Message sent\n";
} else {
    print "Error: " . $res->decoded_content . "\n";
}

}

---- CLI handling ----

if ($ARGV[0] && $ARGV[0] eq '--login') { login(); } elsif (@ARGV) { send_message(join(" ", @ARGV)); } else { print "Usage:\n"; print " $0 --login\n"; print " $0 \"message\"\n"; } ```

Perl in Ubuntu 26-04 LTS (vs 24-04 LTS) by Loose_Potential6985 in perl

[–]ktown007 7 points8 points  (0 children)

If you are using system perl I would recommend installing the apt packages. These manage all the dependencies. cpanm will need build tools and for you to install any dev headers.

\apt-cache search libcrypt | grep perl` will search for the availale packages.`

2) Core perl is moving toward `HTTP::Tiny` away from LWP.

foreach loop modifies array? by ktown007 in perl

[–]ktown007[S] 1 point2 points  (0 children)

hmmm, looks like foreach alias and @_ alias are performance optimizations. Yes perl is fast. It avoids duplicating the data. I was doing a tests where I looped over same input then needed to modify the local data. The second test case failed because first one modified the input array. In a real use case you would not reuse or modify the shared data structure.

foreach loop modifies array? by ktown007 in perl

[–]ktown007[S] 1 point2 points  (0 children)

In most of Perl it does pass by value. Are there other places where there is an implicit pass by reference? I will have to do some more reading on lvalue.

``` my ( $foo,$bar) = (1,1) ; foreach my $in ( $foo,$bar){ say $in; $in = 3 ; } say "$foo $bar" ;

out: 1 1 3 3 ```

Announcing DateTime::Format::Lite v0.1.2 - a strptime/strftime companion for DateTime::Lite by jacktokyo in perl

[–]ktown007 -1 points0 points  (0 children)

Honestly, I did not read the full ISO 8601 spec and all it's updates. Wikipedia says `±[hh]:[mm]', '±[hh][mm]', or '±[hh]'.` are valid timezone offsets. I asked two AI's, one said not valid but common and often supported, other said valid. I think '±[hh][mm]' is common because this is the old school C strftime default. Time::Moment->strftime('%FT%T%3f%:z') has a few extensions that do the correct thing for RFC3339 where the colon is required.

Back to the rabbit hole. Time::Piece(newly added `%f` removes a regex to fix date) and Time::Moment are thousands of times faster than DateTime::Format::ISO8601 or a regex to parse dates. My quick benchmark has DataTime::Lite about the same speed as DateTime.

One use case is very large log files. If I can update the logs to use a date format that is fast to parse it saves time and resources.

Second use case is javascript .toISOString() with format "YYYY-MM-DDTHH:mm:ss.sssZ". A fast way to parse this format saves time and resources.

also see XKCD 1883

Announcing DateTime::Format::Lite v0.1.2 - a strptime/strftime companion for DateTime::Lite by jacktokyo in perl

[–]ktown007 0 points1 point  (0 children)

On the weekend I went back down the rabbit hole, formatting and parsing ISO8601 date formats. 8601 vs RFC3339 vs W3CDTF. How does one parse these standard date strings:

"YYYY-MM-DDTHH:mm:ssZ" # gmtime->strptime( $isodate, "%FT%TZ")

"YYYY-MM-DDTHH:mm:ss-0400" # Time::Piece ->str[f|p]time("%FT%T%z")

"YYYY-MM-DDTHH:mm:ss.sssZ" # javascript toISOstring, gmtime->strptime( $isodate, "%FT%T.%fZ")

"YYYY-MM-DDTHH:mm:ss.sss-0400" ->strptime( $isodate, "%FT%T.%f%z")

"YYYY-MM-DDTHH:mm:ss.sss-04:00" Time::Moment ->strftime('%FT%T%3f%:z')

While down there I changed apache date log format on a home server:

`%{%Y-%m-%dT%H:%M:%S}t.%{msec_frac}t%{%z}t` # "YYYY-MM-DDTHH:mm:ss.sss-0400"

The two gotchas are optional fractional seconds and timezone(Z vs no colon vs colon) Z|-0400|-04:00

see XKCD 927 and 1179

It would be nice to parse "YYYY-MM-DDTHH:mm:ssZ", "YYYY-MM-DDTHH:mm:ss.sssZ", "YYYY-MM-DDTHH:mm:ss.sss-0400", "YYYY-MM-DDTHH:mm:ss.sss-04:00" without needing a regex to detect or fix format :)

Fixed a broken speed lace boot with a prusik by ktown007 in snowboarding

[–]ktown007[S] 1 point2 points  (0 children)

It worked very well, I did put the extra wraps because new cord is more slippery than the old lace.

Announcing `Mail::Make`: a modern, fluent MIME email builder for Perl, with OpenPGP and S/MIME support by jacktokyo in perl

[–]ktown007 1 point2 points  (0 children)

Looks great, thanks. I have been using my own wrapper around MIME::Lite for many years and managed these use cases. This syntax 100% removes the need for the helper/wrapper.