converting tcl to perl to format date time - perl

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.

Related

Converting timestamps in Perl

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

Error when dealing with old and historical dates in Perl Time::Piece

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).

18 digit julian timestamp in perl

I need to get 18-digit Julian Timestamp in my perl script. Could anyone help me in this? However I have written a subroutine to achieve this but it does not look good to me since it always gives me a number ending with 6 zeroes. Please help to get a proper 18-digit J-timestamp.
sub GetJulianTimestamp()
{
my $t = `perl -e 'print time, "\n"'`;
return (($t * 1000000 ) + 210866803200000000);
}
Based on the comments, you appear to be asking how to obtain the number of microseconds since the unix epoch.
use Time::HiRes qw( );
my $microsec_time = int( Time::HiRes::time() * 1_000_000 );
return 210866803200000000 + $microsec_time;
I agree with the answer given by ikegami, except the amount to be added to the unix epoch needs to be changed. The value 210866803200000000 corresponds to November 24, 4714 BC, 00:00 Universal Time, Gregorian proleptic calendar. But the epoch of Julian dates is at noon, not midnight. So the amount to be added should be 210,866,760,000,000,000. And of course there is no official name for a Julian date that has been converted to microseconds, so anyone using such a number would have to provide an explanation to anyone who is receiving the data.

Perl workweek conversion is incorrect

I'm faced a weird problem.
I have date in form of Tue Feb 25 00:20:13 2014.
my task is to calculate the week number and the week day.
I tried the following
use Time::Piece;
my $date="Tue Feb 25 00:20:13 2014";
my $db_date=Time::Piece->strptime($date, "%a %b %d %H:%M:%S %Y");
my $ww=$db_date->strftime("%W.%w-%Y);
print $ww;
When I run the script I get the output as
08.2-2014
which is wrong, the expected output is
09.2-2014
I want to know where did i go wrong?
pls help...
You're using the "%W" strftime() conversion. Time::Piece doesn't specify the meaning of "%W", but the documentation for the equivalent C function says that "%W" starts counting with the first week that contains a Monday. It sounds like you want the ISO 8601 week number, which starts counting with the first week that contains at least four days, in which case the "%V" conversion should do what you want.

How to get seconds of given timezone - UTC time in Perl

I have a file with lines of the form : 1311597859.567497 y_value_to_plot. The first token is time since epoch, i.e. unix time. The user wants to call plot_file.pl with this filename and a timezone specification such as "America/New_York" or "Europe/London". Calling gnuplot on this file with set xdata time; set timefmt "%s" works but it shows the hours in UTC time. But the user would like to see the local time. So for 1311597859.567497, without any timezone changes, gnuplot would show 12:44:19, but if the user specifies America/New_York, he would like to see 08:44:19 in the gnuplot window.
I though a simple fix would be to calculate the offset between utc and the given timezone and subtract that from the token, and then run new plot on this new file.
Hence I was looking for a way to get offset_seconds of UTC from a given timezone in Perl.
By unix time I assume you mean seconds since the epoch in local time and you are trying to convert to seconds since the epoch in UTC.
Consider using a module such as Time::Zone or DateTime::TimeZone (part of DateTime) to help with such a calculation.
For example with Time::Zone:
use Time::Zone;
my $offset_sec = tz_local_offset(); # or tz_offset($tz) if you have the TZ
# in a variable and it is not local
my $time = time(); # realistically it will be the time value you provide in localtime
my $utc_time = $time + $offset_sec;
With DateTime and DateTime::TimeZone:
use DateTime;
use DateTime::TimeZone;
# cache local timezone because determining it can be slow
# if your timezone is user specified get it another way
our $App::LocalTZ = DateTime::TimeZone->new( name => 'local' );
my $tz = DateTime::TimeZone->new( name => $App::LocalTZ );
my $dt = DateTime->now(); # again, time will be whatever you are passing in
# formulated as a DateTime
my $offset = $tz->offset_for_datetime($dt);
Note that using DateTime you can simply convert a DateTime object from local time to UTC time via set_time_zone('UTC') and then format it for gnuplot also.
To do it all by hand, you can format the output of gmtime if you can get to epoch seconds from your local time (perhaps using mktime out of a date/time string).