如何在 Perl 中转换时区?

发布于 2024-08-23 01:08:27 字数 729 浏览 3 评论 0 原文

我正在尝试在 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 的本地时区,但我不知道如何解决这个问题。

I am trying to convert a date/time GMT 0 to GMT -6 in Perl.

For example, a DHCP Server lease time is in the following format:

2010/02/18 23:48:37

I am trying to convert that time to the Localtime zone (GMT -6) but need it to honor Daylight savings time.

The script below may be overkill, but I am not sure how to proceed from here. (Any suggestions would be awsome).

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";

It will output the following lines:

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

I need to be able to add -21600 to the date to get the local time zone of GMT -6 but I am not sure how to approch this.

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

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

发布评论

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

评论(5

浅暮の光 2024-08-30 01:08:27

调用set_time_zone< /a> 方法 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

Call set_time_zone method 2 times:

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

How it works:

  • when you create DateTime object without time zone specified, "floating" time zone is set
  • first call of set_time_zone change time zone to UTC without conversion
  • second call of set_time_zone change UTC to America/Chicago
假装爱人 2024-08-30 01:08:27

这会将 UTC 时间转换为 ETC 时间。
您还可以使用日期的 +FORMAT 参数以任何格式使用日期/时间。

日期 --date='TZ="ETC" 18:30'

This will convert UTC time into ETC time.
You can also use date/time in any format using +FORMAT parameter of date.

date --date='TZ="ETC" 18:30'

全部不再 2024-08-30 01:08:27

Time::Piece 是一个非常轻量级的组件质量好的代码。或者您可以只使用内置函数和 strftimePOSIX::strptime

Time::Piece is a very lightweight piece of code of good quality. Or you can just use built-ins and strftime and POSIX::strptime

故人爱我别走 2024-08-30 01:08:27

不要将时区与“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 转换时区

您的起始时区是您输入构造函数的任何内容(即美国/芝加哥< /code> 在上面的例子中)。要将时间转换为结束时区,请使用 set_time_zone()

工作代码

在下面的代码中,时间从一个时区转换为另一个时区,并且每次都能完美地完成此操作,即使您使用 Linux 操作系统为新加坡时间的服务器将纽约时间转换为旧金山时间。

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

Don't Use Timezones With `DateTime::Format::MySQL->parse_datetime`

There is a very good reason you shouldn't be using this when doing anything relating to timezones. Why? Because it has absolutely no support for timezones whatsoever. Please see the documentation:

All of the parsing methods set the returned DateTime object's time zone to the floating time zone, because MySQL does not provide time zone information. (Source: MetaCPAN: DateTime::Format::MySQL.)

If you DO use this, it will assume your system time zone default. This might not be the timezone you want to convert from! (Although this will work for many people, it only works as long as your servers don't change their default timezone — after that, everything breaks.)

Use `DateTime->new()`, Because It DOES Support TimeZones

Use the constructor that DateTime provides directly (Source: MetaCPAN: DateTime.):

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

Convert TimeZones with DateTime

Your starting time zone is whatever you feed into the constructor (i.e., America/Chicago in the above example). To convert a time to an ending time zone, use set_time_zone().

Working Code

In the code below, a time is converted from one timezone to another, and it does this perfectly every time, even you are converting New York time to San Francisco time with a server whose Linux OS is in Singapore time.

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

地狱即天堂 2024-08-30 01:08:27
#!/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);
#!/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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文