Today I find following perl script running incorrect.
Current actual datetime is 20140814 13:19
But it returns: 2014-7-14-13-19-15 (the month value 7 is 1 less than actual value 8)
MY OS: win7
sub GetFileNameDate {
my ($sec,$min,$hour,$day,$month,$yr19,#rest) = localtime;
return sprintf "%s-%s-%s-%02d-%02d-%02d", ($yr19 + 1900), $month, $day, $hour, $min, $sec;
}
It is not incorrect it is like the month values starts from 0
sub GetFileNameDate {
my ($sec,$min,$hour,$day,$month,$yr19,#rest) = localtime;
return sprintf "%s-%s-%s-%02d-%02d-%02d", ($yr19 + 1900), ($month +1), $day, $hour, $min, $sec;
}
$month is the month itself, in the range 0..11 with 0 indicating January and 11 indicating December.
You can check the manual
That is correct according to the docs for localtime:
$mday is the day of the month and $mon the month in the range 0..11, with 0 indicating January and 11 indicating December. This makes it easy to get a month name from a list.
However, to simplify your goal, I'd recommend using Time::Piece:
use strict;
use warnings;
use Time::Piece;
sub GetFileNameDate {
return localtime->strftime("%Y-%m-%d-%H-%M-%S");
}
print GetFileNameDate(), "\n";
Outputs:
2014-08-13-23-42-56
Did you perhaps want POSIX::strftime?
use POSIX qw( strftime );
print strftime "%Y-%m-%d-%H-%M-%S", localtime;
Related
How do I convert 1461241125.31307 in perl. I tried:
use Date::Parse;
$unix_timestamp = '1461241125.31307';
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($unix_timestamp);
$mon += 1;
$year += 1900;
$unix_timestamp_normal = "$year-$mon-$mday $hour:$min:$sec";
result: 2016-4-21 5:18:45 (no padding of hour)
How do I pad it and make it GMT. I want the result to say 2016-04-21 12:18:45
Thanks for the answers folks.
use DateTime;
$unix_timestamp = '1461241125.31307';
my $dt = DateTime->from_epoch(epoch => $unix_timestamp);
print $dt->strftime('%Y-%m-%d %H:%M:%S'),"\n";
Easiest way:
print scalar localtime $unix_timestamp;
Documentation: http://perldoc.perl.org/functions/localtime.html
For GMT, use gmtime:
print scalar gmtime $unix_timestamp;
Documentation: http://perldoc.perl.org/functions/gmtime.html (Basically says: Everything like localtime, but outputs GMT time.)
For custom formats, try DateTime:
use DateTime;
my $dt = DateTime->from_epoch(epoch => $unix_timestamp);
print $dt->strftime('%Y-%s');
See http://search.cpan.org/perldoc?DateTime for all options. Lots of formats could be created even more easily using the predefined DateTime Formatters: http://search.cpan.org/search?query=DateTime%3A%3AFormat&mode=all
use POSIX qw( strftime );
my $epoch_ts = '1461241125.31307';
say strftime('%Y-%m-%d %H:%M:%S', gmtime($epoch_ts));
Use gmtime instead of localtime
perldoc -f gmtime :
gmtime EXPR
gmtime Works just like "localtime" but the returned values are localized
for the standard Greenwich time zone.
Note: When called in list context, $isdst, the last value returned
by gmtime, is always 0. There is no Daylight Saving Time in GMT.
Portability issues: "gmtime" in perlport.
I was wondering if someone could show me how to convert 9/15/12 to 255 format.
Something in php from getdate array you can get ydate.
I think you're asking how you can get the 1 <= yday <= 366 day representation of a date, similar to yday in php's getdate(). As is common in PERL, there's more than one way to do it. The simplest mechanism would be to use localtime() for today's date:
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
If you want to do it for a different date, I'd probably use the TimeDate CPAN module
use Date::Parse;
print time2str("%j",str2time("9/15/2012"));
I think Tawnos's mentioning php's yday from getdate() is on target. Here's one option (assuming 2012 is the year in your date string):
use strict;
use warnings;
use Date::Calc qw/Day_of_Year/;
my $date = '9/15/12';
my ( $month, $day, $year ) = split '/', $date;
my $doy = Day_of_Year( "20$year", $month, $day ) - 1;
print $doy; # (0 - 365)
Output:
258
Do you want the day of the year? That would be day 258 (0-based) or the 259th day (1-based), though. Using only core Perl:
use Time::Local qw( timegm );
my $date = '9/15/12';
my ($m,$d,$y) = split(qr{/}, $date);
my $epoch = timegm(0,0,0, $d,$m-1,$y);
my $yday = ( gmtime($epoch) )[7]; # 258 (0-based index)
Note that timegm+gmtime is applicable no matter the time zone of the date.
Here's another way, using the core module Time::Piece :
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $t = Time::Piece->strptime(shift,"%m/%d/%y");
print $t->yday, "\n";
The day output is zero-relative: January 01 = 0.
my $dt = '9/15/2012';
my ( $m, $d, $y ) = split( '/', $dt );
my $t = POSIX::mktime( 0, 0, 0, $d, $m - 1, $y - 1900 );
say [ localtime $t ]->[7] - 3;
Julian date (minus 1) is slot 7 in the list return from localtime and gmtime.
Why subtract 3? I don't know; Sept 15 is 259 Julian. Still it performs the function mapping '9/15/2012' to 255.
You can use only function strftime from core module POSIX.
use strict;
use POSIX qw(strftime);
print strftime "%j", localtime(time);
Is there a way to figure out the first day of the month (min day) and the last day of a month (max day), given the month as input, using DateTime in perl?
So far, I figured out how to pass in a first date, last date to give me a range of days.
But what I want to do now is just pass in a month as an argument, say 201203 and return min, maxday.
Is that possible with DateTime?
Also, I want to change the date format mask from YYYYMMDD to YYYY-MM-DD.
use strict;
use warnings;
use DateTime;
unless(#ARGV==2)
{
print "Usage: myperlscript first_date last_date\n";
exit(1);
}
my ($first_date,$last_date)=#ARGV;
my $date=DateTime->new(
{
year=>substr($first_date,0,4),
month=>substr($first_date,4,2),
day=>substr($first_date,6,2)
});
while($date->ymd('') le $last_date)
{
print $date->ymd('') . "\n";
#$date->add(days=>1); #every day
$date->add(days=>30);
}
Expected Results:
2012-03-01
2012-03-31
DateTime does date math for you. You can tell ymd which character you want to use as the separator:
use DateTime;
my( $year, $month ) = qw( 2012 2 );
my $date = DateTime->new(
year => $year,
month => $month,
day => 1,
);
my $date2 = $date->clone;
$date2->add( months => 1 )->subtract( days => 1 );
say $date->ymd('-');
say $date2->ymd('-');
There are many examples in "Last day of the month. Any shorter" on Perlmonks, which I found by Googling "perl datetime last day of month".
And here's a Time::Moment example. It's a leaner, faster subset of DateTime:
use v5.10;
use Time::Moment;
my( $year, $month ) = qw( 2012 2 );
my $tm = Time::Moment->new(
year => $year,
month => $month,
day => 1,
);
my $tm2 = $tm->plus_months( 1 )->minus_days( 1 );
say $tm->strftime('%Y-%m-%d');
say $tm2->strftime('%Y-%m-%d');
It is surprising, that neither DateTime example uses the special constructor last_day_of_month for that (example courtesy of brian d foy):
use DateTime;
use strict;
use 5.010;
my( $year, $month ) = qw( 2012 2 );
my $date = DateTime->new(
year => $year,
month => $month,
day => 1,
);
my $date2 = DateTime->last_day_of_month(
year => $date->year,
month => $date->month,
);
say $date->ymd('-');
say $date2->ymd('-');
As an alternative there is the core Perl module Time::Piece.
For the current month and year:
perl -MTime::Piece -wE '$t=localtime;say $t->month_last_day'
31
More generally, something like:
use 5.010;
use Time::Piece;
my $MY = shift || die "Month and Year expected\n";
my $t = Time::Piece->strptime($MY, "%m%Y");
say $t->month_last_day;
$ ./mycode 022012
29
First day:
$dt->set_day(1);
Last day:
$dt->set_day(1)->add( months => 1 )->subtract( days => 1 );
While the DateTime class offers a constructor to do this, the most efficient way to get the last day of the month from an existing DateTime object is to request the object to calculate it. The class exposes an undocumented method _month_length() that calculates the last day of the month very efficiently. With your DateTime object called $date, you can try
$date->_month_length($date->year,$date->month);
This method is undocumented, so it may or may not be supported in your version of DateTime. Use with caution.
UPD
Starting from v1.144 DateTime starts to support month_lenth
History of the issue
How to convert date format YYYY-MM-DDTHH:MM:SSZ to YYYY-MM-DD HH:MM + 8 hours?
For example:
Input: 2011-07-07T18:05:45Z
Output: 2011-07-08 02:05
Let's start with Rahul's snippet, and add in the date math and output formatting...
use DateTime;
use DateTime::Format::ISO8601;
use DateTime::Format::Strptime;
my $string = '2011-07-07T18:05:45Z';
my $dt = DateTime::Format::ISO8601->parse_datetime( $string );
die "Impossible time" unless $dt;
my $formatter = new DateTime::Format::Strptime(pattern => '%Y-%m-%d %T');
$dt->add( hours => 8 )->set_formatter($formatter);
print "$dt\n";
I've added the use of DateTime::Format::Strptime, in order to specify the desired output format.
Then I've added three more lines:
First I create a formatter, and feed it the output pattern I desire.
Next I add eight hours to the original date, and I assign the output
formatter by chaining the set_formatter() call to the add() call.
Then I print it.
Are you using the DateTime modules?
Specifically, here's a link to DateTime::Format::ISO8601 that reads/writes ISO 8601 format you mentioned as your input.
If you don't have DateTime, you surely have Time::Piece:
use strict;
use warnings;
use Time::Piece;
use Time::Seconds qw(ONE_HOUR);
my $str = '2011-07-07T18:05:45Z';
my $t = Time::Piece->strptime($str, "%Y-%m-%dT%TZ");
$t += 8 * ONE_HOUR;
print $t->strftime("%Y-%m-%d %H:%M"),"\n";
Taken From
How can I validate a "yyyy-MM-dd'T'HH:mm:ssZ" date/timestamp in UTC with Perl?
use DateTime;
use DateTime::Format::ISO8601;
my $string = '2010-02-28T15:21:33Z';
my $dt = DateTime::Format::ISO8601->parse_datetime( $string ); die "Impossible time" unless $dt;
It doesn't work, result is 2010-02-28T15:21:33
Then, do it the hard way...
use Time::Local
use warnings;
use strict;
$time = '2010-02-28T15:21:33Z';
my ($year, month, day) = split (/-/, $time)
$year -= 1900; #Year is an offset of 1900
$month -= 1; #Months are 0 - 11
#Now split the time off of the day (DDTHH:MM:SS)
$day = substr($day, 0, 2);
time = substr($day, 3)
#Now split the time
(my $hour, $minute, $second) = split(/:/, $time);
$second =~ s/Z$//; #Remove Z
my $time_converted = timelocal($second, $minute, $hour, $day, $month, $year);
#Now you have the time, Add eight hours
my $hours_in_seconds = 8 * 60 * 60;
$time_converted += $hours_in_seconds;
# Almost done: Convert time back into the correct array:
($second, $minute, $hour, $day, $month, $year) = localtime($time_converted);
$year += 1900;
$month += 1;
# Now, reformat:
my $formatted_time = sprint (%04d-%02d-%02d %02d:%02d),
$year, $month, $day, $hour, $minute;
For example: from date: 10/02/2010
How do I convert an equal timestamp for 10/02/2010 00:00:00 in Perl?
I can't use local time or time .. is there another way to achieve this?
You can use the Time::Local core module:
use Time::Local 'timelocal';
my ($d, $m, $y) = split '/', '10/02/2010';
my $time = timelocal(0, 0, 0, $d, $m-1, $y);
Note that the month argument for timelocal() is in the range 0..11.
Without localtime():
use Time::Local;
$time = timelocal($sec, $min, $hour, $mday, $mon, $year);
(See perldoc.)
A standard way would be something like:
use POSIX;
use strict;
use warnings;
my $sec = 0;
my $min = 0;
my $hour = 0;
my $day = 10;
my $mon = 2 - 1;
my $year = 2010 - 1900;
my $wday = 0;
my $yday = 0;
my $unixtime = mktime ($sec, $min, $hour, $day, $mon, $year, $wday, $yday);
print "$unixtime\n";
my $readable_time = localtime($unixtime);
print "$readable_time\n"
(From Converting Unix time and readable time with Perl)
You could use Date::Parse:
use Date::Parse;
print str2time('10/02/2010 00:00:00');
On my machine this prints 1285970400, which corresponds to October 2nd, 2010 (I live in +1 GMT with +1 Wintertime.)
I think you want the built-in module Time::Local.
The DateTime module should be helpful here. In particular, I believe the DateTime::Format::Natural module can parse a user-supplied date string. From there, you have a DateTime object and can print it out or transform it as you like.
Depending on where your initial date is coming from you might be able to parse it using
Date::Manip
and calling
ParseDate("10/02/2010")
You can then take that output and convert it into whatever format you wish.