How to convert text date to timestamp? - perl

How to convert date in text format:
23.10.2011 11:35:00
to timestamp ?

Using Time::Local , you can do:
use Time::Local;
my $date = '23.10.2011 11:35:00';
my ($mday,$mon,$year,$hour,$min,$sec) = split(/[\s.:]+/, $date);
my $time = timelocal($sec,$min,$hour,$mday,$mon-1,$year);
print $time,"\n",scalar localtime $time;
Output:
1319362500
Sun Oct 23 11:35:00 2011

I'd look into DateTime and the parsing modules.
perl -MDateTime::Format::Strptime -le'$strp = DateTime::Format::Strptime->new( pattern => "%d.%m.%Y %T", time_zone => "local"); $dt = $strp->parse_datetime("23.10.2011 11:35:00"); print $dt->epoch'
1319384100 at -e line 1.
Same as above, but not a one-liner:
use DateTime::Format::Strptime;
my $strp = DateTime::Format::Strptime->new(
pattern => '%d.%m.%Y %T',
time_zone => 'local',
);
my $dt = $strp->parse_datetime('23.10.2011 11:35:00');
print $dt->epoch;

Using Date::Parse in Perl is very elegante option too.
Maybe someone will found this useful:
$gmtdate = 'Jul 12 00:12:26 2021 GMT';
my $timestamp = str2time($gmtdate);

Not sure why the Time::Piece answer was deleted. Maybe because it (Time::Piece) has its quirks. But it's more powerful than Date::Parse (although less powerful than DateTime, but some say it covers most of the needs), it's a core module, and you don't have to parse the string as with Time::Local. But datetime math is apparently not DST-safe.
Long story short:
use Time::Piece;
my $tp = Time::Piece->strptime("23.10.2011 11:35:00",
"%d.%m.%Y %H:%M:%S");
# or this way (if the timestamp is in the local time zone):
# $tp = localtime->strptime("23.10.2011 11:35:00",
# "%d.%m.%Y %H:%M:%S");
print $tp;
More on creating Time::Piece objects here.

Related

Perl - date calculation

I'm new in Perl. I want to calculate days (e.g. 5 days) after input.
Steps I need to cover:
1. start_date: 08.12.2015
2. add 5 days
3. end date: ?
My idea is to convert the start date into a timestamp. Then I add 5*84.400 seconds. After that, I want to re-convert the end timestamp.
I read the Time::Local module docs, but I did not understand the logic yet.
Is this the right way to handle date calculations?
You can do it using DateTime and DateTime::Format::Strptime. Like this:
use strict;
use DateTime;
use DateTime::Format::Strptime;
my $strp = DateTime::Format::Strptime->new(
pattern => '%d.%m.%Y'
);
my $date = '08.12.2015';
my $dt = $strp->parse_datetime($date);
printf "%s -> %s\n", $date, $dt->add(days => 5)->strftime("%d.%m.%Y");
Using Time::Piece
#!/usr/bin/env perl
use v5.10;
use Time::Piece;
use Time::Seconds;
my $date_string = '08.12.2015';
my $date_format = '%m.%d.%Y';
my $tp = Time::Piece->strptime( $date_string, $date_format );
$tp += 5 * ONE_DAY;
say $tp->strftime($date_format);
Outputs:
08.17.2015
Or another way, in vanilla perl (no use of packages needed), with help from Unix date:
$ date -d 08/12/2015
Wed, Aug 12, 2015 12:00:00 AM
$ date -d 08/12/2015 +%s
1439352000
$ date -d 08/12/2015 +%s|perl -ne 'print scalar localtime $_ + 5*24*60*60'
Mon Aug 17 00:00:00 2015

How to convert unknown date/time format into normal using Perl? [duplicate]

