簡體   English   中英

如何在 Perl 中轉換時區?

[英]How I can I convert timezones in Perl?

我正在嘗試在 Perl 中將日期/時間 GMT 0 轉換為 GMT -6。

例如,DHCP 服務器租用時間的格式如下:

2010/02/18 23:48:37

我正在嘗試將該時間轉換為本地時區(GMT -6),但需要它來遵守夏令時。

下面的腳本可能有點矯枉過正,但我​​不知道如何從這里開始。 (任何建議都會很棒)。

my $TIMESTART;

$TIMESTART = "2010/02/18 23:48:37";
$TIMESTART =~ s/\//-/g;

use DateTime;
use DateTime::TimeZone;

use DateTime::Format::MySQL;
my $dt = DateTime::Format::MySQL->parse_datetime($TIMESTART);

my $tz = DateTime::TimeZone->new( name => 'America/Chicago' );

print $tz->offset_for_datetime($dt) . "\n";

它將輸出以下行:

2010-02-18T23:48:37
-21600

我需要能夠將 -21600 添加到日期以獲得 GMT -6 的本地時區,但我不知道如何解決這個問題。

調用set_time_zone方法2次:

my $dt = DateTime::Format::MySQL->parse_datetime($TIMESTART);
$dt->set_time_zone('UTC'); ## set timezone of parsed date time
$dt->set_time_zone('America/Chicago'); ## change timezone in safe way

print DateTime::Format::MySQL->format_datetime($dt),"\n"; ## check the result

這個怎么運作:

  • 當您創建沒有指定時區的DateTime對象時,將設置“浮動”時區
  • 第一次調用set_time_zone將時區更改為UTC而不進行轉換
  • 第二次調用set_time_zoneUTC更改為America/Chicago

這會將UTC時間轉換為ETC時間。 您還可以使用日期的+ FORMAT參數以任何格式使用日期/時間。

date --date ='TZ =“ETC”18:30'

Time::Piece是一個非常輕量級的優質代碼。 或者你可以使用內置POSIX::strptimestrftime以及POSIX::strptime

不要在 `DateTime::Format::MySQL->parse_datetime` 中使用時區

在做任何與時區相關的事情時,你不應該使用它是有充分理由的。 為什么? 因為它絕對不支持任何時區。 請參閱文檔:

所有的解析方法都將返回的 DateTime 對象的時區設置為浮動時區,因為 MySQL不提供時區信息。 (來源: MetaCPAN:DateTime::Format::MySQL 。)

使用 `DateTime->new()`,因為它確實支持時區

使用DateTime直接提供的構造函數(來源: MetaCPAN: DateTime 。):

my $dt = DateTime->new(
    year       => 1966,
    month      => 10,
    day        => 25,
    hour       => 7,
    minute     => 15,
    second     => 47,
    nanosecond => 500000000,
    time_zone  => 'America/Chicago',
);

使用 DateTime 轉換時區

您的起始時區是您輸入構造函數的任何內容(即,上面示例中的America/Chicago )。 要將時間轉換為結束時區,請使用set_time_zone()

工作代碼

在下面的代碼中,時間從一個時區轉換到另一個時區,並且每次都完美地執行此操作,即使運行它的 Web 服務器是在新加坡時間執行此操作。

use strict;
use DateTime;

sub convertTimeZonesForTime {
        my ($args) = @_;

        my $time = $args->{time};
        my $date = $args->{date};
        my $totimezone = $args->{totimezone};
        my $fromtimezone = $args->{fromtimezone};
        my $format = $args->{format} || '%H:%M:%S';

        my ($year, $month, $day) = map {int $_} split('-', $date);
        my ($hour, $minute, $second) = map {int $_} split(':', $time);

        $year ||= 1999;
        $month ||= 1;
        $day ||= 1;
        $hour ||= 12;
        $minute ||= 30;
        $second ||= 0;


        my $dt = DateTime->new(
                year=>$year,
                month=>$month,
                day=>$day,
                hour=>$hour,
                minute=>$minute,
                second=>$second,
                time_zone => $fromtimezone,
        );
        my $formatter = new DateTime::Format::Strptime(pattern => $format);
        $dt->set_formatter($formatter);
        $dt->set_time_zone($totimezone);

        return "$dt";
}

print(convertTimeZonesForTime({
    'totimezone'=>'America/Denver',
    'fromtimezone'=>'US/Eastern',
    'time'=>'12:30:00',
}));

輸出:

10:30:00

#!/usr/bin/perl -w
($sec,$min,$hour,$mday,$mon,$year) = gmtime(time+21600);
$year = $year + 1900;
printf("%02d:%02d:%02d %02d.%02d.%04d\n", $hour,$min,$sec,$mday,$mon,$year);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM