DevTools: Moseszeit-Formel korrigiert (moses + 94687200 = unix, Anzeige Europe/Berlin)

This commit is contained in:
2026-06-01 09:42:24 +02:00
parent 5bdc17a073
commit 34a00dce8f

View File

@@ -478,33 +478,34 @@ function ElektroRechner({ mobile }) {
} }
// ─────────────────────────────────────────────────────────────── Datetime ── // ─────────────────────────────────────────────────────────────── Datetime ──
// Moseszeit: Unix-Timestamp (Sekunden), aber Jahreszahl wird um +3 Jahre versetzt angezeigt. // Moseszeit-Formel: moses + 94687200 = Unix-Timestamp (Sekunden)
// Beispiel: 1685560872 → Unix=2023-05-31 19:21:12 UTC → Moses-Anzeige=2026-05-31 19:21:12 // Anzeige immer als Europe/Berlin Lokalzeit (CEST=+2, CET=+1)
// Umkehrung: Moses-Jahr -3 → Unix-Jahr → Timestamp berechnen. const MOSES_TO_UNIX_OFFSET = 94687200; // Sekunden
const MOSES_YEAR_OFFSET = 3;
function pad2(n){ return String(n).padStart(2,'0'); } function pad2(n){ return String(n).padStart(2,'0'); }
// Aus Unix-Timestamp (ms) ein Anzeige-Objekt für Moseszeit bauen (UTC + Jahr+3) function mosesToUnixMs(moses) {
function mosesDisplayFromUnixMs(ms) { return (moses + MOSES_TO_UNIX_OFFSET) * 1000;
const d = new Date(ms);
const y = d.getUTCFullYear() + MOSES_YEAR_OFFSET;
const mo= pad2(d.getUTCMonth()+1);
const day=pad2(d.getUTCDate());
const h = pad2(d.getUTCHours());
const mi= pad2(d.getUTCMinutes());
const s = pad2(d.getUTCSeconds());
return { de: `${day}.${mo}.${y} ${h}:${mi}:${s}`, iso: `${y}-${mo}-${day}T${h}:${mi}:${s}` };
} }
// Aus Moses-Sekunden → Unix-Timestamp in ms (einfach *1000, Jahr-Versatz ist nur Anzeige) function unixMsToMoses(unixMs) {
function mosesToUnixMs(mosesTs) { return Math.floor(unixMs / 1000) - MOSES_TO_UNIX_OFFSET;
return mosesTs * 1000;
} }
// Aus lokalem datetime-local Input (local time) ein Date-Objekt // Date -> Berlin-Lokalzeit-String "DD.MM.YYYY HH:MM:SS"
function formatBerlin(d) {
return d.toLocaleString('de-DE', {
timeZone: 'Europe/Berlin',
year:'numeric', month:'2-digit', day:'2-digit',
hour:'2-digit', minute:'2-digit', second:'2-digit',
hour12: false,
}).replace(',','');
}
// Date -> ISO-String in Berlin-Zeit für datetime-local input (YYYY-MM-DDTHH:MM:SS)
function toLocalISO(d) { function toLocalISO(d) {
return `${d.getFullYear()}-${pad2(d.getMonth()+1)}-${pad2(d.getDate())}T${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`; const s = d.toLocaleString('sv-SE', { timeZone: 'Europe/Berlin' }); // sv-SE gibt YYYY-MM-DD HH:MM:SS
return s.replace(' ', 'T');
} }
function formatDE(d){ function formatDE(d){
@@ -529,40 +530,48 @@ function DatetimeRechner({ mobile }) {
const [convResult, setConvResult] = useState(null); const [convResult, setConvResult] = useState(null);
function convFromUnix(val) { function convFromUnix(val) {
const n = parseInt(val);
if (isNaN(n)) { setConvResult(null); return; }
const unixMs = n * 1000;
const d = new Date(unixMs);
const moses = unixMsToMoses(unixMs);
setConvResult({
de: formatBerlin(d),
local: toLocalISO(d),
unix: String(n),
moses: String(moses),
wday: d.toLocaleDateString('de-DE', { timeZone:'Europe/Berlin', weekday:'long' }),
kw: getKW(d),
});
}
function convFromMoses(val) {
const n = parseInt(val); const n = parseInt(val);
if (isNaN(n)) { setConvResult(null); return; } if (isNaN(n)) { setConvResult(null); return; }
const unixMs = mosesToUnixMs(n); const unixMs = mosesToUnixMs(n);
const d = new Date(unixMs); const d = new Date(unixMs);
const moses = mosesDisplayFromUnixMs(unixMs);
const dLocal = new Date(n * 1000); // for weekday (UTC)
setConvResult({ setConvResult({
de: moses.de, de: formatBerlin(d),
local: moses.iso, local: toLocalISO(d),
unix: String(n), unix: String(Math.floor(unixMs/1000)),
wday: WEEKDAYS[d.getUTCDay()], moses: String(n),
wday: d.toLocaleDateString('de-DE', { timeZone:'Europe/Berlin', weekday:'long' }),
kw: getKW(d), kw: getKW(d),
}); });
} }
function convFromLocal(val) { function convFromLocal(val) {
// val is in format YYYY-MM-DDTHH:MM:SS from datetime-local (local browser time)
// For Moses: treat it as UTC (since Moses timestamps are UTC-based + year offset)
if (!val) { setConvResult(null); return; } if (!val) { setConvResult(null); return; }
// Parse the value: year shown is Moses year, so subtract 3 for real UTC year // datetime-local gibt lokale Browser-Zeit — wir interpretieren als Europe/Berlin
const [datePart, timePart] = val.split('T'); const d = new Date(val); // browser local
if (!datePart || !timePart) { setConvResult(null); return; }
const [y, mo, day] = datePart.split('-').map(Number);
const [h, mi, s] = timePart.split(':').map(Number);
const realYear = y - MOSES_YEAR_OFFSET;
const d = new Date(Date.UTC(realYear, mo-1, day, h, mi, s||0));
if (isNaN(d)) { setConvResult(null); return; } if (isNaN(d)) { setConvResult(null); return; }
const unixSec = Math.floor(d.getTime() / 1000); const unixMs = d.getTime();
const moses = mosesDisplayFromUnixMs(d.getTime());
setConvResult({ setConvResult({
de: moses.de, de: formatBerlin(d),
local: val, local: val,
unix: String(unixSec), unix: String(Math.floor(unixMs/1000)),
wday: WEEKDAYS[d.getUTCDay()], moses: String(unixMsToMoses(unixMs)),
wday: d.toLocaleDateString('de-DE', { timeZone:'Europe/Berlin', weekday:'long' }),
kw: getKW(d), kw: getKW(d),
}); });
} }
@@ -641,48 +650,53 @@ function DatetimeRechner({ mobile }) {
{tab==='conv' && ( {tab==='conv' && (
<div> <div>
<div style={{display:'grid',gridTemplateColumns:mobile?'1fr':'1fr 1fr',gap:12,marginBottom:16}}> <div style={{display:'grid',gridTemplateColumns:mobile?'1fr':'1fr 1fr 1fr',gap:12,marginBottom:16}}>
<div> <div>
<div style={lbl}>Unix / Moseszeit (Sekunden)</div> <div style={lbl}>Moseszeit</div>
<input style={inp} type="number" placeholder="z.B. 1685554093" <input style={inp} type="number" placeholder="z.B. 1685554093"
value={conv.unix} onChange={e=>{ setConv(p=>({...p,unix:e.target.value})); convFromUnix(e.target.value); }}/> value={conv.moses||''} onChange={e=>{ setConv(p=>({...p,moses:e.target.value})); convFromMoses(e.target.value); }}/>
</div> </div>
<div> <div>
<div style={lbl}>Datum & Uhrzeit</div> <div style={lbl}>Unix-Timestamp</div>
<input style={inp} type="number" placeholder="z.B. 1780248072"
value={conv.unix||''} onChange={e=>{ setConv(p=>({...p,unix:e.target.value})); convFromUnix(e.target.value); }}/>
</div>
<div>
<div style={lbl}>Datum & Uhrzeit (Berlin)</div>
<input style={inp} type="datetime-local" <input style={inp} type="datetime-local"
value={conv.local} onChange={e=>{ setConv(p=>({...p,local:e.target.value})); convFromLocal(e.target.value); }}/> value={conv.local||''} onChange={e=>{ setConv(p=>({...p,local:e.target.value})); convFromLocal(e.target.value); }}/>
</div> </div>
</div> </div>
<button style={{...S.btn('#4ecdc4',false), fontSize:11, padding:'6px 14px', marginBottom:16}} <button style={{...S.btn('#4ecdc4',false), fontSize:11, padding:'6px 14px', marginBottom:16}}
onClick={()=>{ onClick={()=>{
const d = new Date(); const d = new Date();
const unixSec = Math.floor(d.getTime()/1000); const unixSec = Math.floor(d.getTime()/1000);
const moses = mosesDisplayFromUnixMs(d.getTime()); const mosesVal = unixMsToMoses(d.getTime());
setConv({unix:String(unixSec), local:moses.iso, de:''}); setConv({unix:String(unixSec), moses:String(mosesVal), local:toLocalISO(d)});
convFromUnix(String(unixSec)); convFromUnix(String(unixSec));
}}> }}>
Jetzt verwenden Jetzt verwenden
</button> </button>
{convResult && ( {convResult && (
<div> <div>
<DtRow label="Deutsch (DE)" value={convResult.de}/> <DtRow label="Datum/Uhrzeit (Berlin)" value={convResult.de}/>
<DtRow label="ISO lokal" value={convResult.local}/> <DtRow label="Unix-Timestamp" value={convResult.unix}/>
<DtRow label="Unix / Moseszeit" value={convResult.unix}/> <DtRow label="Moseszeit" value={convResult.moses}/>
<DtRow label="Wochentag" value={convResult.wday}/> <DtRow label="Wochentag" value={convResult.wday}/>
<DtRow label="Kalenderwoche" value={`KW ${convResult.kw}`} muted/> <DtRow label="Kalenderwoche" value={`KW ${convResult.kw}`} muted/>
</div> </div>
)} )}
{!convResult && ( {!convResult && (
<div style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:11,padding:'10px 0'}}> <div style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:11,padding:'10px 0'}}>
Unix-Timestamp oder Datum eingeben alle Formate werden berechnet Einen der drei Werte eingeben alle anderen werden berechnet
</div> </div>
)} )}
<div style={{marginTop:14,padding:'10px 12px',borderRadius:8,background:'rgba(255,255,255,0.03)', <div style={{marginTop:14,padding:'10px 12px',borderRadius:8,background:'rgba(255,255,255,0.03)',
border:'1px solid rgba(255,255,255,0.07)'}}> border:'1px solid rgba(255,255,255,0.07)'}}>
<div style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:9,marginBottom:6}}>BEISPIEL</div> <div style={{color:'rgba(255,255,255,0.45)',fontFamily:'monospace',fontSize:9,marginBottom:6}}>FORMEL</div>
<div style={{color:'rgba(255,255,255,0.6)',fontFamily:'monospace',fontSize:11}}> <div style={{color:'rgba(255,255,255,0.6)',fontFamily:'monospace',fontSize:11}}>
Moseszeit <code style={{color:'#4ecdc4'}}>1685554093</code> = <code style={{color:'#4ecdc4'}}>31.05.2026 17:28:13</code> Moses + <code style={{color:'#4ecdc4'}}>94.687.200</code> = Unix &nbsp;·&nbsp;
<span style={{color:'rgba(255,255,255,0.4)',fontSize:10,marginLeft:8}}>(UTC, Jahr+3 Versatz)</span> Moseszeit <code style={{color:'#4ecdc4'}}>1685554093</code> = Unix <code style={{color:'#4ecdc4'}}>1780241293</code> = <code style={{color:'#4ecdc4'}}>31.05.2026 17:28:13</code>
</div> </div>
</div> </div>
</div> </div>