This question already has answers here:
How can I parse dates and convert time zones in Perl?
(5 answers)
Closed 7 years ago.
I have a date/time like this: 2015-07-31T13:30:00.000+01:00
And I want to convert it to normal date and time using Perl and Time::Piece->strptime
Here is my code:
sub changeDateFormat {
my ($date, $fromFormat, $toFormat) = (#_);
return Time::Piece->strptime($date, $fromFormat)->strftime($toFormat);
}
The call:
print changeDateFormat($that_date, '%Y-%m-%dT%H:%M:%S.%N+%z', '%Y:%m:%d');
I think that .000 are nano seconds and +01.00 stands for time zone.
But the given code gives this:
Error parsing time at /usr/lib64/perl5/Time/Piece.pm line 470
Any help is appreciated.
There's a couple of problems I think.
%N isn't in my strftime manpage. So that might well not work.
And %z - I'm pretty sure +01:00 isn't valid.
%z The +hhmm or -hhmm numeric timezone (that is, the hour and
minute offset from UTC). (SU)
This works though:
my $date = '2015-07-31T13:30:00+0100';
my $fromFormat = '%Y-%m-%dT%H:%M:%S%z';
print Time::Piece->strptime($date, $fromFormat);
So I'd suggest - unless your milliseconds are important - you could just strip those via a regex, and likewise the timezone. (And it they are important, I don't think Time::Piece does ms resolution anyway)
You can probably use a regular expression to 'correct' your input date if you were so inclined. I'm unsure if fits your use case but:
$date =~ s/\+(\d{2}):(\d{2})$/+$1$2/;
$date =~ s/\.\d{3}+/+/;
You can use strptime in Time::Piece and adding the time zone manually as shown in this answer, or you could try using DateTime::Format::Strptime instead:
use feature qw(say);
use strict;
use warnings;
use DateTime::Format::Strptime;
my $timestamp = '2015-07-31T13:30:00.000+0100';
my $strp = DateTime::Format::Strptime->new(
pattern => '%Y-%m-%dT%H:%M:%S.%N%z'
);
my $dt = $strp->parse_datetime( $timestamp );
say $dt->strftime('%Y:%m:%d');
Output:
2015:07:31
use DateTime;
use DateTime::Format::ISO8601;
use DateTime::Format::Strptime;
my $string = '2015-07-31T13:30:00.000+01:00';
my $date = DateTime::Format::ISO8601->parse_datetime( $string );
die "Error" unless $date;
my $formatter = new DateTime::Format::Strptime(pattern => '%Y-%m-%d %T');
$date->set_formatter($formatter);
print "$date\n";

Simple way to format date

I wrote a perl script to get datetime.
It do work but I do wonder if there any easier way to format date as output.
#!/usr/bin/perl
use DateTime;
my $dt = DateTime->now( time_zone => 'local' );
$myTimeStamp = $dt->subtract( days => 1 );
$myYear = $myTimeStamp->year;
$myMonth = $myTimeStamp->month;
if ( length( $myMonth ) == 1 ) {
$myMonth = "0$myMonth";
}
$myDay = $myTimeStamp->day;
if ( length( $myDay ) == 1 ) {
$myDay = "0$myDay";
}
$myHour = $myTimeStamp->hour;
if ( length( $myHour ) == 1 ) {
$myHour = "0$myHour";
}
#$myDir = "/var/tmp/logs/$myYear/$myMonth/$myYear$myMonth-";
print "--> $myYear $myMonth $myDay $myHour\n";
# --> 2012 02 28 02
exit 0;
DateTime provides the format_cldr method for this:
use DateTime;
my $myTimeStamp = DateTime->now->subtract( days => 1 );
printf "--> %s\n", $myTimeStamp->format_cldr('yyyy MM dd HH');
# --> 2012 02 28 02
Sure, use POSIX module:
The POSIX module permits you to access all (or nearly all) the
standard POSIX 1003.1 identifiers.
Example:
use POSIX;
print POSIX::strftime('%d-%m-%Y %H:%M:%S', localtime());
First of all always use strict; and use warnings; at the start of your program and declare all your variables close to their first use. This applies especially if you are seeking help as it will find a lot of simple errors that aren't immediately obvious.
It is best to use printf if you want to zero-pad any output. There is also no need to extract the date fields to separate variables. Is the output you have shown the one you ultimately want? This program does the same thing as the code you have posted.
use strict;
use warnings;
use DateTime;
my $myTimeStamp = DateTime->now->subtract( days => 1 );
printf "--> %04d %02d %02d %02d\n", map $myTimeStamp->$_, qw/year month day hour/;
OUTPUT
--> 2012 02 28 12
For re-formatting dates, as noted, there is the POSIX core module. You would be remiss not to look at the core module Time::Piece too, which not only delivers strftime() but also strptime() to provide very flexible date/time parsing. Time::Piece appeared in Perl core in 5.9.5.

How do I convert datetime to a different format? [perl]

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.

Parsing dateTime in perl correct to micro/nano seconds

Im looking for a perl module which takes a date string like this "Nov 23 10:42:31.808381" and its format something like "%b %d ...." this and get me a dateTime object/or print it into another format specified in the same way. Time::Piece doesnt have resolution upto nano seconds. Is there any module which will help me?
Im using perl 5.8 (this doesnt have named backreferences)
DateTime::Format::Strptime has support for microseconds and nanoseconds.
Your format is slightly strange as it doesn't include a year. I've added one you make this demo code work.
#!/usr/bin/perl
use strict;
use warnings;
use DateTime::Format::Strptime;
my $strp = DateTime::Format::Strptime->new(
pattern => '%b %d %Y %H:%M:%S.%6N',
on_error => 'croak',
);
my $string = 'Nov 23 2010 10:42:31.808381';
my $dt = $strp->parse_datetime($string);
print $dt->microsecond;
"Nov 23 10:42:31.808381" -- is microseconds, not nanoseconds
If you need microseconds, you must use Time::HiRes; module and gettimeofday method in it.