Convert time in GMT to current time zone in perl - perl

I want to convert GMT time string to my system time zone.
Ex.
Tue Nov 04 22:03:03 2014 GMT
My machine time zone is PST, so output should be : 2014-11-04 14:03:03 PST
I can do this in bash but could not find any solution for perl.
Bash solution=> timestamp_local=date "+%Y-%m-%d %H:%M:%S %Z" -d "$timestamp_GMT"
Anyone have solution in perl?
PS: I have to process a huge file ( around 100-200MB of text file ). So, I want a optimized solution.

Simple enough with DateTime and friends.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use DateTime::Format::Strptime;
use DateTime;
my $format = '%a %b %d %H:%M:%S %Y %Z';
my $time_string = 'Tue Nov 04 22:03:03 2014 GMT';
my $dt_p = DateTime::Format::Strptime->new(
pattern => $format,
time_zone => 'UTC',
);
my $time = $dt_p->parse_datetime($time_string);
say $time->strftime('%a %b %d %H:%M:%S %Y %Z');
$time->set_time_zone('America/Los_Angeles');
say $time->strftime('%a %b %d %H:%M:%S %Y %Z');
Update: And this old answer shows how to do something very similar with the core module Time::Piece.

POSIX library should be enough to do this;
use strict;
use feature qw/say/;
use POSIX qw(strftime tzset);
say strftime("%Y %d %m %H:%M:%S GMT", gmtime(time)); # GMT
say strftime("%Y %d %m %H:%M:%S %Z", localtime(time)); # Local Time
# Set to custom timezone
$ENV{TZ} = 'America/Los_Angeles';
tzset;
say strftime("%Y %d %m %H:%M:%S %Z", localtime(time)); # Custom Zone

Related

Displaying 12-h time in Perl using DateTime

This perl script produces a datestamp and timestamp.
Is there a simple way to display the time in a 12 hour format with AM/PM displayed?
use DateTime;
use DateTime::TimeZone;
my $tz = DateTime::TimeZone->new( name => 'Pacific/Honolulu' );
my $dt = DateTime->now(time_zone =>'Pacific/Honolulu');
my $offset = $tz->offset_for_datetime($dt);
$timestamp = $dt->hms(':');
$datestamp = $dt->mdy('/');
print "$datestamp at $timestamp\n";
Most date-time modules will provide access to the C function strftime or a re-implementation of it. In format specifications provided to strftime, you can use the following patterns:
%I: The hour as a decimal number using a 12-hour clock.
%l: The hour as a decimal number using a 12-hour clock. Single digits are preceded by a blank.
%p: Either "AM" or "PM".
%P: Either "am" or "pm".
DateTime objects have a method called strftime. For example,
$ perl -e'
use DateTime qw( );
my $now = DateTime->now( time_zone => "local" );
CORE::say $now->strftime("%Y/%m/%d %I:%M:%S %p %z");
'
2019/06/02 09:45:37 PM -0400
As #Nilesh Bhimani tried to point out, the DateTime module is rather heavy, and it's not required for this task (especially if you want to use local time or UTC) because the POSIX module provides strftime as well. For example,
$ perl -e'
use POSIX qw( strftime );
my $now = time;
CORE::say strftime("%Y/%m/%d %I:%M:%S %p %z", localtime($now));
'
2019/06/02 09:45:37 PM -0400
#!/usr/local/bin/perl
use POSIX qw(strftime);
my $datestring = strftime "%a %b %e %H:%M:%S %Y %P", localtime;
printf "date and time - $datestring\n";
my $datestring = strftime "%a %b %e %H:%M:%S %Y %P", gmtime;
printf "date and time - $datestring\n";

Time::Piece (localtime/gmtime) calculation vs bash date

