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

问题描述 投票:0回答:1

我写了一个脚本,将给定时间转换为特定于站点的时间。 我有两个站点(例如伦敦和班加罗尔 - 虚拟机)。

这是我的脚本:

#!/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

有什么方法可以得到预期结果中提到的预期结果。

datetime perl timezone
1个回答
2
投票

如果我把你的问题归结为我认为你在问什么,那就是

如何让

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.

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
© www.soinside.com 2019 - 2024. All rights reserved.