<?php
/**
* JJYシミュレータ 送出タイムコード日時変更ユーティリティ
*/
$jjyAdjustFile = '/home/pi/script/jjy_adjust.txt'; // jjy_adjust.txtのパス
$result = false;
if($_POST) {
$result = file_put_contents($jjyAdjustFile, isset($_POST['adjust']) ? $_POST['adjust'] : '0');
$message = $result ? 'ok' : "設定保持ファイル {$jjyAdjustFile} を更新できません。\n {$jjyAdjustFile} のパーミッションを0666に変更して下さい。";
header('Content-type: text/plain');
print $message;
exit;
}
if(file_exists($jjyAdjustFile)) {
$file = file_get_contents($jjyAdjustFile);
$adjustSec = (preg_match('/^\-?\d+$/', $file)) ? $file : 0;
} else {
error_exit("設定保持ファイル {$jjyAdjustFile} が見つかりません。<br />空ファイル {$jjyAdjustFile} を作成し、パーミッションを0666に設定して下さい。");
}
function error_exit($mes) {
header('Content-type: text/html');
print "<!DOCTYPE html><html><head><meta charset='utf-8'></head><body>{$mes}</body></html>";
exit;
}
$timeNow = microtime(true) * 1000;
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='user-scalable=no,width=device-width,initial-scale=1'>
<title>jjy.py 送出タイムコード日時変更</title>
<script>
var localDate = new Date();
var nowDate = new Date(<?=$timeNow?>);
var diff = nowDate - localDate;
var sendSec = <?=$adjustSec?>;
var adjust = <?=$adjustSec?>;
var dg = function(id) {return document.getElementById(id);}
window.onload = function() {
var lastSec;
var lastTime = new Date(new Date().getTime() + diff).getTime();
setInterval(
function() {
var now = new Date(new Date().getTime() + diff);
if(lastSec != now.getSeconds()) {
if(Math.abs(lastTime - now.getTime()) > 2000) {
location.reload(true);
}
lastTime = now.getTime();
lastSec = now.getSeconds();
dg('nowDate').innerHTML = getFormat(now);
dg('sendDate').innerHTML = getFormat(new Date(new Date().getTime() + diff + adjust * 1000) , 1);
if(chgEnabled) dg('d'+ sel[selNum]).style.backgroundColor = selColor;
}
}, 10
);
}
function getFormat(d, m) {
return(
(m ? '<span id="dy">' : '') + d.getFullYear() + (m ? '</span>' : '')
+ '.' + (m ? '<span id="dm">' : '') + ('0' + (d.getMonth()+1)).slice(-2) + (m ? '</span>' : '')
+ '.' + (m ? '<span id="dd">' : '') + ('0' + d.getDate()).slice(-2) + (m ? '</span>' : '')
+ ' <span class="week">' + ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][d.getDay()] + '</span>'
+ ' '
+ '<span class="timeView">'
+ (m ? '<span id="dh">':'') + ('0' + d.getHours()).slice(-2) + (m ? '</span>' : '')
+ ':' + (m ? '<span id="di">':'') + ('0' + d.getMinutes()).slice(-2) + (m ? '</span>' : '')
+ ':' + (m ? '<span id="ds">':'') + ('0' + d.getSeconds()).slice(-2) + (m ? '</span>' : '')
+ '</span>');
}
var sel = ['y', 'm', 'd', 'h', 'i', 's'];
var selNum = sel.length -1;
var selColor = '#bbf';
var repeatId = 0;
var touchFlg = false;
function buttonPress(n, tf) {
t = sel[selNum];
if(tf) touchFlg = true;
if(!tf && touchFlg) return;
if(!chgEnabled) return;
adjustRelUpdate(t, n);
if(!repeatId) {
repeatId = setTimeout(function() {
repeatId = setInterval(function() {
adjustRelUpdate(t, n);
}, 30);
}, 400);
}
}
function buttonRelease() {
if(repeatId) {
clearInterval(repeatId);
repeatId = 0;
}
}
function adjustRelUpdate(t, n) {
var d = new Date().getTime() + diff + adjust * 1000;
var sd = new Date(d);
var sd_ = new Date(d);
if(t == 'y') sd.setFullYear(sd.getFullYear() + n);
else if(t == 'm') sd.setMonth(sd.getMonth() + n);
else if(t == 'd') sd.setDate(sd.getDate() + n);
else if(t == 'h') sd.setHours(sd.getHours() + n);
else if(t == 'i') sd.setMinutes(sd.getMinutes() + n);
else if(t == 's') sd.setSeconds(sd.getSeconds() + n);
var p = ~~((sd.getTime() - sd_.getTime()) / 1000);
if(t != 's') p = ~~((p + (30 * n)) / 60) * 60;
adjust += p;
var hy = 315576e4;
if(n == 1 && adjust >= hy) adjust -= (hy * 2 - 86400);
if(n == -1 && adjust <= -hy) adjust += (hy * 2 - 86400);
adjustUpdate();
}
function chgSel(n) {
if(!chgEnabled) {
chgEnabled = true;
ceTimeoutUpdate();
dg('d' + sel[selNum]).style.backgroundColor = selColor;
return;
}
dg('d' + sel[selNum]).style.backgroundColor = '';
selNum += n;
if(selNum < 0) selNum = sel.length -1;
else if(selNum > sel.length -1) selNum = 0;
dg('d' + sel[selNum]).style.backgroundColor = selColor;
chgEnabled = true;
ceTimeoutUpdate();
}
function adjustUpdate(m) {
sendDate = new Date(new Date().getTime() + diff + adjust * 1000);
dg('sendDate').innerHTML = getFormat(sendDate, 1);
if(!m) {
dg('d' + sel[selNum]).style.backgroundColor = selColor;
ceTimeoutUpdate();
}
if(adjust == sendSec) {
dg('sendBtn').style.backgroundColor = '';
dg('result').innerHTML = '';
} else {
dg('sendBtn').style.backgroundColor = '#f80';
dg('result').innerHTML = '確定するまで変更内容は反映されません';
}
}
var chgEnabled = false;
var ceTimeoutId;
function ceTimeoutUpdate() {
if(ceTimeoutId) clearTimeout(ceTimeoutId);
ceTimeoutId = setTimeout(
function() {
chgEnabled = false;
dg('d' + sel[selNum]).style.backgroundColor = '';
}, 4000);
}
function cancelChg() {
setNow(1);
}
function setNow(m) {
adjust = m ? sendSec : 0;
adjustUpdate(1);
if(ceTimeoutId) {
clearTimeout(ceTimeoutId);
chgEnabled = false;
}
}
function sendData() {
var a = new XMLHttpRequest();
var url = '<?='http'.($_SERVER['SERVER_PORT'] == 443 ? 's' : '').'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']?>';
a.open('POST', url);
a.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
a.send('adjust=' + adjust);
popUpMessage('Waiting...', 1e6);
a.addEventListener('load', function() {
if(a.status == 200 && this.response == 'ok') {
if(ceTimeoutId) {
clearTimeout(ceTimeoutId);
chgEnabled = false;
}
sendSec = adjust;
adjustUpdate(1);
popUpMessage('設定を変更しました', 2000);
} else {
if(a.status == 200) {
alert(this.response);
} else if(a.status == 404) {
alert(url + 'が見つかりません');
} else {
alert(url + 'からの応答がありません');
}
}
}, false);
}
var pId;
function popUpMessage(mes, t) {
var d = dg('popUp');
d.innerHTML = mes;
d.style.left = '53px';
if(pId) clearTimeout(pId);
pId = setTimeout(
function() {
d.style.left = '-1000px';
}, t);
}
</script>
<style>
@import url('https://fonts.googleapis.com/css?family=M+PLUS+1p:300&subset=japanese');
html {
touch-action: manipulation;
-webkit-touch-callout: none;
-webkit-user-select: none;
font-family: 'M PLUS 1p', sans-serif;
}
input[type='button'], input[type='submit'] {
-webkit-appearance: none;
-webkit-user-select: none;
border-radius: 4px;
background-color: #fff;
border: 1px solid black;
font-family: 'M PLUS 1p', sans-serif;
}
.btnSel{
width: 50px;
max-width: 50px;
height: 122px;
font-size: 15px;
position: absolute;
}
.btnUd{
width: 66%;
height: 60px;
max-width: 196px;
font-size: 15px;
position: absolute;
}
.btnBar{
width: 50%;
max-width: 149px;
height: 35px;
position: absolute;
bottom: 0px;
}
.btnBar2{
width: 100%;
max-width: 300px;
height: 35px;
}
.bRight {
right: 0px;
}
.bUp {
left: 52px;
}
.bDown {
left: 52px;
top: 62px;
}
.bNow {
right: 0px;
}
.t {
width: 100%;
height: 164px;
max-width: 300px;
position: relative;
}
.dateView {
font-size: 16px;
}
.timeView {
font-size: 22px;
}
.week {
display: inline-block;
width: 30px;
font-size: 16px;
}
.popUp {
position: absolute;
padding-top: 8px;
padding-bottom: 8px;
top: 160px;
left: -1000px;
width: 200px;
height: auto;
background-color: #446;
color: #fff;
border: 4px #ccf solid;
border-radius: 5px;
text-align: center;
vertical-align: middle;
font-size: 20px;
z-index: 99;
}
</style>
</head>
<body onmouseup='buttonRelease()' onmouseleave='buttonRelease()' ontouchend='buttonRelease()'>
<h3>jjy.py 送出タイムコード日時変更</h3>
<span class='dateView'>現在日時:<span id='nowDate'></span></span><br />
<span class='dateView'>送出日時:<span id='sendDate'></span></span><br />
<br />
<div class='t'>
<input type='button' value='<' onclick='chgSel(-1)' class='btnSel bLeft'>
<input type='button' value='+' onmousedown='buttonPress(1)' ontouchstart='buttonPress(1, 1)' class='btnUd bUp'>
<input type='button' value='-' onmousedown='buttonPress(-1)' ontouchstart='buttonPress(-1, 1)' class='btnUd bDown'>
<input type='button' value='>' onclick='chgSel(1)' class='btnSel bRight'>
<input type='button' value='変更を取り消す' onclick='cancelChg()' class='btnBar bCancel'>
<input type='button' value='現在日時に合わせる' onclick='setNow()' class='btnBar bNow'>
</div>
<p style='font-size:9px;'>
現在日時 … Raspberry Pi上での現在の日時です<br />
送出日時 … jjy.pyがタイムコードとして送出している日時です<br />
</p>
<input type='button' id='sendBtn' value='変更を確定する' class='btnBar2' onclick='if(adjust != sendSec) sendData()'><br />
<p style='color:red' id='result'></p>
<div class='popUp' id='popUp'></div>
</body>
</html>