Have this bash script:
future="${1:-Dec 08 2017 22:00:00}"
t1=$(date -j -f "%b %d %Y %H:%M:%S" "$future" +%s) #using OS X
t0=$(date +%s)
echo "Current: $(date)"
echo "Future : $future"
echo "Diff : $(( $t1 - $t0 )) secs"
It prints:
Current: pi 8. december 2017 21:25:25 CET
Future : Dec 08 2017 22:00:00
Diff : 2075 secs
The result (diff) is correct.
Now trying to do the same using perl:
use strict;
use warnings;
use feature 'say';
use Time::Piece;
my $format = '%b %d %Y %H:%M:%S';
my $future = shift // 'Dec 08 2017 22:00:00';
say "Future: $future";
say "localtime: ", scalar localtime();
say "gmtime : ", scalar gmtime();
my $tf = Time::Piece->strptime($future, $format);
say 'localtime-diff : ', $tf-localtime();
say 'gmtime-diff : ', $tf-gmtime();
it prints
Future: Dec 08 2017 22:00:00
localtime: Fri Dec 8 21:27:45 2017 #correct
gmtime : Fri Dec 8 20:27:45 2017 #correct
localtime-diff : 5535 #incorrect (expecting 3600 secs less)
gmtime-diff : 5535 #ok
What is wrong? Mean, why it prints the same diff for the localtime and gmtime but the scalar localtime and scalar gmtime prints different (and correct) strings?
EDIT: So, the main question is: how to get the same result as in bash using perl?
Both localtime() and gmtime() return an object that represents now.
You are doing:
2017-12-08T22:00:00+00:00 - 2017-12-08T21:25:25+01:00 # $tf-localtime()
2017-12-08T22:00:00+00:00 - 2017-12-08T20:25:25+00:00 # $tf-gmtime()
It looks like you want to do
2017-12-08T22:00:00+01:00 - 2017-12-08T21:25:25+01:00
Using Time::Piece:
use Time::Piece qw( localtime );
my $future_str = 'Dec 08 2017 23:00:00';
my $format = '%b %d %Y %H:%M:%S';
my $future_dt = localtime->strptime($future_str, $format);
say $future_dt - localtime(); # 2241 (instead of 5841)
Using DateTime:
use DateTime::Format::Strptime qw( );
my $future_str = 'Dec 08 2017 23:00:00';
my $format = DateTime::Format::Strptime->new(
pattern => '%b %d %Y %H:%M:%S',
locale => 'en',
time_zone => 'local',
on_error => 'croak',
);
my $future_dt = $format->parse_datetime($future_str);
say $future_dt->epoch - time(); # 2241 (instead of 5841)

How can I change the date time formats in Perl?

i want to convert the date time format to that i want.
how to convert the date time format from Fri Nov 21 2014 15:04:32 to 2014-11-21 15:04:32 ?
thanks
Time::Piece has been core Perl for many years.
Use strptime (string parse time) to parse your date/time string.
Use strftime (string format time) to format your date/time as you want it.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Time::Piece;
# Formats are defined in "man strftime"
my $in_fmt = '%a %b %d %Y %H:%M:%S';
my $out_fmt = '%Y-%m-%d %H:%M:%S';
my $in_date = 'Fri Nov 21 2014 15:04:32';
my $date = Time::Piece->strptime($in_date, $in_fmt);
my $out_date = $date->strftime($out_fmt);
say $out_date;
my $str = 'Fri Nov 21 2014 15:04:32';
my #months =('jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec');
my ($day,$mon,$date,$year,$time) = split(' ',lc($str));
my %month_hash;
#month_hash{#months} = (1 .. 12);
print "$year-$month_hash{$mon}-$date $time";
try this its crude method but works for your requirements. use date::manip for flexible usage

How to get the system clock in format in Perl?

I want to get the system clock (time and date) and display it in a human-readable format in Perl.
The format like 2014-09-12 15:13:56
#!/usr/local/bin/perl
my %months = qw(Jan Feb Mar Apr May Jun Jul
Aug Sep Oct Nov Dec);
#weekDays = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear,
$daylightSavings) = localtime();
$year = 1900 + $yearOffset;
$now = "$year-$months-$dayOfMonth $hour:$minute:$second";
print $now;
When you run the program, you should see a much more readable date and time like this:
2014--12 16:57:15
how to get convert the month to number ?
Using Time::Piece (core module since perl v5.9.5)
use Time::Piece;
my $dt = localtime;
print $dt->ymd, " ", $dt->hms, "\n";
using DateTime
use DateTime;
my $dt = DateTime->now();
print $dt->ymd, " ", $dt->hms, "\n";
It's easier using a Perl module (POSIX doesn't requires installation):
use POSIX qw/strftime/;
my $now_string = strftime "%Y-%m-%d %H:%M:%S", localtime;
print $now_string, "\n"; #<-- prints: 2014-09-12 11:09:45 (with my local time)
Regarding to your code, there is a typo:
$now = "$year-$months-$dayOfMonth $hour:$minute:$second";
should be:
$now = "$year-$month-$dayOfMonth $hour:$minute:$second";
Be sure to write use strict; and use warnings; in the top place of your script. It prevents you from errors like that.
I like to put these date and time tasks into functions for reuse.
Here is my approach:
use strict;
use warnings;
my $time_stamp = getTodaysDateTime();
print "Program Started: $time_stamp \n";
# do some processing
$time_stamp = getTodaysDateTime();
print "Program Ended: $time_stamp \n";
# return date in specific format
# ex: 2014-09-12 14:11:43
sub getTodaysDateTime {
my ($sec,$min,$hour,$mday,$mon,$year,
$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon += 1;
return sprintf("%d-%02d-%02d %02d:%02d:%02d",
$year,$mon,$mday,$hour,$min,$sec);
}

Date Conversion

In perl, how do I convert date like
Thu Mar 06 02:59:39 +0000 2008
to
2008-03-06T02:59:39Z
Tried HTTP::Date, it works if the question did not have +0000 in the string :(
DateTime::Format::Strptime will do this conversion.
#!/usr/bin/perl
use strict;
use warnings;
use 5.012;
use DateTime::Format::Strptime;
my $date = 'Thu Mar 06 02:59:39 +0000 2008 ';
my( #strp ) = (
DateTime::Format::Strptime->new( pattern => "%a %b %d %T %z %Y", ),
DateTime::Format::Strptime->new( pattern => "%FY%T%Z", )
);
my $dt = $strp[0]->parse_datetime( $date );
print $strp[1]->format_datetime( $dt );
prints 2008-03-06T02:59:39UTC
Chris
If you're absolutely, positively sure that the date will ALWAYS be in that format, you can simply use regular expressions to reformat it. The only thing is that you have to have a way of converting the month to a number. That way, you don't have to download any extra modules to do the date conversion:
my $date = "Thu Mar 06 02:59:39 +0000 2008"; #Original String
#Create the Month Hash (you might want all twelve months).
my %monthHash (Jan => "01", Feb => 2, Mar => 3);
# Use RegEx Matching to parse your date.
# \S+ means one or more non-spaces
# \s+ means one or more spaces
# Parentheses save that part of the string in $1, $2, $3, etc.
$date =~ m/\S+\s+(\S+)\s+(\S+)\s+(\S+)\s+\S+\s(.*)/;
my $monthString = $1;
my $day = $2;
my $time = $3;
my $year = $4;
# Convert Month string to a number.
my $month = $monthHash{$monthString};
#Reformat the string
$fmtDate="$year-$month-$day" . "T" . "$time" . "Z";
Otherwise I was going to say you can also try DateTime::Format::Strptime, but Chris Charley beat me to it.
So, edit it with a regex and use HTTP::Date:
( my $new_date_string = $old_state_string ) =~ s/[+-]\d{4,}\s+//;