NasupiiのPerl書抜帳
MS-Excel のシリアル値から日付・時刻の文字列を得るプログラムのソースコード
Perl ソースコード
# ================================================================================
# serial2date.pl
# シリアル値の換算
# Copyright (C) 2013 Nasupii last update 2013/11/03
# perlのシリアル値はグリニッジ標準時の1970年1月1日0時0分0秒からの秒数で表す。
# 現在の値を求めるには関数 time()を使用する
# 日付、時刻に換算するときは
# gmtime(time()) グリニッジ標準時
# localtime(time)) ローカル時
# ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($tt);
# $sec, $min, ...はそれぞれ、秒数(0-59)、分(0-59)、時(0-23)、日(1-31)、月(0-11)、
# 年(1900年からの年数(西暦の下2桁ではない))、曜日(日(0)-土(6))、年日数(1月1日を0とする)、
# $isdst(夏時間なら0以外の値)を表わす。
#
# MS-Excelのシリアル値は1900年1月1日をシリアル値1とした、日数を表す。
# なお、excelのバグで、1900年は閏年に設定されていて1900年2月29日があるように計算している
# そこで、他の正しい日付計算をするソフトと換算する場合は、1989年12月30日午前0時を0とする日数
# として計算するほうがわかりやすい。
# Excelのシリアル値からperlのシリアル値への換算法
#
# perlが基準とする 1970年1月1日0時0分0秒をExcelのシリアル値は25569である(MS-Excel 2010 にて)
# また、1日の秒数は 60 x 60 x 24 = 86400 である
# Excelのシリアル値を a とし、perlのシリアル値をbとすると
# b = (a-25569)*86400 となる
# これを年月日に換算するには gmtime()を使えば良い
# 以下換算用のサブルーチンを作成した
# ================================================================================
#テスト用メイン
foreach $a ("0", "0.9", "41418.5", "41419.5", "as23") {
print "シリアル値=", $a, " 日付=", serial2date($a), "\n";
}
foreach $a ("0", "0.9", "41418.5", "41419.5", "as23") {
print "シリアル値=", $a, " 日付 時刻=", serial2datetime($a), "\n";
}
foreach $a ("0", "0.9", "41418.5", "41419.5", "as23") {
print "シリアル値=", $a, " 時刻=", serial2time($a), "\n";
}
# ================================================================================
# sub serial2date
# Copyright (C) 2013 Nasupii last update 2013/11/03
# MS-Excel のシリアル値から 日付の文字列を得る
# 引数 MS-Excel のシリアル値
# 戻り値 yyyy/mm/dd (年/月/日)
# 例外処理
# 引数に数字と小数点以外の文字が含まれていた場合は引数をそのまま戻り値とする
# 引数が1より小さい値だった場合は空文字列を戻り値とする
# ================================================================================
sub serial2date {
return($_[0]) if($_[0] =~ m/[^\d\.]/);
return("") if($_[0] < 1.0);
my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
= gmtime(($_[0]-25569)*86400);
return(sprintf("%4d/%02d/%02d", $year+1900, $mon+1, $mday));
}
# ================================================================================
# sub serial2datetime
# Copyright (C) 2013 Nasupii last update 2013/11/03
# MS-Excel のシリアル値から 日付時刻の文字列を得る
# 引数 MS-Excel のシリアル値
# 戻り値 yyyy/mm/dd h:mm (年/月/日 時:分)24時間制
# 例外処理
# 引数に数字と小数点以外の文字が含まれていた場合は引数をそのまま戻り値とする
# 引数が1より小さい値だった場合は空文字列を戻り値とする
# ================================================================================
sub serial2datetime {
return($_[0]) if($_[0] =~ m/[^\d\.]/);
return("") if($_[0] < 1.0);
my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
= gmtime(($_[0]-25569)*86400);
return(sprintf("%4d/%02d/%02d %2d:%02d", $year+1900, $mon+1, $mday, $hour, $min));
}
# ================================================================================
# sub serial2time
# Copyright (C) 2013 Nasupii last update 2013/11/03
# MS-Excel のシリアル値から 時刻の文字列を得る
# 引数 MS-Excel のシリアル値
# 戻り値 h:mm (時:分)24時間制
# 例外処理
# 引数に数字と小数点以外の文字が含まれていた場合は引数をそのまま戻り値とする
# ================================================================================
sub serial2time {
return($_[0]) if($_[0] =~ m/[^\d\.]/);
my($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
= gmtime(($_[0]- int($_[0]))*86400);
return(sprintf("%2d:%02d", $hour, $min));
}
Copyright (C) Nasupii