I have to convert the GMT date to region specific date with format like "YYYY-MM-DD H:M:S".
Code developed is :-
use Time::Local;
($year,$mon,$day) = split /\-/, $ARGV[0];
($hrs,$min,$sec ) = split /:/, $ARGV[1];
$time = timegm( $sec, $min, $hrs, $day, $mon-1, $year-1900);
print scalar localtime($time), "\n";
But when I run it like :-
$ perl testDateGMTToLocal.pl 2018-10-29 11:49:33
It gives o/p converted in local time zone:-
Mon Oct 29 07:49:33 2018
But I want this o/p in below format
29-OCT-18 07:49:33
Thanks in advance.
I'd recommend to do it all using modules. The all-capable and very complete module is DateTime, and for this job you'd also need DateTime::Format::Strptime.
One other option is the simpler and much smaller core module Time::Piece
use warnings;
use strict;
use feature 'say';
use Time::Piece;
die "Usage $0 YYYY-MM-DD H:M:S" if #ARGV != 2;
my $time = join ' ', #ARGV;
my $tp = Time::Piece->strptime($time, "%Y-%m-%d %T");
my $local = localtime($tp->epoch);
say $local;
# In the desired format
say join('-', $local->mday, uc $local->month, $local->yy),
' ', $local->hms;
# If "Oct" is ok instead of block capitals for month abbreviation
say $local->strftime("%d-%b-%y %T");
This converts GMT time, with invocation as in the question, to the local time on my machine
Mon Oct 29 04:09:33 2018
29-OCT-18 04:09:33
29-Oct-18 04:09:33
where the middle one was asked for.
On some systems there is the %F format specifier for %Y-%m-$d.ā There may be a defined format for 29-OCT-18, in which case you don't have to patch it by hand, but I am not aware of it.
ā Or the module has its own formatting in which case that's portable. But origin of the error when it fails to do %F on my system isn't clear to me in that sense.
You can use
use POSIX qw( strftime );
print(strftime("%d-%b-%y %H:%M:%S", localtime($time)), "\n");
Related
I am reading a log file which contains time stamps which I want to convert to human readable.
In this command, $1 contains a time stamp (like this 1403457192.663): $temp = localtime->mon($1) but instead of storing the month, $temp contains the same timestamp that was input. What am I doing wrong?
You're close. The time should be passed to the localtime function, not the mon method.:
$temp = localtime($1)->mon; # 6
You can use strftime with this to turn it into any arbitrary format
localtime($1)->strftime("%b %d %a"); # Jun 22 Sun
Or if you're not picky about the format you can just stringify it:
$temp = localtime($1);
print "$temp\n"; # Sun Jun 22 13:13:12 2014
This assumes that Time::Piece is loaded.
I'd simply go with
$ perl -E'
use POSIX qw( strftime );
say strftime("%Y/%m/%d %H:%M:%S", localtime(1403457192.663));
'
2014/06/22 13:13:12
But you're using Time::localtime. That module overrides the localtime builtin, so you need a slight modification if you use that.
Either avoid using Time::localtime's localtime
$ perl -E'
use POSIX qw( strftime );
use Time::localtime qw( localtime );
say strftime("%Y/%m/%d %H:%M:%S", CORE::localtime(1403457192.663));
'
2014/06/22 13:13:12
or flatten an existing Time::localtime object.
$ perl -E'
use POSIX qw( strftime );
use Time::localtime qw( localtime );
my $tm = localtime(1403457192.663);
say strftime("%Y/%m/%d %H:%M:%S", #$tm);
'
2014/06/22 13:13:12
All of these solutions lose the millisecond precision. If it's relevant, you'll have to extract it from the original input and reinsert it in the output.
For formatting dates most system strftime manual pages will list a few "shortcuts" to get you certain "standard" formats.
e.g. %F is equivalent to ā%Y-%m-%dā.
~/% perl -MPOSIX -E'say strftime"%D",localtime'
06/25/14
~/% perl -MPOSIX -E'say strftime"%F",localtime'
2014-06-25
These can make using "ye olde" strftime easier ;-)
Perl since 5.10 now contains Time::Piece. This makes it the official way to handle time in Perl. Or, about as official as something gets in Perl. Since it's always available, you might as well learn to use that:
use strict;
use warnings;
use Time::Piece;
use Time::Seconds; # More time fun!
my $time = Time::Piece->new; # Gets the current timestamp
my $month = $time->mon(); # Month from 1 to 12
my $month = $time->month(); # Abbreviation of the name of month
my $month = $time->fullmonth(); # Full name of the month
my $time = $time + (ONE_DAY * 30) # Add thirty days to the time
my $date = $time->mdy # The date 30 days from now.
My platform is Linux. I want the printed date to be formatted as Apr 3, 2014, 5:28 PM when given input such as 2014-04-03T17:28:54.864Z.
My current Perl script.
#!/usr/bin/perl
use lib '/tmp/DateTime/Format';
use DateTime::Format::ISO8601;
my $date = "2014-04-03T17:28:54.864Z";
my $iso8601 = DateTime::Format::ISO8601 -> new;
my $dt = $iso8601->parse_datetime( $date );
print "Date before conversion *******-> \"$date\"\n";
my $s6 = $dt->strftime("%b %-d, %Y, %I:%M %p");
print "Date after conversion *******-> \"$s6\"\n";
It gives the output Apr %-d, 2014, 05:28 PM. When the day of the month or hour is a single digit, I do not want zero or space padding. I want the output as Apr 3, 2014, 5:28 PM when day and hour are each a single digit.
I see no %-d option listed in the valid strftime patterns.
You could use %e to get a leading space instead of a leading zero but, since you discount that, you can get the day independently, then change it and use that changed value within the format string, something like (untested, but you'll get the idea):
# Get day and remove leading zero.
my $dayofmonth = $dt->strftime("%d");
$dayofmonth =~ s/^0//;
# Construct format string from "hard-coded" day.
my $s6 = $dt->strftime("%b " . $dayofmonth . ", %Y, %I:%M %p");
Try this:
my $s6 = $dt->format_cldr('MMM d, Y, h:mm a');
It makes use of the module:
DateTime::Format::CLDR - Parse and format CLDR time patterns
Which you can find documented here.
Because there aren't any strftime patterns for days other than %d and %e, the easy solution is just to edit the result after the fact
$s6 =~ s/\s+/ /g;
This would change your script to the following:
use strict;
use warnings;
use DateTime::Format::ISO8601;
my $date = "2014-04-03T17:28:54.864Z";
my $iso8601 = DateTime::Format::ISO8601->new;
my $dt = $iso8601->parse_datetime( $date );
print qq{Date before conversion *******-> "$date"\n};
my $s6 = $dt->strftime("%b %e, %Y, %I:%M %p");
$s6 =~ s/\s+/ /g;
print qq{Date after conversion *******-> "$s6"\n};
Input:
$str="Thu Mar 25 01:48:45 IST 2011";
Desired output:
2011-03-25
I want only date, not the time.
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $tstamp = Time::Piece->strptime
("Thu Mar 25 01:48:45 2011", "%a %b %d %H:%M:%S %Y");
print $tstamp->strftime("%Y-%m-%d\n");
use Date::Manip;
$str =~ s/[[:upper:]]{3}//; # Remove timezone
$d = ParseDate($str);
die "Invalid date\n" unless $d;
$d=~s/(....)(..)(..).*/$1-$2-$3/;
print "$d\n";
Heck, if you know the format of the date, you don't even need to use a Perl module to manipulate the date and time:
my %months = (Jan => 1, Feb => 2, Mar => 3, Apr => 4 ...);
my $st r= "Thu Mar 25 01:48:45 IST 2011";
$st =~! /\S+\s+(\S+)\s+(\S+)\s+\S+\s+\S+(\S+)/;
my $date = sprintf "%s-%02s-%02s", $3, $months{$1}, $2;
Okay, this is very error prone, and you probably want to do a lot of error checking. The regular expression I used could be formatted a bit stronger (checking for characters and numbers instead of just "not white space". And, you probably want to make sure the month is valid too.
Actually, you're better off using a Date/Time module to do this. I was going to recommend Time::Piece, but James_R_Ferguson beat me to it.
Need help parsing the datetime stamp and splitting it up by date and time.
use strict;
use warnings;
use Time::Piece;
my $string = "05:57:03 08/31/10 MDT";
print $string,"\n";
my $time = Time::Piece->strptime($string, "%H:%M:%S");
my $date = Time::Piece->strptime($string, "%Y/%m/%d");
print $time,$date,"\n";
Thanks! Also how do I figure out which day of week this is using code?
use DateTime::Format::Strptime;
my $s = DateTime::Format::Strptime->new(pattern => '%T %D %Z');
my $dt = $s->parse_datetime('05:57:03 08/31/10 MDT');
say $dt->strftime('%A'); # Tuesday
You should be able to use code like the following:
my $t = Time::Piece->strptime($string, "%H:%M:%S %m/%d/%y %Z");
However, on my system at least, I have to change the time zone MST to GMT for it to match; if I leave it as in your example, I get an error:
Perl> my $t = Time::Piece->strptime("05:57:03 08/31/10 DST", "%H:%M:%S %m/%d/%y %Z");
[!] Runtime error: Error parsing time at /usr/local/lib/perl/5.10.0/Time/Piece.pm line 469.
If it works for you, though, you'll have a Time::Piece object, on which you can call e.g. $t->day_of_week for the day of the week as a number, $t->day for e.g. 'Tue', or $t->fullday for e.g. 'Tuesday'.
See the documentation for Time::Piece for details on the methods you can call.
I am reading in log data with the following time stamp format:
Sat Aug 07 04:42:21 2010
I want to convert it to something like this:
20100807044221
What is the best way to do this in perl? Thanks.
Use Time::Piece. (Core module since Perl 5.10.)
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece;
my $timestamp1 = 'Sat Aug 07 04:42:21 2010';
my $time = Time::Piece->strptime($timestamp1, '%a %b %d %H:%M:%S %Y');
my $timestamp2 = $time->strftime('%Y%m%d%H%M%S');
Date::Parse may not be installed on all your systems, so you may want to use the following snippet:
my ($sec, $min, $hour, $mday, $mon, $year) = localtime();
my $timestamp = sprintf( "%04d%02d%02d%02d%02d%02d",
$year+1900, $mon+1, $mday, $hour, $min, $sec);
print("Timestamp: $timestamp\n");
Timestamp: 20100819135418
This is what Date::Parse is for.
You specify language and corresponding date format, like (copied from the documentation):
$lang = Date::Language->new('German');
$lang->str2time("25 Jun 1996 21:09:55 +0100");
The above will return "epoch" value, AKA unix time value (what you need).
Edit: regarding your post, you only need the canonical date string like yyyy-mmm-ddd etc., therefore you can invoke POSIX::strftime for that. Furthermore, your date format is default, so you won't need the language call:
...
use Date::Parse;
use POSIX qw(strftime);
my $sec = str2time('Sat Aug 07 04:42:21 2010');
my $ymd = strftime "%Y%m%d%H%M%S", gmtime($sec);
print "$ymd\n";
...
Result:
20100807024221
Regards
rbo
perl -MPOSIX -le'print strftime "%Y%m%d%H%M%S", localtime'
never mind, you need to parse it first. that'll just print it out in your format.