如何在 Perl 中更改日期时间值的时区?

发布于 2024-08-19 12:17:35 字数 215 浏览 7 评论 0原文

使用此函数:

perl -e 'use Time::Local; print timelocal("00","00","00","01","01","2000"),"\n";'

它将返回一个纪元 - 但仅限于 GMT - 如果我想要 GMT+1 的结果(即系统本地时间(TZ)),我需要更改什么?

预先感谢,

安德斯

Using this function:

perl -e 'use Time::Local; print timelocal("00","00","00","01","01","2000"),"\n";'

It will return an epochtime - but only in GMT - if i want the result in GMT+1 (which is the systems localtime(TZ)), what do i need to change?

Thanks in advance,

Anders

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

蓝颜夕 2024-08-26 12:17:35
use DateTime;
my $dt   = DateTime->now;
$dt->set_time_zone( 'Europe/Madrid' );
use DateTime;
my $dt   = DateTime->now;
$dt->set_time_zone( 'Europe/Madrid' );
凉月流沐 2024-08-26 12:17:35

epochtime 只有一种基于 UTC 的标准定义,并且不同时区没有不同的 epochtime。

如果您想找到 gmtime 和 localtime 之间的偏移,使用

use Time::Local;
@t = localtime(time);
$gmt_offset_in_seconds = timegm(@t) - timelocal(@t);

There is only one standard definition for epochtime, based on UTC, and not different epochtimes for different timezones.

If you want to find the offset between gmtime and localtime, use

use Time::Local;
@t = localtime(time);
$gmt_offset_in_seconds = timegm(@t) - timelocal(@t);
纸伞微斜 2024-08-26 12:17:35

另一个基于 DateTime::Format::Strptime 的示例

use strict;
use warnings;
use v5.10;
use DateTime::Format::Strptime;

my $s = "2016-12-22T06:16:29.798Z";
my $p = DateTime::Format::Strptime->new(
  pattern => "%Y-%m-%dT%T.%NZ",
  time_zone => "UTC"
);

my $dt = $p->parse_datetime($s);    
$dt->set_time_zone("Europe/Berlin");
say join ' ', $dt->ymd, $dt->hms; # shows 2016-12-22 07:16:29

An other example based on DateTime::Format::Strptime

use strict;
use warnings;
use v5.10;
use DateTime::Format::Strptime;

my $s = "2016-12-22T06:16:29.798Z";
my $p = DateTime::Format::Strptime->new(
  pattern => "%Y-%m-%dT%T.%NZ",
  time_zone => "UTC"
);

my $dt = $p->parse_datetime($s);    
$dt->set_time_zone("Europe/Berlin");
say join ' ', $dt->ymd, $dt->hms; # shows 2016-12-22 07:16:29
欢你一世 2024-08-26 12:17:35

虽然 Time::Local 是一个合理的解决方案,但您最好使用更现代的 DateTime 面向对象模块。下面是一个示例:

use strict;
use DateTime;
my $dt = DateTime->now;
print $dt->epoch, "\n";

对于时区,您可以使用 DateTime::TimeZone 模块。

use strict;
use DateTime;
use DateTime::TimeZone;

my $dt = DateTime->now;
my $tz = DateTime::TimeZone->new(name => "local");

$dt->add(seconds => $tz->offset_for_datetime($dt));

print $dt->epoch, "\n";

CPAN 链接:

DateTime

While Time::Local is a reasonable solution, you may be better off using the more modern DateTime object oriented module. Here's an example:

use strict;
use DateTime;
my $dt = DateTime->now;
print $dt->epoch, "\n";

For the timezones, you can use the DateTime::TimeZone module.

use strict;
use DateTime;
use DateTime::TimeZone;

my $dt = DateTime->now;
my $tz = DateTime::TimeZone->new(name => "local");

$dt->add(seconds => $tz->offset_for_datetime($dt));

print $dt->epoch, "\n";

CPAN Links:

DateTime

乄_柒ぐ汐 2024-08-26 12:17:35

您只需设置时区即可。尝试:

env TZ=UTC+1 perl -e 'use Time::Local; print timelocal("00","00","00","01","01","2000"),"\n";'

You just need to set the timezone. Try:

env TZ=UTC+1 perl -e 'use Time::Local; print timelocal("00","00","00","01","01","2000"),"\n";'
你曾走过我的故事 2024-08-26 12:17:35

Time::Local::timelocallocaltime 的倒数。结果将采用您主机的当地时间:

$ perl -MTime::Local -le \
    'print scalar localtime timelocal "00","00","00","01","01","2000"'
Tue Feb  1 00:00:00 2000

您想要与该本地时间相对应的gmtime吗?

$ perl -MTime::Local' -le \
    'print scalar gmtime timelocal "00","00","00","01","01","2000"'
Mon Jan 31 23:00:00 2000

您是否想要相反的方式,即与 gmtime 相对应的 localtime

$ perl -MTime::Local -le \
    'print scalar localtime timegm "00","00","00","01","01","2000"'
Tue Feb  1 01:00:00 2000

Time::Local::timelocal is the inverse of localtime. The result will be in your host's local time:

$ perl -MTime::Local -le \
    'print scalar localtime timelocal "00","00","00","01","01","2000"'
Tue Feb  1 00:00:00 2000

Do you want the gmtime that corresponds to that localtime?

$ perl -MTime::Local' -le \
    'print scalar gmtime timelocal "00","00","00","01","01","2000"'
Mon Jan 31 23:00:00 2000

Do you want it the other way around, the localtime that corresponds to that gmtime?

$ perl -MTime::Local -le \
    'print scalar localtime timegm "00","00","00","01","01","2000"'
Tue Feb  1 01:00:00 2000
讽刺将军 2024-08-26 12:17:35

算法

如果要将时间值从一个时区更改为另一个时区,则必须能够指示两个时区。

毕竟,如果您设置是否要将“12:30”转换为GMT或美国/东部或委内瑞拉时间,这意味着添加/减去一些小时或小时和分钟,您需要知道哪个时区是开始时间zone,否则,计算将不知道要加多少或减多少。

如果您使用DateTime->now;,时区默认为系统时间,这可能不是您想要转换的时区。

在下面的代码中,我演示了如何将日期时间对象初始化为正确的起始时区 (fromtimezone) 以及如何将该时间转换为结束时区 (totimezone)...

工作代码

I无法在线找到安装了 DateTime CPAN 模块的 Perl 沙箱。

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 if !defined $year;
        $month ||= 1 if !defined $month;
        $day ||= 1 if !defined $day;
        $hour ||= 12 if !defined $hour;
        $minute ||= 30 if !defined $minute;
        $second ||= 0 if !defined $second;

        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

The Algorithm

If you want to change a time value from one timezone to another timezone, you must be able to indicate both timezones.

After all, if you set if you want to convert "12:30" to GMT or US/Eastern or Venezuelan time, which means adding/subtracting some amount of hours or hours and minutes, you need to know what timezone is the starting time zone, otherwise, the calculation won't know how much to add or subtract.

If you use DateTime->now;, the timezone is defaulted to the system-time, which may not be the timezone you want to convert from.

In the below code, I demonstrate how to initialize the datetime object to the right starting timezone (fromtimezone) and how to convert that time to the ending timezone (totimezone)...

Working Code

I could not find a Perl sandbox online with the DateTime CPAN module installed.

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 if !defined $year;
        $month ||= 1 if !defined $month;
        $day ||= 1 if !defined $day;
        $hour ||= 12 if !defined $hour;
        $minute ||= 30 if !defined $minute;
        $second ||= 0 if !defined $second;

        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',
}));

Output:

10:30:00

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文