{"id":72,"date":"2024-06-18T08:14:54","date_gmt":"2024-06-18T08:14:54","guid":{"rendered":"https:\/\/helsinki-tallinn.com\/de\/?page_id=72"},"modified":"2026-02-24T08:13:11","modified_gmt":"2026-02-24T08:13:11","slug":"fahrplan","status":"publish","type":"page","link":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/","title":{"rendered":"Fahrplan Helsinki Tallinn"},"content":{"rendered":" <p>Hier sehen Sie den <strong>Live Fahrplan f\u00fcr die Strecke Helsinki Tallinn in beide Richtungen<\/strong>. Die \u00dcbersicht kombiniert alle drei Betreiber: <a href=\"https:\/\/helsinki-tallinn.com\/de\/viking-line\/\">Viking Line<\/a>, <a href=\"https:\/\/helsinki-tallinn.com\/de\/tallink-silja\/\">Tallink Silja<\/a> und <a href=\"https:\/\/helsinki-tallinn.com\/de\/eckero-line\/\">Ecker\u00f6 Line<\/a>.<\/p>   <p><strong>Standardm\u00e4\u00dfig werden die n\u00e4chsten 3 Tage geladen.<\/strong> \u00dcber die Datumswahl k\u00f6nnen Sie jedes gew\u00fcnschte Datum pr\u00fcfen.<\/p>   <p><strong>Wichtig:<\/strong> Die Abfahrtszeiten sind live und k\u00f6nnen sich durch Wetter, Hafenbetrieb oder operative Anpassungen \u00e4ndern. Pr\u00fcfen Sie am Reisetag zus\u00e4tzlich die Check in Regeln Ihres Betreibers.<\/p>   <p><strong>Hinweis:<\/strong> Wenn Sie in der Tabelle auf den Schiffsnamen klicken, \u00f6ffnen sich englische Detailseiten mit technischen Daten und teilweise Live Tracker.<\/p>   <h2 class=\"wp-block-heading\" id=\"helsinkitallinn\">Live Fahrplan Helsinki nach Tallinn<\/h2>   <p>Abfahrten ab dem <a href=\"https:\/\/helsinki-tallinn.com\/de\/helsinki-hafen\/\">Hafen Helsinki<\/a>. Angezeigt werden Abfahrtszeit, Ankunft, Fahrtdauer, Schiff und Betreiber.<\/p>  <div class=\"tp-wrap\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/wp-json\\\/timetables-pro\\\/v1\\\/timetables&quot;,&quot;route&quot;:161,&quot;days&quot;:3,&quot;autoload&quot;:true,&quot;label&quot;:&quot;Helsinki - Talinn&quot;,&quot;labels&quot;:{&quot;ui_date&quot;:&quot;Datum&quot;,&quot;ui_days&quot;:&quot;Tage&quot;,&quot;ui_button&quot;:&quot;Abfahrten&quot;,&quot;status_idle&quot;:&quot;Datum w\\u00e4hlen + zeigen&quot;,&quot;status_loading&quot;:&quot;L\\u00e4dt...&quot;,&quot;status_empty&quot;:&quot;Keine Abfahrten&quot;,&quot;status_found&quot;:&quot;%d Abfahrten&quot;,&quot;th_date&quot;:&quot;Datum&quot;,&quot;th_dep&quot;:&quot;Abf.&quot;,&quot;th_arr&quot;:&quot;Ank.&quot;,&quot;th_dur&quot;:&quot;Dauer&quot;,&quot;th_ship&quot;:&quot;Schiff&quot;,&quot;th_op&quot;:&quot;Oper.&quot;,&quot;th_route&quot;:&quot;Route&quot;,&quot;wd_sun&quot;:&quot;So&quot;,&quot;wd_mon&quot;:&quot;Mo&quot;,&quot;wd_tue&quot;:&quot;Di&quot;,&quot;wd_wed&quot;:&quot;Mi&quot;,&quot;wd_thu&quot;:&quot;Do&quot;,&quot;wd_fri&quot;:&quot;Fr&quot;,&quot;wd_sat&quot;:&quot;Sa&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Alle %s Abf. im Fahrplan&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Mehr %1$s + %2$s im Fahrplan&quot;,&quot;summary_footer_generic&quot;:&quot;Mehr im Fahrplan&quot;,&quot;summary_header&quot;:&quot;N\\u00e4chste 2 Abfahrten:&quot;,&quot;summary_no_upcoming&quot;:&quot;Keine n\\u00e4chsten Abf.&quot;,&quot;more_link&quot;:&quot;Mehr Abf.&quot;},&quot;showLogo&quot;:true,&quot;shipMap&quot;:{&quot;fi&quot;:&quot;Finlandia&quot;},&quot;shipLinks&quot;:{&quot;fi&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/finlandia\\\/&quot;,&quot;viking xprs&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/viking-xprs\\\/&quot;,&quot;mystar&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/mystar\\\/&quot;,&quot;victoria i&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/victoria\\\/&quot;,&quot;megastar&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/megastar\\\/&quot;},&quot;showShip&quot;:true}\">\n  <div class=\"tp-controls\" role=\"group\" aria-label=\"Timetable controls\">\n    <div>\n      <label for=\"tp-date\">Datum<\/label><br>\n      <input id=\"tp-date\" class=\"tp-date\" type=\"date\" aria-label=\"Datum\">\n    <\/div>\n    <div>\n      <label for=\"tp-range\">Tage<\/label><br>\n      <select id=\"tp-range\" class=\"tp-range\" aria-label=\"Tage\">\n        <option value=\"1\">1<\/option><option value=\"3\">3<\/option><option value=\"7\">7<\/option><option value=\"14\">14<\/option>\n      <\/select>\n    <\/div>\n    <div><button id=\"tp-load\" class=\"tp-btn\">Abfahrten<\/button><\/div>\n  <\/div>\n\n  <div id=\"tp-status\" class=\"tp-muted\" aria-live=\"polite\">Datum w\u00e4hlen + zeigen<\/div>\n  <div id=\"tp-results\"><\/div>\n\n  <div class=\"tp-loader\" aria-hidden=\"true\">\n    <div class=\"tp-loader-card\">\n      <div class=\"tp-spinner\" aria-hidden=\"true\"><\/div>\n      <div class=\"tp-loader-text\">L\u00e4dt...<\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n  const wrap   = document.currentScript.previousElementSibling;\n  const cfg    = JSON.parse(wrap.getAttribute('data-config')||'{}');\n  const L      = cfg.labels||{};\n  const dateEl = wrap.querySelector('#tp-date');\n  const daysEl = wrap.querySelector('#tp-range');\n  const btn    = wrap.querySelector('#tp-load');\n  const status = wrap.querySelector('#tp-status');\n  const out    = wrap.querySelector('#tp-results');\n  const loader = wrap.querySelector('.tp-loader');\n\n  const showShip = (cfg.showShip !== false && cfg.showShip !== 0 && cfg.showShip !== '0');\n\n  dateEl.valueAsDate = new Date();\n  Array.from(daysEl.options).forEach(o=>{ if(parseInt(o.value,10)===parseInt(cfg.days||7,10)) o.selected=true; });\n\n  function pad(n){ return String(n).padStart(2,'0'); }\n  function iso(d){ return d.getFullYear()+'-'+pad(d.getMonth()+1)+'-'+pad(d.getDate()); }\n  function toLocal(s){ return new Date(s); }\n  function hhmm(d){ return d.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'}); }\n  function dShort(d){ return d.toLocaleDateString([], {day:'numeric', month:'short'}); } \/\/ short, no year\n  function dur(m){ const h=Math.floor(m\/60), r=m%60; return r? (h+'h '+r+'m') : (h+'h'); }\n\n  const WD = [\n    L.wd_sun || 'SUN',\n    L.wd_mon || 'MON',\n    L.wd_tue || 'TUE',\n    L.wd_wed || 'WED',\n    L.wd_thu || 'THU',\n    L.wd_fri || 'FRI',\n    L.wd_sat || 'SAT'\n  ];\n\n  function setLoader(v){ loader.classList.toggle('show', !!v); loader.setAttribute('aria-hidden', v?'false':'true'); }\n\n  function opCell(r){\n    const name = r.opName || ('Operator '+(r.opId||''));\n    const logo = (cfg.showLogo && r.opLogo) ? '<img decoding=\"async\" src=\"'+r.opLogo+'\" alt=\"'+name+'\"> ' : '';\n    const label = logo + '<span>'+name+'<\/span>';\n    return r.opLink ? '<a class=\"tp-op\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+label+'<\/a>' : '<span class=\"tp-op\">'+label+'<\/span>';\n  }\n\n  function shipInfo(original){\n    const key = (original||'').toLowerCase().trim();\n    const label = (cfg.shipMap && cfg.shipMap[key]) || original || '';\n    const href  = (cfg.shipLinks && cfg.shipLinks[key]) || '';\n    return {label, href};\n  }\n\n  function shipBadge(original){\n    const s = shipInfo(original);\n    const badge = '<span class=\"tp-badge\">'+(s.label||'')+'<\/span>';\n    return s.href ? ('<a href=\"'+s.href+'\" target=\"_blank\" rel=\"nofollow noopener\">'+badge+'<\/a>') : badge;\n  }\n\n  function renderTable(rows){\n    const th = {date:L.th_date,dep:L.th_dep,arr:L.th_arr,dur:L.th_dur,ship:L.th_ship,op:L.th_op};\n\n    const headCells = [\n      '<th>'+th.date+'<\/th>',\n      '<th>'+th.dep+'<\/th>',\n      '<th>'+th.arr+'<\/th>',\n      '<th>'+th.dur+'<\/th>'\n    ];\n    if (showShip) {\n      headCells.push('<th>'+th.ship+'<\/th>');\n    }\n    headCells.push('<th>'+th.op+'<\/th>');\n\n    let html = '<table class=\"tp-table\"><thead><tr>'+headCells.join('')+'<\/tr><\/thead><tbody>';\n\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const cells = [\n        '<td>'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span><\/td>',\n        '<td>'+hhmm(r.dep)+'<\/td>',\n        '<td>'+hhmm(r.arr)+'<\/td>',\n        '<td>'+dur(r.min)+'<\/td>'\n      ];\n      if (showShip) {\n        cells.push('<td>'+shipBadge(r.ship)+'<\/td>');\n      }\n      cells.push('<td>'+opCell(r)+'<\/td>');\n      html += '<tr>'+cells.join('')+'<\/tr>';\n    });\n    html += '<\/tbody><\/table>';\n    return html;\n  }\n\n  function renderCards(rows){\n    const routeName = cfg.label || '';\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const times = hhmm(r.dep) + ' <span class=\"tp-arrow\">\u2192<\/span> ' + hhmm(r.arr);\n      html += '<div class=\"tp-card\">'+\n        \/\/ Row 1: Date + weekday + times\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\"><span class=\"tp-sub\">'+dShort(r.dep)+'<\/span><span class=\"tp-day\">'+dow+'<\/span><\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-time\">'+times+'<\/span><\/div>'+\n        '<\/div>';\n\n      if (showShip || routeName) {\n        html +=\n        \/\/ Row 2: Ship & Route (no prefixes)\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+(showShip ? shipBadge(r.ship) : '')+'<\/div>'+\n          (routeName ? ('<div class=\"rhs\">'+routeName+'<\/div>') : '<div class=\"rhs\"><\/div>')+\n        '<\/div>';\n      }\n\n      html +=\n        \/\/ Row 3: Operator (no book button)\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+opCell(r)+'<\/div>'+\n          '<div class=\"rhs\"><\/div>'+\n        '<\/div>'+\n      '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  async function load(){\n    btn.disabled = true; setLoader(true); status.textContent = L.status_loading;\n    const start = new Date(dateEl.value || new Date());\n    const days  = Math.max(1, parseInt(daysEl.value,10)||1);\n    const end   = new Date(start); end.setDate(start.getDate()+days-1);\n    const url = new URL(cfg.rest); url.searchParams.set('route', String(cfg.route));\n    url.searchParams.set('from', iso(start)); url.searchParams.set('to', iso(end));\n    try{\n      const res = await fetch(url.toString(), {credentials:'same-origin'});\n      if(!res.ok) throw new Error('HTTP '+res.status);\n      const json = await res.json();\n      const list = (json && json.data && Array.isArray(json.data.rows)) ? json.data.rows : [];\n      const rows = list.map(t=>({\n        opId:t.operatorId||null, opName:t.operatorName||'', opLogo:t.operatorLogo||'', opLink:t.operatorLink||'',\n        dep:toLocal(t.departureTime), arr:toLocal(t.arrivalTime), min:t.durationInMinutes||0, ship:t.shipName||''\n      })).sort((a,b)=>a.dep-b.dep);\n      if(rows.length===0){ status.textContent = L.status_empty; out.innerHTML=''; return; }\n      status.textContent = (cfg.label? (cfg.label+': '):'') + (L.status_found||'%d sailings found').replace('%d', rows.length);\n      out.innerHTML = renderTable(rows) + renderCards(rows);\n    }catch(e){\n      status.textContent = 'Failed to load data'; out.innerHTML = '<pre>'+String(e.message||e)+'<\/pre>';\n    }finally{ setLoader(false); btn.disabled=false; }\n  }\n\n  btn.addEventListener('click', load);\n  if (cfg.autoload) load();\n})();\n<\/script>\n\n  <h2 class=\"wp-block-heading\" id=\"tallinnhelsinki\">Live Fahrplan Tallinn nach Helsinki<\/h2>   <p>Abfahrten ab dem <a href=\"https:\/\/helsinki-tallinn.com\/de\/tallinn-hafen\/\">Hafen Tallinn<\/a>. Auch hier werden standardm\u00e4\u00dfig die n\u00e4chsten 3 Tage angezeigt.<\/p>  <div class=\"tp-wrap\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/wp-json\\\/timetables-pro\\\/v1\\\/timetables&quot;,&quot;route&quot;:162,&quot;days&quot;:3,&quot;autoload&quot;:true,&quot;label&quot;:&quot;Talinn - Helsinki&quot;,&quot;labels&quot;:{&quot;ui_date&quot;:&quot;Datum&quot;,&quot;ui_days&quot;:&quot;Tage&quot;,&quot;ui_button&quot;:&quot;Abfahrten&quot;,&quot;status_idle&quot;:&quot;Datum w\\u00e4hlen + zeigen&quot;,&quot;status_loading&quot;:&quot;L\\u00e4dt...&quot;,&quot;status_empty&quot;:&quot;Keine Abfahrten&quot;,&quot;status_found&quot;:&quot;%d Abfahrten&quot;,&quot;th_date&quot;:&quot;Datum&quot;,&quot;th_dep&quot;:&quot;Abf.&quot;,&quot;th_arr&quot;:&quot;Ank.&quot;,&quot;th_dur&quot;:&quot;Dauer&quot;,&quot;th_ship&quot;:&quot;Schiff&quot;,&quot;th_op&quot;:&quot;Oper.&quot;,&quot;th_route&quot;:&quot;Route&quot;,&quot;wd_sun&quot;:&quot;So&quot;,&quot;wd_mon&quot;:&quot;Mo&quot;,&quot;wd_tue&quot;:&quot;Di&quot;,&quot;wd_wed&quot;:&quot;Mi&quot;,&quot;wd_thu&quot;:&quot;Do&quot;,&quot;wd_fri&quot;:&quot;Fr&quot;,&quot;wd_sat&quot;:&quot;Sa&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Alle %s Abf. im Fahrplan&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Mehr %1$s + %2$s im Fahrplan&quot;,&quot;summary_footer_generic&quot;:&quot;Mehr im Fahrplan&quot;,&quot;summary_header&quot;:&quot;N\\u00e4chste 2 Abfahrten:&quot;,&quot;summary_no_upcoming&quot;:&quot;Keine n\\u00e4chsten Abf.&quot;,&quot;more_link&quot;:&quot;Mehr Abf.&quot;},&quot;showLogo&quot;:true,&quot;shipMap&quot;:{&quot;fi&quot;:&quot;Finlandia&quot;},&quot;shipLinks&quot;:{&quot;fi&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/finlandia\\\/&quot;,&quot;viking xprs&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/viking-xprs\\\/&quot;,&quot;mystar&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/mystar\\\/&quot;,&quot;victoria i&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/victoria\\\/&quot;,&quot;megastar&quot;:&quot;https:\\\/\\\/helsinki-tallinn.com\\\/de\\\/megastar\\\/&quot;},&quot;showShip&quot;:true}\">\n  <div class=\"tp-controls\" role=\"group\" aria-label=\"Timetable controls\">\n    <div>\n      <label for=\"tp-date\">Datum<\/label><br>\n      <input id=\"tp-date\" class=\"tp-date\" type=\"date\" aria-label=\"Datum\">\n    <\/div>\n    <div>\n      <label for=\"tp-range\">Tage<\/label><br>\n      <select id=\"tp-range\" class=\"tp-range\" aria-label=\"Tage\">\n        <option value=\"1\">1<\/option><option value=\"3\">3<\/option><option value=\"7\">7<\/option><option value=\"14\">14<\/option>\n      <\/select>\n    <\/div>\n    <div><button id=\"tp-load\" class=\"tp-btn\">Abfahrten<\/button><\/div>\n  <\/div>\n\n  <div id=\"tp-status\" class=\"tp-muted\" aria-live=\"polite\">Datum w\u00e4hlen + zeigen<\/div>\n  <div id=\"tp-results\"><\/div>\n\n  <div class=\"tp-loader\" aria-hidden=\"true\">\n    <div class=\"tp-loader-card\">\n      <div class=\"tp-spinner\" aria-hidden=\"true\"><\/div>\n      <div class=\"tp-loader-text\">L\u00e4dt...<\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n  const wrap   = document.currentScript.previousElementSibling;\n  const cfg    = JSON.parse(wrap.getAttribute('data-config')||'{}');\n  const L      = cfg.labels||{};\n  const dateEl = wrap.querySelector('#tp-date');\n  const daysEl = wrap.querySelector('#tp-range');\n  const btn    = wrap.querySelector('#tp-load');\n  const status = wrap.querySelector('#tp-status');\n  const out    = wrap.querySelector('#tp-results');\n  const loader = wrap.querySelector('.tp-loader');\n\n  const showShip = (cfg.showShip !== false && cfg.showShip !== 0 && cfg.showShip !== '0');\n\n  dateEl.valueAsDate = new Date();\n  Array.from(daysEl.options).forEach(o=>{ if(parseInt(o.value,10)===parseInt(cfg.days||7,10)) o.selected=true; });\n\n  function pad(n){ return String(n).padStart(2,'0'); }\n  function iso(d){ return d.getFullYear()+'-'+pad(d.getMonth()+1)+'-'+pad(d.getDate()); }\n  function toLocal(s){ return new Date(s); }\n  function hhmm(d){ return d.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'}); }\n  function dShort(d){ return d.toLocaleDateString([], {day:'numeric', month:'short'}); } \/\/ short, no year\n  function dur(m){ const h=Math.floor(m\/60), r=m%60; return r? (h+'h '+r+'m') : (h+'h'); }\n\n  const WD = [\n    L.wd_sun || 'SUN',\n    L.wd_mon || 'MON',\n    L.wd_tue || 'TUE',\n    L.wd_wed || 'WED',\n    L.wd_thu || 'THU',\n    L.wd_fri || 'FRI',\n    L.wd_sat || 'SAT'\n  ];\n\n  function setLoader(v){ loader.classList.toggle('show', !!v); loader.setAttribute('aria-hidden', v?'false':'true'); }\n\n  function opCell(r){\n    const name = r.opName || ('Operator '+(r.opId||''));\n    const logo = (cfg.showLogo && r.opLogo) ? '<img decoding=\"async\" src=\"'+r.opLogo+'\" alt=\"'+name+'\"> ' : '';\n    const label = logo + '<span>'+name+'<\/span>';\n    return r.opLink ? '<a class=\"tp-op\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+label+'<\/a>' : '<span class=\"tp-op\">'+label+'<\/span>';\n  }\n\n  function shipInfo(original){\n    const key = (original||'').toLowerCase().trim();\n    const label = (cfg.shipMap && cfg.shipMap[key]) || original || '';\n    const href  = (cfg.shipLinks && cfg.shipLinks[key]) || '';\n    return {label, href};\n  }\n\n  function shipBadge(original){\n    const s = shipInfo(original);\n    const badge = '<span class=\"tp-badge\">'+(s.label||'')+'<\/span>';\n    return s.href ? ('<a href=\"'+s.href+'\" target=\"_blank\" rel=\"nofollow noopener\">'+badge+'<\/a>') : badge;\n  }\n\n  function renderTable(rows){\n    const th = {date:L.th_date,dep:L.th_dep,arr:L.th_arr,dur:L.th_dur,ship:L.th_ship,op:L.th_op};\n\n    const headCells = [\n      '<th>'+th.date+'<\/th>',\n      '<th>'+th.dep+'<\/th>',\n      '<th>'+th.arr+'<\/th>',\n      '<th>'+th.dur+'<\/th>'\n    ];\n    if (showShip) {\n      headCells.push('<th>'+th.ship+'<\/th>');\n    }\n    headCells.push('<th>'+th.op+'<\/th>');\n\n    let html = '<table class=\"tp-table\"><thead><tr>'+headCells.join('')+'<\/tr><\/thead><tbody>';\n\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const cells = [\n        '<td>'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span><\/td>',\n        '<td>'+hhmm(r.dep)+'<\/td>',\n        '<td>'+hhmm(r.arr)+'<\/td>',\n        '<td>'+dur(r.min)+'<\/td>'\n      ];\n      if (showShip) {\n        cells.push('<td>'+shipBadge(r.ship)+'<\/td>');\n      }\n      cells.push('<td>'+opCell(r)+'<\/td>');\n      html += '<tr>'+cells.join('')+'<\/tr>';\n    });\n    html += '<\/tbody><\/table>';\n    return html;\n  }\n\n  function renderCards(rows){\n    const routeName = cfg.label || '';\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const times = hhmm(r.dep) + ' <span class=\"tp-arrow\">\u2192<\/span> ' + hhmm(r.arr);\n      html += '<div class=\"tp-card\">'+\n        \/\/ Row 1: Date + weekday + times\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\"><span class=\"tp-sub\">'+dShort(r.dep)+'<\/span><span class=\"tp-day\">'+dow+'<\/span><\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-time\">'+times+'<\/span><\/div>'+\n        '<\/div>';\n\n      if (showShip || routeName) {\n        html +=\n        \/\/ Row 2: Ship & Route (no prefixes)\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+(showShip ? shipBadge(r.ship) : '')+'<\/div>'+\n          (routeName ? ('<div class=\"rhs\">'+routeName+'<\/div>') : '<div class=\"rhs\"><\/div>')+\n        '<\/div>';\n      }\n\n      html +=\n        \/\/ Row 3: Operator (no book button)\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+opCell(r)+'<\/div>'+\n          '<div class=\"rhs\"><\/div>'+\n        '<\/div>'+\n      '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  async function load(){\n    btn.disabled = true; setLoader(true); status.textContent = L.status_loading;\n    const start = new Date(dateEl.value || new Date());\n    const days  = Math.max(1, parseInt(daysEl.value,10)||1);\n    const end   = new Date(start); end.setDate(start.getDate()+days-1);\n    const url = new URL(cfg.rest); url.searchParams.set('route', String(cfg.route));\n    url.searchParams.set('from', iso(start)); url.searchParams.set('to', iso(end));\n    try{\n      const res = await fetch(url.toString(), {credentials:'same-origin'});\n      if(!res.ok) throw new Error('HTTP '+res.status);\n      const json = await res.json();\n      const list = (json && json.data && Array.isArray(json.data.rows)) ? json.data.rows : [];\n      const rows = list.map(t=>({\n        opId:t.operatorId||null, opName:t.operatorName||'', opLogo:t.operatorLogo||'', opLink:t.operatorLink||'',\n        dep:toLocal(t.departureTime), arr:toLocal(t.arrivalTime), min:t.durationInMinutes||0, ship:t.shipName||''\n      })).sort((a,b)=>a.dep-b.dep);\n      if(rows.length===0){ status.textContent = L.status_empty; out.innerHTML=''; return; }\n      status.textContent = (cfg.label? (cfg.label+': '):'') + (L.status_found||'%d sailings found').replace('%d', rows.length);\n      out.innerHTML = renderTable(rows) + renderCards(rows);\n    }catch(e){\n      status.textContent = 'Failed to load data'; out.innerHTML = '<pre>'+String(e.message||e)+'<\/pre>';\n    }finally{ setLoader(false); btn.disabled=false; }\n  }\n\n  btn.addEventListener('click', load);\n  if (cfg.autoload) load();\n})();\n<\/script>\n\n  <p><strong>Terminal und Check in Informationen<\/strong> finden Sie in den Hafen\u00fcbersichten. Bei starkem Wind oder winterlichen Bedingungen empfehlen wir zus\u00e4tzlich einen Blick auf die <a href=\"https:\/\/helsinki-tallinn.com\/de\/wettervorhersage\/\">Wettervorhersage<\/a>. Hintergrund zu St\u00f6rungen und Ausf\u00e4llen finden Sie auf der englischen Seite zu <a href=\"https:\/\/helsinki-tallinn.com\/cancellations-and-weather\/\">cancellations and weather (EN)<\/a>.<\/p> ","protected":false},"excerpt":{"rendered":"<p>Hier sehen Sie den Live Fahrplan f\u00fcr die Strecke Helsinki Tallinn in beide Richtungen. Die \u00dcbersicht kombiniert alle drei Betreiber: [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":200,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"inline_featured_image":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-72","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Fahrplan Helsinki Tallinn - Helsinki Tallinn F\u00e4hre<\/title>\n<meta name=\"description\" content=\"Entdecken Sie hier den vollst\u00e4ndigen F\u00e4hrfahrplan f\u00fcr die \u00dcberfahrt zwischen Helsinki und Tallinn (Viking Line, Ecker\u00f6 Line und Tallink).\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fahrplan Helsinki Tallinn - Helsinki Tallinn F\u00e4hre\" \/>\n<meta property=\"og:description\" content=\"Entdecken Sie hier den vollst\u00e4ndigen F\u00e4hrfahrplan f\u00fcr die \u00dcberfahrt zwischen Helsinki und Tallinn (Viking Line, Ecker\u00f6 Line und Tallink).\" \/>\n<meta property=\"og:url\" content=\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/\" \/>\n<meta property=\"og:site_name\" content=\"Helsinki Tallinn F\u00e4hre\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-24T08:13:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/near-helsinki.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"500\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data1\" content=\"2\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/\",\"url\":\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/\",\"name\":\"Fahrplan Helsinki Tallinn - Helsinki Tallinn F\u00e4hre\",\"isPartOf\":{\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/near-helsinki.jpg\",\"datePublished\":\"2024-06-18T08:14:54+00:00\",\"dateModified\":\"2026-02-24T08:13:11+00:00\",\"description\":\"Entdecken Sie hier den vollst\u00e4ndigen F\u00e4hrfahrplan f\u00fcr die \u00dcberfahrt zwischen Helsinki und Tallinn (Viking Line, Ecker\u00f6 Line und Tallink).\",\"breadcrumb\":{\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#primaryimage\",\"url\":\"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/near-helsinki.jpg\",\"contentUrl\":\"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/near-helsinki.jpg\",\"width\":1920,\"height\":500,\"caption\":\"near-helsinki\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Helsinki Tallinn\",\"item\":\"https:\/\/helsinki-tallinn.com\/de\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Fahrplan Helsinki Tallinn\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/#website\",\"url\":\"https:\/\/helsinki-tallinn.com\/de\/\",\"name\":\"Helsinki Tallinn F\u00e4hre\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/helsinki-tallinn.com\/de\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/#organization\",\"name\":\"Helsinki Tallinn F\u00e4hre\",\"url\":\"https:\/\/helsinki-tallinn.com\/de\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/Helsinki-Talinn-powered.png\",\"contentUrl\":\"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/Helsinki-Talinn-powered.png\",\"width\":700,\"height\":200,\"caption\":\"Helsinki Tallinn F\u00e4hre\"},\"image\":{\"@id\":\"https:\/\/helsinki-tallinn.com\/de\/#\/schema\/logo\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Fahrplan Helsinki Tallinn - Helsinki Tallinn F\u00e4hre","description":"Entdecken Sie hier den vollst\u00e4ndigen F\u00e4hrfahrplan f\u00fcr die \u00dcberfahrt zwischen Helsinki und Tallinn (Viking Line, Ecker\u00f6 Line und Tallink).","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/","og_locale":"de_DE","og_type":"article","og_title":"Fahrplan Helsinki Tallinn - Helsinki Tallinn F\u00e4hre","og_description":"Entdecken Sie hier den vollst\u00e4ndigen F\u00e4hrfahrplan f\u00fcr die \u00dcberfahrt zwischen Helsinki und Tallinn (Viking Line, Ecker\u00f6 Line und Tallink).","og_url":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/","og_site_name":"Helsinki Tallinn F\u00e4hre","article_modified_time":"2026-02-24T08:13:11+00:00","og_image":[{"width":1920,"height":500,"url":"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/near-helsinki.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Gesch\u00e4tzte Lesezeit":"2\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/","url":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/","name":"Fahrplan Helsinki Tallinn - Helsinki Tallinn F\u00e4hre","isPartOf":{"@id":"https:\/\/helsinki-tallinn.com\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#primaryimage"},"image":{"@id":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#primaryimage"},"thumbnailUrl":"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/near-helsinki.jpg","datePublished":"2024-06-18T08:14:54+00:00","dateModified":"2026-02-24T08:13:11+00:00","description":"Entdecken Sie hier den vollst\u00e4ndigen F\u00e4hrfahrplan f\u00fcr die \u00dcberfahrt zwischen Helsinki und Tallinn (Viking Line, Ecker\u00f6 Line und Tallink).","breadcrumb":{"@id":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/helsinki-tallinn.com\/de\/fahrplan\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#primaryimage","url":"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/near-helsinki.jpg","contentUrl":"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/near-helsinki.jpg","width":1920,"height":500,"caption":"near-helsinki"},{"@type":"BreadcrumbList","@id":"https:\/\/helsinki-tallinn.com\/de\/fahrplan\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Helsinki Tallinn","item":"https:\/\/helsinki-tallinn.com\/de\/"},{"@type":"ListItem","position":2,"name":"Fahrplan Helsinki Tallinn"}]},{"@type":"WebSite","@id":"https:\/\/helsinki-tallinn.com\/de\/#website","url":"https:\/\/helsinki-tallinn.com\/de\/","name":"Helsinki Tallinn F\u00e4hre","description":"","publisher":{"@id":"https:\/\/helsinki-tallinn.com\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/helsinki-tallinn.com\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/helsinki-tallinn.com\/de\/#organization","name":"Helsinki Tallinn F\u00e4hre","url":"https:\/\/helsinki-tallinn.com\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/helsinki-tallinn.com\/de\/#\/schema\/logo\/image\/","url":"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/Helsinki-Talinn-powered.png","contentUrl":"https:\/\/helsinki-tallinn.com\/de\/wp-content\/uploads\/sites\/2\/2026\/02\/Helsinki-Talinn-powered.png","width":700,"height":200,"caption":"Helsinki Tallinn F\u00e4hre"},"image":{"@id":"https:\/\/helsinki-tallinn.com\/de\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/helsinki-tallinn.com\/de\/wp-json\/wp\/v2\/pages\/72","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/helsinki-tallinn.com\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/helsinki-tallinn.com\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/helsinki-tallinn.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/helsinki-tallinn.com\/de\/wp-json\/wp\/v2\/comments?post=72"}],"version-history":[{"count":10,"href":"https:\/\/helsinki-tallinn.com\/de\/wp-json\/wp\/v2\/pages\/72\/revisions"}],"predecessor-version":[{"id":239,"href":"https:\/\/helsinki-tallinn.com\/de\/wp-json\/wp\/v2\/pages\/72\/revisions\/239"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/helsinki-tallinn.com\/de\/wp-json\/wp\/v2\/media\/200"}],"wp:attachment":[{"href":"https:\/\/helsinki-tallinn.com\/de\/wp-json\/wp\/v2\/media?parent=72"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}