I am looking to convert timestamps such as the following
2019-01-01T02:15:00+00:00
Into Australian Eastern Standard Time in Perl.
I have over 10,000 of these timestamps, any help would be really appreciated
I need to input them into a mysql DB with a format of YYYY-MM-DD hh:mm:ss
You would use the standard Perl module Time::Piece. It provides the standard strptime and strftime functions. The first allows you to parse a timestamp with a template and the second outputs a timestamp based on the same kind of template. To change timezones you would add or subtract the number of seconds difference.
$t = Time::Piece->strptime("2020-11-04T01:46:00", "%Y-%m-%dT%H:%M:%S");
$t += $offset;
print $t->strftime("%Y-%m-%dT%H:%M:%S");
Or if your current time is the current locale and you're always converting from GMT:
$t = Time::Piece->strptime("2020-11-04T01:46:00", "%Y-%m-%dT%H:%M:%S");
$l = localtime $t->epoch;
print $l->strftime("%Y-%m-%dT%H:%M:%S");
Now if you need to do something more complicated than that (daylight savings time, leap seconds), there is the DateTime module but it is correspondingly far more complicated to use.
See also How can I parse dates and convert time zones in Perl?
HTH
Related
My collegue (who has left the company) has written a bunch of scripts, including batch and Perl scripts, and I'm getting rid of the regional settings dependencies.
In the last Perl script, he's written the following piece of code:
my $format = "%d.%m.%Y %H:%M";
my $today_converted = Time::Piece->strptime($today, $format) - ONE_HOUR - ONE_HOUR - ONE_HOUR - ONE_HOUR - ONE_HOUR;
(the idea is to get five hours before midnight of that particular date)
The value of $today seems to be "03/04/2017" (which stands for the third of April (European dateformat)), which seems not to be understood by Time::Piece implementation:
Error parsing time at C:/Perl64/lib/Time/Piece.pm line 481.
Which format can I use which is understood by Time::Piece Perl implementation?
In the format you have dots . as the date delimiter, but in the data you have slashes /. That's why it doesn't parse. It needs an exact match.
I think it's worth clarifying that strptime() will parse most date and time formats - that's the point of the method. But you need to define the format of the date string that you are parsing. That's what the second parameter to strptime() (in this case, your $format variable) is for.
The letters used in the format are taken from a standard list of definitions which used by every implementation of strptime() (and its inverse, strftime()). See man strptime on your system for a complete list of the available options.
In your case, the format is %d.%m.%Y %H:%M - which means that it will parse timestamps which have the day, month and year separated by dots, followed by a space and the hours and minutes separated by a colon. If you want to parse timestamps in a different format, then you will need to change the definition of $format.
It seems Time:Piece gives me this error:
Error parsing time at /usr/lib/perl5/site_perl/Time/Piece.pm line 481.
after the line where I use strptime with some old dates.
My code contains this:
my $ddate = "$month / $day / $year";
my $tmp = Time::Piece->strptime( $ddate, "%m / %d / %Y");
and $$date takes dates from a database using DBI that contains historical and old dates (dates back to the 10th and 9th centuries AD). How can I deal with this if there is any solution?
You'll have to use something other than Time::Piece if you want to deal with timestamps before 1970.
If you want to use the Gregorian calendar, you can use DateTime.
If you want to use the Julian calendar, you can use DateTime::Calendar::Julian.
The Gregorian calendar was introduced in September, 1582, and it was used universally by 1918. In between, calendar usage varied by country.
$ perl -MDateTime::Calendar::Julian -E'
say
DateTime::Calendar::Julian->new(year => 1013, month => 2, day => 22)
->strftime("%a");
'
Sun
Alternatively, Date::Convert looks promising if you're just care about dates (not timestamps).
perl code:
#!/bin/env perl
use DateTime;
print DateTime->now;
OUTPUT:
2013-01-28T06:02:33
what's mean of 'T' letter in the output string ?
ISO8601 and RFC3339 both use "T" to join the date and the time, and DateTime's default stringifier apparently adopted that convention. If you want another format, you can use one of the DateTime::Format::* modules or ->strftime.
my $now = DateTime->now( time_zone => 'local' );
say $now->strftime('%Y-%m-%d %H:%M:%S');
It stands for "Time". You can read more at:
http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations
It's the separator between date and time in ISO 8601. It's always a T in this format.
The character [T] shall be used as time designator to indicate the start of the representation of the time of day
component in these expressions. The hyphen [-] and the colon [:] shall be used, in accordance with 4.4.4, as
separators within the date and time of day expressions, respectively, when required.
NOTE By mutual agreement of the partners in information interchange, the character [T] may be omitted in
applications where there is no risk of confusing a date and time of day representation with others defined in this
International Standard.
--Data elements and interchange
formats — Information interchange —
Representation of dates and times, ISO 8601:2004(E)
I need to convert my TCL script to perl, i know bit of perl but not much:
I needed to convert this line to perl:
set current [clock format [clock scan "1 hour ago" -base [clock seconds]] -format "%Y-%m-%d %H"]
It prints the current date and 1 hour behind( Since the server returns EST, i want CST).
For example if today's date was 07/31/2012 and the time was 4:20pm(5:20pm EST) it would print
2012-07-31 16
The server returns eastern time, therefore I want it to print 1 hour ago to adjust to central time.
Note : it should not print 16:20.
Try this:
use POSIX qw/strftime/;
print strftime('%Y-%m-%d %H', localtime);
# prints 2012-07-31 14 for me, currently
EDIT: If you have to get this format for one hour ago, then do this instead:
use POSIX qw/strftime/;
my $hour_ago = time() - (60*60);
print strftime('%Y-%m-%d %H', localtime($hour_ago));
# prints 2012-07-31 13 for me, currently
And if it's a time zone issue, you might want consider dealing with the time zone explicitly, rather than assuming a one hour offset. Here's an article on handling time zones in Perl.
In Perl, localtime takes a Unix timestamp and gives back year/month/day/hour/min/sec etc. I'm looking for the opposite of localtime: I have the parts, and I'd like to build a unix timestamp from them.
You can use the timelocal function in the Time::Local CPAN module.
NAME
Time::Local - efficiently compute time
from local and GMT time
SYNOPSIS
$time = timelocal($sec,$min,$hour,$mday,$mon,$year);
$time = timegm($sec,$min,$hour,$mday,$mon,$year);
DESCRIPTION
This module provides functions that
are the inverse of built-in perl
functions localtime() and gmtime().
They accept a date as a six-element
array, and return the corresponding
time(2) value in seconds since the
system epoch (Midnight, January 1,
1970 GMT on Unix, for example). This
value can be positive or negative,
though POSIX only requires support for
positive values, so dates before the
system's epoch may not work on all
operating systems.
It is worth drawing particular
attention to the expected ranges for
the values provided. The value for the
day of the month is the actual day (ie
1..31), while the month is the number of months since January (0..11). This
is consistent with the values returned
from localtime() and gmtime().
Note: POSIX::mktime is a just a wrapper around your C library's mktime() function. Time::Local is a pure-Perl implementation, and always returns results matching Perl's localtime. Also, Time::Local offers gmtime, while mktime only works in local time. (Well, you could try changing $ENV{TZ}, but that doesn't work on some systems.)
POSIX::mktime
DateTime on CPAN might of of some use. It also has a lot of time manipulation/translation methods.
Just create the DateTime using your parts and call $datetime->formatter("%s") ;