たむらです。時刻合わせ-その2です。
Win32api の setLocalTime/getLocalTime と、syscall での実装です。
定数 RUBY_PLATFORM で、 Windows 環境かどうかをチェックしてます。
もちろん、Win32apiの中にも同様なものがありますが。
MSのサイトで、getLocalTime した構造体を setLocalTime で埋めなさいと
あったので、こういう実装にしてます。
Syscall の方は、関数 syscall の利用です。OSによって、settimeofday の
定義された数値が違ったりするので、やはり RUBY_PLATFORM で分岐させてます。
メソッド settime は、モジュール Win32/Syscall を自動的に呼んで、
実際の時刻設定を行います。 Rubyは、基本的に上から順に文を評価していくので、
書き方によっては、妙なエラーになったりします。
例えば、Linux で動かす場合は、require 'win32api' なんかしたくないわけです。
#! ruby -Ke
# -*- mode: Ruby; -*-
## $Id: $
module Win32
def platform?
/(cygwin|mingw32|mswin32)$/ === RUBY_PLATFORM
end
def settime(year,month,day, hour,min,sec)
require 'Win32API'
getLocalTime = Win32API.new("kernel32", "GetLocalTime", %w(P), 'V')
setLocalTime = Win32API.new("kernel32", "SetLocalTime", %w(P), 'V')
getLastError = Win32API.new("kernel32", "GetLastError", [], 'L')
# year,month,dayofweek,day, hour,min,sec,msec
pSYSTEMTIME = ' ' * 2 * 8 # 2byte x 8
getLocalTime.call(pSYSTEMTIME)
t = pSYSTEMTIME.unpack("S8")
t[0..1] = year,month
t[3..6] = day, hour,min,sec
setLocalTime.call( t.pack("S8") )
e = getLastError.call
if e != 0 then
raise "Error[#{e}]: setLocalTime(win32api)!!"
end
end
module_function :settime, :platform?
end
module Syscall
CODE_SETTIMEOFDAY =
case RUBY_PLATFORM
when /linux.*$/
79
when /(free|net)bsd.*$/
122
# when /(sunos|solaris).*$/
# 37 # find /usr/include -name \*.h |xargs grep -i settimeofday
# で探すと、/usr/include/bsm/audit_kevents.h に
#define AUE_SETTIMEOFDAY 37 ってのがあったけど、動かなかった。
# `syscall':Invalid argument (Errno::EINVAL)
else
nil
end
def settime(year,month,day, hour,min,sec)
raise "Not imprement yet!!" if CODE_SETTIMEOFDAY.nil?
t = Time.mktime(year,month,day, hour,min,sec)
syscall(CODE_SETTIMEOFDAY, [t.to_i,0].pack('ll'), [0,0].pack('ii'))
end
module_function :settime
end
def settime(year,month,day, hour,min,sec)
if Win32::platform? then
Win32::settime(year,month,day,hour,min,sec)
else
if Syscall::settime(year,month,day,hour,min,sec) != 0 then
raise "Error: settimeofday(syscall)!!"
end
end
end
if __FILE__ == $0 # for test
p t = Time.now
n = t.hour % 2 == 0 ? -1 : +1
p settime(t.year,t.month,t.day,t.hour+n,t.min,t.sec)
p Time.now
end
__END__
『if __FILE__ == $0 # for test』以下は、テストケースです。
単純に今の時刻の時間を 1時間早めたり、遅くしたりしてます。
時刻を元に戻しやすいようにしただけですが (^^;
# 0分をまたいで、やると破綻しますが。
どなたか前回のと合体させて、こちらにアップしてみませんか ?
今回のスクリプトは、ちょっと小細工しすぎなので、もっと単純で
良いと思います。
# OS 限定とか
tDiary はじめました。 http://tamura.tdiary.net
たむら mailto:sgs02516@...