在Perl中将给定时间转换为站点特定时间

kpbwa7wx  于 2023-05-18  发布在  Perl
关注(0)|答案(1)|浏览(204)

我已经写了一个脚本,将给定的时间转换为网站的特定时间。我有两个网站(前。伦敦和班加罗尔- VM的)。
以下是我的脚本:

#!/usr/bin/perl
use strict;
use warnings;
use Date::Parse;
use DateTime;
use Date::Format;
use Time::Local;

my $id = "BAN";

my %time_zone_hash = (
        'LON' => 'Europe/London',
        'BAN' => 'Asia/Kolkata',
);

my $bang_time = convertSiteSpecificTime($id, "2023-05-15 04:30:00");
print "time:$bang_time\n";

print "time in readable format:".localtime($bang_time)."\n";

sub convertSiteSpecificTime {
        my $id = shift;
        my $time_str = shift;
        my $epoch_time = str2time(time2str("%Y-%m-%d %T", str2time($time_str)));

        if (!$epoch_time) {
                print "'$time_str' is not a valid date. Please provide a valid date.\n";
                exit(1);
        }
        my $dt = DateTime->from_epoch(epoch => $epoch_time);
        $dt->set_time_zone($time_zone_hash{$id});

        print "dt: $dt\n";
        return $dt->epoch();
}

当前结果:

dt: 2023-05-15T09:00:00
time:1684121400
time in readable format:Mon May 15 04:30:00 2023

预期结果:

dt: 2023-05-15T09:00:00
time:1684121400
time in readable format:Mon May 15 09:00:00 2023

所以,目前我在伦敦VM和运行这个脚本。因此,时间(2023-05-15 04:30:00)应该转换为班加罗尔特定时间,因为我已经将$id值初始化为BAN
print "time:$bang_time\n";行中的结果打印出正确的unixtime。即1684121400。但人类可读格式的时间在print "time in readable format:".localtime($bang_time)."\n";行打印不如预期。这里的问题是我在时间转换过程中使用了localtime
是否有任何方法可以让我得到预期结果中提到的预期结果。

n1bvdmb6

n1bvdmb61#

如果我把你的问题归结为我认为你在问的问题,那就是
如何让localtime使用Asia/Kolkata
它使用TZ env var。

for my $tz (qw(
   UTC
   Europe/London
   Asia/Kolkata
   America/Halifax
)) {
   local $ENV{ TZ } = $tz;
   say sprintf "%-16s %s", "$tz:", "".localtime( 1684121400 );
}
UTC:             Mon May 15 03:30:00 2023
Europe/London:   Mon May 15 04:30:00 2023
Asia/Kolkata:    Mon May 15 09:00:00 2023
America/Halifax: Mon May 15 00:30:00 2023

既然你已经在使用DateTime,让我给你一个更干净的解决方案。

use DateTime::Format::Strptime qw( );

my $format = DateTime::Format::Strptime->new(
   pattern   => "%F %T",
   strict    => 1,
   time_zone => "Europe/London",
   on_error  => "croak",
);

my $dt = $format->parse_datetime( "2023-05-15 04:30:00" );
say $dt->epoch();
say $dt->strftime( "%FT%T%z" );

$dt->set_time_zone( "Asia/Kolkata" );
say $dt->epoch();
say $dt->strftime( "%FT%T%z" );
1684121400
2023-05-15T04:30:00+0100
1684121400
2023-05-15T09:00:00+0530

再次使用Time::Piece。它比DateTime要轻得多,但使用起来更复杂。

use Time::Piece qw( localtime );

my $dt;

{
   local $ENV{ TZ } = "Europe/London";
   $dt = localtime->strptime( "2023-05-15 04:30:00", "%F %T" );
   say $dt->epoch();
   say $dt->strftime( "%FT%T%z" );
}

{
   local $ENV{ TZ } = "Asia/Kolkata";
   say $dt->epoch();
   say $dt->strftime( "%FT%T%z" );
}
1684121400
2023-05-15T04:30:00+0100
1684121400
2023-05-15T09:00:00+0530

相关问题