strftime(3)でいうところの「%z」にあたる、「+0900」のようなタイムゾーンのGMT/UTCへのオフセット文字列を出力するモジュールをリリースしました。XSです
https://metacpan.org/release/Time-TZOffset
https://github.com/kazeburo/Time-TZOffset
機能は1つ
my @localtime = localtime;
say tzoffset(@localtime); => +0900
Windowsでも動作します。
use Benchmark qw/:all/;
use POSIX qw//;
use Time::Local;
use Time::TZOffset;
cmpthese(timethese(-1, {
'posix' => sub {
POSIX::strftime('%z', @lt);
},
'time_local' => sub {
my $sec = Time::Local::timegm(@lt) - Time::Local::timelocal(@lt);
sprintf '%+03d%02u', $sec/60/60, $min/60%60;
},
'tzoffset' => sub {
Time::TZOffset::tzoffset(@lt);
},
}));
__END__
Benchmark: running posix, time_local, tzoffset for at least 1 CPU seconds...
posix: 1 wallclock secs ( 0.66 usr + 0.39 sys = 1.05 CPU) @ 179442.86/s (n=188415)
time_local: 1 wallclock secs ( 1.12 usr + 0.16 sys = 1.28 CPU) @ 25846.09/s (n=33083)
tzoffset: 1 wallclock secs ( 0.75 usr + 0.25 sys = 1.00 CPU) @ 286720.00/s (n=286720)
Rate time_local posix tzoffset
time_local 25846/s -- -86% -91%
posix 179443/s 594% -- -37%
tzoffset 286720/s 1009% 60% --
POSIX::strftime('%z')
より速く動作します。
このUTCへのオフセットはLinuxやBSD系のOSでは、t\m
構造体に含まれており、mktime(3)
を使うと簡単に得られます。
struct tm mytm;
memset(&mytm,0,sizeof(mytm));
mytm.tm_min = min;
mytm.tm_hour = hour;
mytm.tm_mday = mday;
mytm.tm_mon = mon;
mytm.tm_year = year;
mytm.tm_isdst = -1;
mktime(&mytm);
mytm.tm_gmtoff;
XS不慣れなのでツッコミ等お待ちしています。