How to convert to proper time from stat() module - perl

I have a code to retrieve last modified date from stat() module in Perl. But the output which displayed is not in proper time format. Could you please help me to get proper time (HH:MM:SS)?
Please find the sample program I have used:
my $file="filename";
my $time=(stat($file))[9];
say "$time";
Output: 149160
Please help me convert into HH:MM:SS.

Assuming you just want hours, minutes and seconds, you can use POSIX and gmtime:
use warnings;
use strict;
use feature 'say';
use POSIX qw(strftime);
my $file="filename";
my $time=(stat($file))[9];
say strftime('%H:%M:%S', gmtime($time));

Given that you only want hours, minutes and seconds, as an alternative approach, you may use localtime or its companion function, gmtime, without the POSIX module and simply select the desired time components.
use strict;
use warnings;
use feature qw(say);
my $file = "filename";
my #time;
#time = localtime((stat($file))[9]);
say join ":", #time [2,1,0]; #...HH:MM:SS in local time
#time = gmtime ((stat($file))[9]);
say join ":", #time [2,1,0]; #...HH:MM:SS in GMT time

Related

Convert Date DD/MM/YYYY to 7 Digit Julian Date in Perl

I have not used Julian date before and have no experience with it. I do not know how the 7-Digit needs to be converted or if there is a library that does it.
I require help with 10/10/2020 to be converted to 2459133 in Perl.
Time::Piece is part of the standard Perl library.
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Time::Piece;
# Get a Time::Piece object from your date string
my $d = Time::Piece->strptime('10/10/2020', '%d/%m/%Y');
# Call its julian_day() method.
say $d->julian_day;

Convert ISO-8601 timestamp from UTC-7:00 to "Europe/Amsterdam" (CEST) time, which is UTC+2:00

In Perl I use a bash command to convert an ISO-8601 timestamp to local format YYYY-mm-dd HH:MM:SS.
These timestamps, for example, are used in Google Cloud JSON APIs. For example
2016-08-09T17:05:05.414-07:00. Check the source below for a working example.
This works fine, but is there a way to accomplish the same in Perl without using a bash command? Of course I'm sure there is, but I couldn't find anything simple.
#!/usr/bin/perl -w
use strict;
use warnings;
my $f = `date -d 2016-08-09T17:05:05.414-07:00 +'%Y-%m-%d %H:%M:%S'`;
chop $f;
print "$f\n"; # 2016-08-10 02:05:05
The DateTime modules are the obvious choice for this. Your original string is formatted according to the ISO-8601 standard so the DateTime::Format::ISO8601 will parse it directly
Then it is simply a matter of setting the time zone to zero and formatting the result as required
Here's the code
use strict;
use warnings 'all';
use feature 'say';
use DateTime::Format::ISO8601;
say localise_time('2016-08-09T17:05:05.414-07:00');
sub localise_time {
my ($dt) = #_;
$dt = DateTime::Format::ISO8601->parse_datetime($dt);
$dt->set_time_zone('Europe/Amsterdam');
$dt->strftime('%Y-%m-%d %H:%M:%S');
}
output
2016-08-10 02:05:05

Get week number with POSIX::strftime in perl

I need to get the ISO 8601 week number of todays date in perl.
What is wrong woth the following code?
#! /usr/bin/perl
use strict;
use warnings;
use Time::Local;
use POSIX qw(strftime);
my $weekNumber = POSIX::strftime("%V", localtime time);
print $weekNumber, "\n";
The output I get is simply %V and my expected result (for epoch 1407769639) is 33.
FYI using POSIX::strftime("%W", localtime time); results in 32.
It is best to use Time::Piece, which has been a core module since version 10 of Perl 5, and so shouldn't need installing unless you are running a very old version.
Time::Piece replaces the core localtime function with one that returns a Time::Piece object, so the code would look like this
use strict;
use warnings;
use Time::Piece;
print localtime->week, "\n";
output
33
The POSIX functions are thin layers over your C library. What you get is based on your C library's behaviour. You get %V because your C library's strftime doesn't recognize %V.

perl to open csv file with dynamic date in it?

How can I open a CSV file with a date that changes each day, where the date format is yyyy for year, dd for day and mmm for a 3 letter month.
This is as far as I've got
#!/usr/bin/perl
use strict;
use warnings;
#Set-up Input Files
#Inputfile
$INFILE = "C:\\DBR_%yyyy\\%b\\Failures_input%d%h\\.csv";
#Open input file for reading
open (INPUT,"$INFILE") or die " cannot open $INFILE ";
It is very unclear what you are asking for, and you don't mention %d and %h in your pattern.
If you want to open the latest CSV file then you need to do a nested search of the path, finding the latest date and time.
Here is something that may help. This code generates the path to the file that would be created for the current date and time. It uses the Time::Piece module, which is part of core Perl and shouldn't need installing. By default it overloads the localtime operator so that it returns a Time::Piece object in scalar context. That allows the module's utility methods to be applied directly.
use strict;
use warnings;
use Time::Piece;
my $failures_file = localtime->strftime('C:\DBR_%Y\%b\Failures_input%d%b.csv');
my $invoices_file = localtime->strftime('C:\%Y\%b\invoices%d%b.csv');
print $failures_file, "\n";
print $invoices_file, "\n";
output
C:\DBR_2014\Mar\Failures_input17Mar.csv
C:\2014\Mar\invoices17Mar.csv
However I think it is more likely that you want the name of the latest file with a path of that form, which is a little more complex (and a dreadful system design). Please verify your requirement and we will be able to help you further.
I wanted to write an answer about the localtime Perl function, but its documentation is so complete that it even includes stuff about the three-letter abbreviations.
A few remarks on your string literal for the filename:
You can use single forward slashes, even on Windows
You don't have to escape the dot with a backslash
You can "interpolate" variables into strings: "DBR_$yyyy" if $yyyy is a variable.
I second SzG's general recommendations.
The following shows how to add the date formatting to your filename using two core modules.
Using Time::Piece (in Perl core since version 5.8):
use Time::Piece;
use strict;
use warnings;
my $infile = localtime->strftime('C:\DBR_%Y\%b\Failures_input%d.csv');
Or using POSIX and strftime if you're working on an ancient box. To find the available specifiers, just google strftime:
use POSIX qw(strftime);
use strict;
use warnings;
my $infile = strftime 'C:\DBR_%Y\%b\Failures_input%d.csv', localtime;
Outputs:
C:\DBR_2014\Mar\Failures_input16.csv

How to convert a time format to seconds in solaris

I have a time of format 2013-04-29 08:17:58 and I need to convert it into seconds.
In UNIX, we can use date +%s. Is there anyway to do it in Solaris?
Use Time::Piece. It has been part of the standard Perl 5 distribution since version 9.5 and shouldn't need installing.
use strict;
use warnings;
use 5.010;
use Time::Piece;
my $t = '2013-04-29 08:17:58';
$t = Time::Piece->strptime($t, '%Y-%m-%d %H:%M:%S');
say $t->epoch;
output
1367223478
With a little more effort, you can do this with your horribly outdated version of Perl.
#!/usr/bin/perl
use strict;
use warnings;
use Time::Local;
my $str = '2013-04-29 08:17:58';
my #dt = split /[- :]/, $str;
$dt[0] -= 1900;
$dt[1] -= 1;
print timelocal reverse #dt;
Time::Local has been included with Perl since the first release of Perl 5 (in 1994).
But please do what you can to get your ancient version of Perl updated.
Update: Getting a few downvotes on this. But no-one has bothered to explain why.