Perl:在考虑夏令时的纪元以来以秒为单位输入时间时获取 gmtime 和本地时间之间的偏移量
Perl : Get offset between gmtime and localtime when input time in seconds since epoch which considers daylight savings time
我想获得自纪元以来给定微秒数的本地时间和 gmtime 之间的小时偏移量。到目前为止我所拥有的是这样的
# Microseconds since Epoch
my $msec = 555329743301750;
# Convert to seconds
my $sec = $msec/1000000;
my $val = (POSIX::mktime(localtime $sec) - POSIX::mktime(gmtime $sec)) / 60 / 60;
print "$val\n";
1) 我得到的输出是 -6。(CST 本地时间)但是我期待 -5。我期望的行为类似于 运行 bash 命令
的结果
`date -d 20190514 "+%z"`;
2) 长话短说,我如何计算类似于 perl 中的 date -d 20190514 "+%z"
的偏移量?
使用核心Time::Piece:
use strict;
use warnings;
use Time::Piece;
# Microseconds since Epoch
my $usec = 555329743301750;
# Convert to seconds
my $sec = $usec/1000000;
my $offset = localtime($sec)->tzoffset / 3600;
Time::Moment 和 DateTime 也可以 return 这个值,如果你像我在 上展示的那样构造它们的话。
my $offset = $time_moment->offset / 60;
my $offset = $datetime->offset / 3600;
您也可以根据日期创建这些对象,但它当然会为您提供当天午夜(当地时间)的偏移量。
use Time::Piece;
my $time = localtime->strptime('20190514', '%Y%m%d');
use Time::Moment;
use Role::Tiny ();
my $class = Role::Tiny->create_class_with_roles('Time::Moment', 'Time::Moment::Role::TimeZone');
my $time = $class->new(year => 2019, month => 5, day => 14)->with_system_offset_same_local;
use DateTime;
my $time = DateTime->new(year => 2019, month => 5, day => 14, time_zone => 'local');
这将为您提供与 Linux "%z" 格式相同的 [+-]HHMM 格式:
use POSIX qw[mktime];
my $tz = (localtime time)[8] * 60 - mktime(gmtime 0) / 60;
$tz = sprintf "%+03d%02d\n", $tz / 60, abs($tz) % 60;
如果您只想要以小时为单位的偏移量,您可以这样做:
my $tz_offset_hours = (localtime time)[8] - mktime(gmtime 0)) / 3600;
奖励: 以下子例程将 return 带有时区偏移量和微秒的完整时间戳,如“YYYY-MM-DD HH:MM:SS。 nnnnnn [+-]HHMM":
use POSIX qw[mktime strftime];
use Time::HiRes qw[gettimeofday];
sub timestamp () {
my @now = gettimeofday;
my $tz = (localtime $now[0])[8] * 60 - mktime(gmtime 0) / 60;
my $ts = strftime("%Y-%m-%d %H:%M:%S", localtime $now[0]);
return sprintf "%s.%06d %+03d%02d", $ts, $now[1], $tz / 60, abs($tz) % 60;
}
我想获得自纪元以来给定微秒数的本地时间和 gmtime 之间的小时偏移量。到目前为止我所拥有的是这样的
# Microseconds since Epoch
my $msec = 555329743301750;
# Convert to seconds
my $sec = $msec/1000000;
my $val = (POSIX::mktime(localtime $sec) - POSIX::mktime(gmtime $sec)) / 60 / 60;
print "$val\n";
1) 我得到的输出是 -6。(CST 本地时间)但是我期待 -5。我期望的行为类似于 运行 bash 命令
的结果`date -d 20190514 "+%z"`;
2) 长话短说,我如何计算类似于 perl 中的 date -d 20190514 "+%z"
的偏移量?
使用核心Time::Piece:
use strict;
use warnings;
use Time::Piece;
# Microseconds since Epoch
my $usec = 555329743301750;
# Convert to seconds
my $sec = $usec/1000000;
my $offset = localtime($sec)->tzoffset / 3600;
Time::Moment 和 DateTime 也可以 return 这个值,如果你像我在
my $offset = $time_moment->offset / 60;
my $offset = $datetime->offset / 3600;
您也可以根据日期创建这些对象,但它当然会为您提供当天午夜(当地时间)的偏移量。
use Time::Piece;
my $time = localtime->strptime('20190514', '%Y%m%d');
use Time::Moment;
use Role::Tiny ();
my $class = Role::Tiny->create_class_with_roles('Time::Moment', 'Time::Moment::Role::TimeZone');
my $time = $class->new(year => 2019, month => 5, day => 14)->with_system_offset_same_local;
use DateTime;
my $time = DateTime->new(year => 2019, month => 5, day => 14, time_zone => 'local');
这将为您提供与 Linux "%z" 格式相同的 [+-]HHMM 格式:
use POSIX qw[mktime];
my $tz = (localtime time)[8] * 60 - mktime(gmtime 0) / 60;
$tz = sprintf "%+03d%02d\n", $tz / 60, abs($tz) % 60;
如果您只想要以小时为单位的偏移量,您可以这样做:
my $tz_offset_hours = (localtime time)[8] - mktime(gmtime 0)) / 3600;
奖励: 以下子例程将 return 带有时区偏移量和微秒的完整时间戳,如“YYYY-MM-DD HH:MM:SS。 nnnnnn [+-]HHMM":
use POSIX qw[mktime strftime];
use Time::HiRes qw[gettimeofday];
sub timestamp () {
my @now = gettimeofday;
my $tz = (localtime $now[0])[8] * 60 - mktime(gmtime 0) / 60;
my $ts = strftime("%Y-%m-%d %H:%M:%S", localtime $now[0]);
return sprintf "%s.%06d %+03d%02d", $ts, $now[1], $tz / 60, abs($tz) % 60;
}