Skip to content

Instantly share code, notes, and snippets.

@iiic
Last active May 29, 2018 10:21
Show Gist options
  • Save iiic/d1723d491633d2b0cbdbf162fe5e2bb1 to your computer and use it in GitHub Desktop.
Save iiic/d1723d491633d2b0cbdbf162fe5e2bb1 to your computer and use it in GitHub Desktop.
Element time s atributem datetime nebo s atributem data-raw-content změní na 'živé' zobrazení data a času, interval pravidelné aktualizace se dá nastavit.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tagy předělávkou textareji na element s atributem contenteditable</title>
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<style>
@charset "UTF-8";
body {
font-family: 'Roboto', sans-serif;
}
</style>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.12/css/all.css" integrity="sha384-G0fIWCsCzJIMAVNQPfjH08cyYaUtMwjJwqiRKxxE/rx96Uroj1BtIQ6MLJuheaO9"
crossorigin="anonymous">
</head>
<body>
<ul>
<li>aktuální časy:
<ul>
<li>
<time id="a"></time>
</li>
<li>
<time id="b"></time>
</li>
<li>
<time id="c"></time>
</li>
<li>
<time id="d"></time>
</li>
<li>
<time id="e"></time>
</li>
<li>
<time id="f"></time>
</li>
<li>
<time id="g"></time>
</li>
<li>
<time id="h"></time>
</li>
<li>
<time id="i"></time>
</li>
<li>
<time id="j"></time>
</li>
<li>
<time id="k"></time>
</li>
<li>
<time id="l"></time>
</li>
<li>
<time id="m"></time>
</li>
<li>
<time id="n"></time>
</li>
<li>
<time id="o"></time>
</li>
<li>
<time id="p"></time>
</li>
<li>
<time id="q"></time>
</li>
<li>
<time id="r"></time>
</li>
<li>
<time id="s"></time>
</li>
<li>
<time id="t"></time>
</li>
<li>
<time id="u"></time>
</li>
<li>
<time id="v"></time>
</li>
<li>
<time id="w"></time>
</li>
<li>
<time id="x"></time>
</li>
<li>
<time id="y"></time>
</li>
<li>
<time id="z"></time>
</li>
</ul>
</li>
<li>pavné časy:
<ul>
<li>@todo :</li>
<li>
<time datetime="2018-05-28T07:49:28.000Z"></time>
</li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</li>
</ul>
<script>
( () => { // data pro nakrmení dema… není součástí scriptu!
const a = new Date();
const b = new Date(); b.setSeconds( b.getSeconds() - 1 );
const c = new Date(); c.setSeconds( c.getSeconds() - 5 );
const d = new Date(); d.setSeconds( d.getSeconds() - 10 );
const e = new Date(); e.setSeconds( e.getSeconds() - 30 );
const f = new Date(); f.setSeconds( f.getSeconds() - 58 );
const g = new Date(); g.setSeconds( g.getSeconds() - 89 );
const h = new Date(); h.setSeconds( h.getSeconds() );
const i = new Date(); i.setSeconds( i.getSeconds() );
const j = new Date(); j.setSeconds( j.getSeconds() );
const k = new Date(); k.setSeconds( k.getSeconds() );
const l = new Date(); l.setSeconds( l.getSeconds() );
const m = new Date(); m.setSeconds( m.getSeconds() - 60 * 2 );
const n = new Date(); n.setSeconds( n.getSeconds() - 60 * 3 );
const o = new Date(); o.setSeconds( o.getSeconds() - 60 * 5 );
const p = new Date(); p.setSeconds( p.getSeconds() - 60 * 10 );
const q = new Date(); q.setSeconds( q.getSeconds() - 60 * 20 );
const r = new Date(); r.setSeconds( r.getSeconds() - 60 * 30 );
const s = new Date(); s.setSeconds( s.getSeconds() - 60 * 60 );
const t = new Date(); t.setSeconds( t.getSeconds() - 60 * 60 * 2 );
const u = new Date(); u.setSeconds( u.getSeconds() - 60 * 60 * 5 );
const v = new Date(); v.setSeconds( v.getSeconds() - 60 * 60 * 10 );
const w = new Date(); w.setSeconds( w.getSeconds() - 60 * 60 * 24 );
const x = new Date(); x.setSeconds( x.getSeconds() - 60 * 60 * 25 );
const y = new Date(); y.setSeconds( y.getSeconds() - 60 * 60 * 30 );
const z = new Date(); z.setSeconds( z.getSeconds() - 60 * 60 * 50 );
document.getElementById( 'a' ).setAttribute( 'data-raw-content', Math.round( a / 1000 ) );
document.getElementById( 'b' ).setAttribute( 'data-raw-content', Math.round( b / 1000 ) );
document.getElementById( 'c' ).setAttribute( 'data-raw-content', Math.round( c / 1000 ) );
document.getElementById( 'd' ).setAttribute( 'data-raw-content', Math.round( d / 1000 ) );
document.getElementById( 'e' ).setAttribute( 'data-raw-content', Math.round( e / 1000 ) );
document.getElementById( 'f' ).setAttribute( 'data-raw-content', Math.round( f / 1000 ) );
document.getElementById( 'g' ).setAttribute( 'data-raw-content', Math.round( g / 1000 ) );
document.getElementById( 'h' ).setAttribute( 'data-raw-content', Math.round( h / 1000 ) );
document.getElementById( 'i' ).setAttribute( 'data-raw-content', Math.round( i / 1000 ) );
document.getElementById( 'j' ).setAttribute( 'data-raw-content', Math.round( j / 1000 ) );
document.getElementById( 'k' ).setAttribute( 'data-raw-content', Math.round( k / 1000 ) );
document.getElementById( 'l' ).setAttribute( 'data-raw-content', Math.round( l / 1000 ) );
document.getElementById( 'm' ).setAttribute( 'data-raw-content', Math.round( m / 1000 ) );
document.getElementById( 'n' ).setAttribute( 'data-raw-content', Math.round( n / 1000 ) );
document.getElementById( 'o' ).setAttribute( 'data-raw-content', Math.round( o / 1000 ) );
document.getElementById( 'p' ).setAttribute( 'data-raw-content', Math.round( p / 1000 ) );
document.getElementById( 'q' ).setAttribute( 'data-raw-content', Math.round( q / 1000 ) );
document.getElementById( 'r' ).setAttribute( 'data-raw-content', Math.round( r / 1000 ) );
document.getElementById( 's' ).setAttribute( 'data-raw-content', Math.round( s / 1000 ) );
document.getElementById( 't' ).setAttribute( 'data-raw-content', Math.round( t / 1000 ) );
document.getElementById( 'u' ).setAttribute( 'data-raw-content', Math.round( u / 1000 ) );
document.getElementById( 'v' ).setAttribute( 'data-raw-content', Math.round( v / 1000 ) );
document.getElementById( 'w' ).setAttribute( 'data-raw-content', Math.round( w / 1000 ) );
document.getElementById( 'x' ).setAttribute( 'data-raw-content', Math.round( x / 1000 ) );
document.getElementById( 'y' ).setAttribute( 'data-raw-content', Math.round( y / 1000 ) );
document.getElementById( 'z' ).setAttribute( 'data-raw-content', Math.round( z / 1000 ) );
} )();
</script>
<script>
'use strict';
( function ()
{
const LANG = window[ 'lang' ] || 'en';
const DATE_FORMAT = window[ 'dateFormat' ] || 'long';
const RENEW_INTERVAL = window[ 'renewInterval' ] || 15; // (float) in secs
const TIME_DIFF = 300; // (float) in secs
const TIME_UNITS_IN_LANGUAGES = { // for live time view
'en': {
'preffix': '',
'suffix': ' ago',
'justNow': 'just now',
'today': 'today',
'yesterday': 'yesterday',
'theDayBeforeYesterday': null,
'plural': ( n = 0 ) => { return n === 1 ? 0 : 1; },
'long': {
s: [ 'second', 'seconds' ],
m: [ 'minute', 'minutes' ],
h: [ 'hour', 'hours' ],
d: [ 'day', 'days' ],
w: [ 'week', 'weeks' ],
},
'short': {
s: 's',
m: 'm',
h: 'h',
d: 'd',
w: 'w',
},
},
'cs': {
'preffix': '',
'suffix': '',
'justNow': 'nyní',
'today': 'dnes',
'yesterday': 'včera',
'theDayBeforeYesterday': null,
'plural': ( n = 0 ) => { return n === 1 ? 0 : ( ( n >= 2 && n <= 4 ) ? 1 : 2 ); },
'long': {
s: [ 'sekunda', 'sekundy', 'sekund' ],
m: [ 'minuta', 'minuty', 'minut' ],
h: [ 'hodina', 'hodiny', 'hodin' ],
d: [ 'den', 'dny', 'dní' ],
w: [ 'týden', 'týdny', 'týdnů' ],
},
'short': {
s: 's',
m: 'min.',
h: 'dny',
d: 'h.',
w: 'týd.',
},
},
};
/**
* @todo : description
*/
function renewDateTextContent ()
{ // can be runed periodicly
document.querySelectorAll( 'time' ).forEach( (/** @type {HTMLTimeElement} */ element ) =>
{ // @todo : take time also from time[datetime] and maybe time from microformats date
let date = new Date( element.dateTime );
if ( isNaN( date.valueOf() ) ) {
date = new Date( Number( element.getAttribute( 'data-raw-content' ) ) * 1000 );
}
if ( !isNaN( date.valueOf() ) ) {
const timeDiff = getTimeDiff( date, new Date(), false, LANG, DATE_FORMAT );
if ( timeDiff && timeDiff.length > 1 ) {
element.textContent = timeDiff;
if ( !element.title ) {
element.title = date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
}
if ( !element.dateTime ) {
element.dateTime = date.toISOString();
}
}
}
} );
}
/**
* @todo : description
*/
function getTimeDiff ( /** @type {Date} */ timeA, /** @type {Date} */ timeB, relative = false, lang = 'en', type = 'long' )
{
const s = 1 * 1000;
const m = 60 * s;
const h = 60 * m;
const d = 24 * h;
const w = 7 * d;
const justNow = 5 * s;
const stop = 4 * w;
if ( relative && ( timeA > timeB ) ) {
return false;
}
const inflect = ( /** @type { String | Array } */ term, /** @type {Number} */ n = 0, /** @type {Function} */ pluralFunction ) =>
{
if ( pluralFunction && Array.isArray( term ) ) {
return term[ pluralFunction( n ) ];
}
return term;
};
const diff = Math.abs( Number( timeA ) - Number( timeB ) );
const rc = ( int = 0 ) =>
{
return Math.floor( int * ( ( 1 / TIME_DIFF ) / 1000 ) );
};
const currentDate = new Date();
const closerDate = [ timeA, timeB ].reduce( ( prev, curr ) =>
{
return ( Math.abs( Number( curr ) - Number( currentDate ) ) < Math.abs( Number( prev ) - Number( currentDate ) ) ? curr : prev );
} );
const UNITS = TIME_UNITS_IN_LANGUAGES[ lang ];
const DIVIDER = ' ';
const coolDateString = ( name = '', n = 0 ) =>
{
return UNITS.preffix + n + DIVIDER + inflect( name, n, UNITS.plural ) + UNITS.suffix;
};
if ( diff < justNow - 1 * s ) { // no SWITCH… switch() have very bad performance!
return UNITS.justNow;
} else if ( diff < m - 1 * s ) {
return coolDateString( UNITS[ type ].s, Math.round( diff / s ) );
} else if ( diff < h - 1 * s ) {
return coolDateString( UNITS[ type ].m, Math.round( diff / m ) );
} else if ( diff < d - 1 * s ) {
return coolDateString( UNITS[ type ].h, Math.round( diff / h ) );
} else if ( diff < w - 1 * s ) {
if ( diff < 3 * d && ( rc( Number( closerDate ) ) === rc( Number( currentDate ) ) ) ) {
const comparedDate = ( closerDate === timeA ) ? timeB : timeA;
const yesterdayDate = new Date();
yesterdayDate.setDate( yesterdayDate.getDate() - 1 );
const theDayBeforeYesterdayDayDate = new Date();
theDayBeforeYesterdayDayDate.setDate( theDayBeforeYesterdayDayDate.getDate() - 2 );
const comparedShred = String( comparedDate.getDate() ) + comparedDate.getMonth() + comparedDate.getFullYear();
const todayShred = String( currentDate.getDate() ) + currentDate.getMonth() + currentDate.getFullYear();
const yesterdayShred = String( yesterdayDate.getDate() ) + yesterdayDate.getMonth() + yesterdayDate.getFullYear();
const theDayBeforeYesterdayShred = String( theDayBeforeYesterdayDayDate.getDate() ) + theDayBeforeYesterdayDayDate.getMonth() + theDayBeforeYesterdayDayDate.getFullYear();
if ( UNITS.today && comparedShred === todayShred ) {
return UNITS.today + DIVIDER + comparedDate.toLocaleTimeString();
} else if ( UNITS.yesterday && comparedShred === yesterdayShred ) {
return UNITS.yesterday + DIVIDER + comparedDate.toLocaleTimeString();
} else if ( UNITS.theDayBeforeYesterday && comparedShred === theDayBeforeYesterdayShred ) {
return UNITS.theDayBeforeYesterday + DIVIDER + comparedDate.toLocaleTimeString();
}
}
return coolDateString( UNITS[ type ].d, Math.round( diff / d ) );
} else if ( diff < stop - 1 * s ) {
return coolDateString( UNITS[ type ].w, Math.round( diff / w ) );
}
return true;
}
window.setInterval( renewDateTextContent, RENEW_INTERVAL * 1000 );
window[ 'renewDateTextContent' ] = renewDateTextContent;
renewDateTextContent();
} )();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment