{"id":89,"date":"2025-01-09T12:56:55","date_gmt":"2025-01-09T12:56:55","guid":{"rendered":"https:\/\/dover-dunkirk.com\/fr\/vaartijden\/"},"modified":"2026-09-28T20:04:57","modified_gmt":"2026-09-28T20:04:57","slug":"horaires-des-traversees","status":"publish","type":"page","link":"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/","title":{"rendered":"Horaires du ferry Dunkerque vers Douvres"},"content":{"rendered":"\n<div class=\"dd-hero dd-hero--page\"><img fetchpriority=\"high\" src=\"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2026\/09\/delft-seaways-bow-loading-ramp.webp\" alt=\"Le Delft Seaways \u00e0 quai \u00e0 Loon-Plage, rampe abaiss\u00e9e\" width=\"1400\" height=\"1050\" fetchpriority=\"high\" decoding=\"async\"><\/div><div class=\"dd-wrap\">\n\t<div class=\"dd-page-head dd-page-head--card\">\n\t\t<h1>Horaires du ferry Dunkerque vers Douvres<\/h1>\n\t\t<p class=\"dd-lede\">Les d\u00e9parts DFDS ont lieu environ toutes les deux heures, dans les deux sens, avec un d\u00e9part de nuit certains jours. Ci-dessous les d\u00e9parts du jour, les horaires de la semaine \u00e0 venir et les heures de fermeture de l&rsquo;enregistrement. Les heures de d\u00e9part sont en heure locale du port de d\u00e9part.<\/p>\n\t\t<div class=\"dd-meta\"><span class=\"dd-updated\"><svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\"\/><path d=\"M12 7v5l3 2\"\/><\/svg>Mis \u00e0 jour 28 septembre 2026<\/span><span class=\"dd-small dd-muted\">Source : horaires DFDS via DirectFerries, actualis\u00e9 chaque minute<\/span><\/div>\n\t<\/div>\n\n\t<div class=\"dd-page\">\n\t\t<div class=\"dd-main\">\n\t\t\t<section id=\"aujourdhui\">\n\t\t\t\t<h2>D\u00e9parts du jour<\/h2>\n\t\t\t\t<p>Les deux sens, avec l&rsquo;heure de fermeture de l&rsquo;enregistrement. Dunkerque et Douvres sont dans des fuseaux horaires diff\u00e9rents ; c&rsquo;est pourquoi le billet n&rsquo;affiche qu&rsquo;une heure d&rsquo;\u00e9cart vers l&rsquo;Angleterre et trois heures vers la France, pour deux heures de mer dans les deux cas.<\/p>\n\t\t\t\t<section class=\"dd-board dd-board--full\" aria-label=\"D\u00e9parts du jour\"><div class=\"dd-board__head\"><p class=\"dd-board__title\">D\u00e9parts du jour<\/p><span class=\"dd-board__live\"><i><\/i>En direct <span class=\"dd-board__upd\">\u00b7 mis \u00e0 jour \u00e0 00:55<\/span><\/span><\/div><div class=\"dd-board__clocks\"><div class=\"dd-board__clock\" data-tz=\"Europe\/Paris\"><span class=\"dd-board__port\">Dunkerque<\/span><span class=\"dd-board__time dd-num\" data-dd-clock>01:55<\/span><span class=\"dd-board__zone\" data-dd-zone>CEST<\/span><\/div><div class=\"dd-board__mid\">2 h de travers\u00e9e<br>Royaume-Uni -1 h<\/div><div class=\"dd-board__clock is-right\" data-tz=\"Europe\/London\"><span class=\"dd-board__port\">Douvres<\/span><span class=\"dd-board__time dd-num\" data-dd-clock>00:55<\/span><span class=\"dd-board__zone\" data-dd-zone>BST<\/span><\/div><\/div><div class=\"dd-board__pane is-on\" id=\"dd-pane-99\" role=\"tabpanel\" aria-labelledby=\"dd-tab-99\"><h3 class=\"dd-board__pane-title\">Dunkerque \u2192 Douvres<\/h3><table class=\"dd-board__table\"><thead><tr><th>D\u00e9part<\/th><th>Arriv\u00e9e<\/th><th>Enregistrement avant<\/th><th><\/th><\/tr><\/thead><tbody><tr class=\"is-next\"><td class=\"dd-board__dep dd-num\">04:00<\/td><td class=\"dd-board__arr dd-num\">05:00<\/td><td class=\"dd-board__chk dd-num\">03:00<\/td><td class=\"dd-board__st\"><span class=\"dd-pill dd-pill--next\"><i><\/i>Prochain<\/span><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">06:00<\/td><td class=\"dd-board__arr dd-num\">07:00<\/td><td class=\"dd-board__chk dd-num\">05:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">08:00<\/td><td class=\"dd-board__arr dd-num\">09:00<\/td><td class=\"dd-board__chk dd-num\">07:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">10:00<\/td><td class=\"dd-board__arr dd-num\">11:00<\/td><td class=\"dd-board__chk dd-num\">09:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">12:00<\/td><td class=\"dd-board__arr dd-num\">13:00<\/td><td class=\"dd-board__chk dd-num\">11:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">14:00<\/td><td class=\"dd-board__arr dd-num\">15:00<\/td><td class=\"dd-board__chk dd-num\">13:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">16:00<\/td><td class=\"dd-board__arr dd-num\">17:00<\/td><td class=\"dd-board__chk dd-num\">15:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">18:00<\/td><td class=\"dd-board__arr dd-num\">19:00<\/td><td class=\"dd-board__chk dd-num\">17:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">20:00<\/td><td class=\"dd-board__arr dd-num\">21:00<\/td><td class=\"dd-board__chk dd-num\">19:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">23:59<\/td><td class=\"dd-board__arr dd-num\">00:59<\/td><td class=\"dd-board__chk dd-num\">22:59<\/td><td class=\"dd-board__st\"><\/td><\/tr><\/tbody><\/table><\/div><div class=\"dd-board__pane\" id=\"dd-pane-100\" role=\"tabpanel\" aria-labelledby=\"dd-tab-100\"><h3 class=\"dd-board__pane-title\">Douvres \u2192 Dunkerque<\/h3><table class=\"dd-board__table\"><thead><tr><th>D\u00e9part<\/th><th>Arriv\u00e9e<\/th><th>Enregistrement avant<\/th><th><\/th><\/tr><\/thead><tbody><tr class=\"is-next\"><td class=\"dd-board__dep dd-num\">06:00<\/td><td class=\"dd-board__arr dd-num\">09:00<\/td><td class=\"dd-board__chk dd-num\">05:00<\/td><td class=\"dd-board__st\"><span class=\"dd-pill dd-pill--next\"><i><\/i>Prochain<\/span><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">08:00<\/td><td class=\"dd-board__arr dd-num\">11:00<\/td><td class=\"dd-board__chk dd-num\">07:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">10:00<\/td><td class=\"dd-board__arr dd-num\">13:00<\/td><td class=\"dd-board__chk dd-num\">09:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">12:00<\/td><td class=\"dd-board__arr dd-num\">15:00<\/td><td class=\"dd-board__chk dd-num\">11:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">14:00<\/td><td class=\"dd-board__arr dd-num\">17:00<\/td><td class=\"dd-board__chk dd-num\">13:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">16:00<\/td><td class=\"dd-board__arr dd-num\">19:00<\/td><td class=\"dd-board__chk dd-num\">15:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">18:00<\/td><td class=\"dd-board__arr dd-num\">21:00<\/td><td class=\"dd-board__chk dd-num\">17:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">20:00<\/td><td class=\"dd-board__arr dd-num\">23:00<\/td><td class=\"dd-board__chk dd-num\">19:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><tr><td class=\"dd-board__dep dd-num\">22:00<\/td><td class=\"dd-board__arr dd-num\">01:00<\/td><td class=\"dd-board__chk dd-num\">21:00<\/td><td class=\"dd-board__st\"><\/td><\/tr><\/tbody><\/table><\/div><div class=\"dd-board__foot\"><span>D\u00e9part \u00e0 l&#039;heure locale du port de d\u00e9part, arriv\u00e9e \u00e0 l&#039;heure locale du port d&#039;arriv\u00e9e.<\/span><\/div><\/section>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"semaine\">\n\t\t\t\t<h2>Horaires de la semaine : Dunkerque vers Douvres<\/h2>\n\t\t\t\t<p>Par jour, le nombre de d\u00e9parts et les heures en heure fran\u00e7aise. En semaine il y a g\u00e9n\u00e9ralement dix d\u00e9parts, moins le week-end ; le d\u00e9part de nuit de 23h59 n&rsquo;est pas assur\u00e9 tous les jours.<\/p>\n\t\t\t\t<div class=\"dd-panel dd-tw\"><table class=\"dd-table dd-week\"><thead><tr><th>Jour<\/th><th>D\u00e9parts<\/th><th>Heures de d\u00e9part, heure locale<\/th><\/tr><\/thead><tbody><tr class=\"is-today\"><th scope=\"row\">lun 5-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">23:59<\/span><\/td><\/tr><tr><th scope=\"row\">mar 6-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">23:59<\/span><\/td><\/tr><tr><th scope=\"row\">mer 7-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">23:59<\/span><\/td><\/tr><tr><th scope=\"row\">jeu 8-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">23:59<\/span><\/td><\/tr><tr><th scope=\"row\">ven 9-10<\/th><td><span class=\"dd-week__n dd-num\">9<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><\/td><\/tr><tr><th scope=\"row\">sam 10-10<\/th><td><span class=\"dd-week__n dd-num\">8<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">04:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><\/td><\/tr><tr><th scope=\"row\">dim 11-10<\/th><td><span class=\"dd-week__n dd-num\">7<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><\/td><\/tr><\/tbody><\/table><\/div>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"semaine-retour\">\n\t\t\t\t<h2>Horaires de la semaine : Douvres vers Dunkerque<\/h2>\n\t\t\t\t<p>Heures de d\u00e9part en heure anglaise. Ajoutez une heure pour l&rsquo;heure d&rsquo;arriv\u00e9e \u00e0 Dunkerque.<\/p>\n\t\t\t\t<div class=\"dd-panel dd-tw\"><table class=\"dd-table dd-week\"><thead><tr><th>Jour<\/th><th>D\u00e9parts<\/th><th>Heures de d\u00e9part, heure locale<\/th><\/tr><\/thead><tbody><tr class=\"is-today\"><th scope=\"row\">lun 5-10<\/th><td><span class=\"dd-week__n dd-num\">9<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">mar 6-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">02:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">mer 7-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">02:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">jeu 8-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">02:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">ven 9-10<\/th><td><span class=\"dd-week__n dd-num\">10<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">02:00<\/span><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">sam 10-10<\/th><td><span class=\"dd-week__n dd-num\">8<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">06:00<\/span><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">10:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><tr><th scope=\"row\">dim 11-10<\/th><td><span class=\"dd-week__n dd-num\">7<\/span><\/td><td class=\"dd-week__times\"><span class=\"dd-week__t dd-num\">08:00<\/span><span class=\"dd-week__t dd-num\">12:00<\/span><span class=\"dd-week__t dd-num\">14:00<\/span><span class=\"dd-week__t dd-num\">16:00<\/span><span class=\"dd-week__t dd-num\">18:00<\/span><span class=\"dd-week__t dd-num\">20:00<\/span><span class=\"dd-week__t dd-num\">22:00<\/span><\/td><\/tr><\/tbody><\/table><\/div>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"date\">\n\t\t\t\t<h2>Choisir une autre date<\/h2>\n\t\t\t\t<p>Choisissez une date et le nombre de jours ; les horaires viennent directement de la grille DFDS. Pour le tarif ce jour-l\u00e0, voir <a href=\"https:\/\/dover-dunkirk.com\/fr\/reserver-dunkerque-douvres\/\">tarifs et r\u00e9servation<\/a>.<\/p>\n\t\t\t\t<h3>Dunkerque vers Douvres<\/h3>\n\t\t\t\t<div class=\"tp-wrap tp-theme-extended_cards tp-day-setup-modern\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/wp-json\\\/timetables-pro\\\/v1\\\/timetables&quot;,&quot;routes&quot;:[99],&quot;days&quot;:1,&quot;autoload&quot;:true,&quot;theme&quot;:&quot;extended_cards&quot;,&quot;daySetup&quot;:&quot;modern&quot;,&quot;limit10&quot;:false,&quot;routeLabels&quot;:{&quot;99&quot;:&quot;Dunkerque-Douvres&quot;},&quot;opFilter&quot;:[&quot;6&quot;],&quot;labels&quot;:{&quot;ui_date&quot;:&quot;Date&quot;,&quot;ui_days&quot;:&quot;Jours&quot;,&quot;ui_button&quot;:&quot;Afficher les travers\\u00e9es&quot;,&quot;status_idle&quot;:&quot;Choisissez une date et cliquez sur Afficher les travers\\u00e9es&quot;,&quot;status_loading&quot;:&quot;Chargement...&quot;,&quot;status_empty&quot;:&quot;Aucune travers\\u00e9e trouv\\u00e9e&quot;,&quot;status_found&quot;:&quot;%d travers\\u00e9es trouv\\u00e9es&quot;,&quot;th_date&quot;:&quot;Date&quot;,&quot;th_dep&quot;:&quot;D\\u00e9part&quot;,&quot;th_arr&quot;:&quot;Arriv\\u00e9e&quot;,&quot;th_dur&quot;:&quot;Dur\\u00e9e&quot;,&quot;th_ship&quot;:&quot;Navire&quot;,&quot;th_op&quot;:&quot;Op\\u00e9rateur&quot;,&quot;th_route&quot;:&quot;Route&quot;,&quot;wd_sun&quot;:&quot;DIM&quot;,&quot;wd_mon&quot;:&quot;LUN&quot;,&quot;wd_tue&quot;:&quot;MAR&quot;,&quot;wd_wed&quot;:&quot;MER&quot;,&quot;wd_thu&quot;:&quot;JEU&quot;,&quot;wd_fri&quot;:&quot;VEN&quot;,&quot;wd_sat&quot;:&quot;SAM&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Voir tous les d\\u00e9parts %s dans notre horaire&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Voir plus de d\\u00e9parts %1$s et %2$s dans notre horaire&quot;,&quot;summary_footer_generic&quot;:&quot;Consultez notre horaire pour plus de travers\\u00e9es&quot;,&quot;summary_header&quot;:&quot;Les deux prochains d\\u00e9parts :&quot;,&quot;summary_no_upcoming&quot;:&quot;Aucun prochain d\\u00e9part trouv\\u00e9&quot;,&quot;more_link&quot;:&quot;Plus de travers\\u00e9es&quot;,&quot;more_departures_button&quot;:&quot;Afficher plus de d\\u00e9parts&quot;,&quot;day_nav_previous&quot;:&quot;Afficher le jour pr\\u00e9c\\u00e9dent&quot;,&quot;day_nav_next&quot;:&quot;Afficher le jour suivant&quot;,&quot;day_nav_today&quot;:&quot;Afficher aujourd\\u2019hui&quot;,&quot;day_nav_tomorrow&quot;:&quot;Afficher demain&quot;,&quot;local_time_pair&quot;:&quot;Heure locale du port de d\\u00e9part : %1$s \\\/ Heure locale du port d&#039;arriv\\u00e9e : %2$s&quot;,&quot;local_time_combined&quot;:&quot;Heure locale des ports de d\\u00e9part et d&#039;arriv\\u00e9e : %s&quot;,&quot;tag_often_booked&quot;:&quot;\\u2b50 Souvent r\\u00e9serv\\u00e9&quot;,&quot;tag_leaving_soon&quot;:&quot;\\ud83d\\udd34 D\\u00e9part imminent&quot;,&quot;tag_currently_sailing&quot;:&quot;\\ud83d\\udfe2 En navigation&quot;,&quot;tag_arrived&quot;:&quot;\\u26ab Arriv\\u00e9&quot;,&quot;tag_overnight&quot;:&quot;Nuit \\u00e0 bord&quot;},&quot;showLogo&quot;:true,&quot;activityBoosters&quot;:true,&quot;title&quot;:&quot;&quot;,&quot;shipMap&quot;:[],&quot;shipLinks&quot;:[],&quot;showShip&quot;:false,&quot;departurePort&quot;:&quot;Dunkirk&quot;,&quot;arrivalPort&quot;:&quot;Dover&quot;,&quot;departureTimezone&quot;:&quot;Europe\\\/Paris&quot;,&quot;arrivalTimezone&quot;:&quot;Europe\\\/London&quot;}\">\n  <div class=\"tp-controls\" role=\"group\" aria-label=\"Timetable controls\">\n    <div>\n      <label for=\"tp-date-ops\">Date<\/label><br>\n      <input id=\"tp-date-ops\" class=\"tp-date\" type=\"date\" aria-label=\"Date\">\n    <\/div>\n    <div class=\"tp-day-field\">\n      <label for=\"tp-range-ops\">Jours<\/label><br>\n      <select id=\"tp-range-ops\" class=\"tp-range\" aria-label=\"Jours\">\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-ops\" class=\"tp-btn\">Afficher les travers\u00e9es<\/button><\/div>\n  <\/div>\n\n  <div class=\"tp-local-nav-row\">\n    <div class=\"tp-local-times\" id=\"tp-local-times-ops\" aria-live=\"polite\"><\/div>\n    <div class=\"tp-day-nav-host\"><\/div>\n  <\/div>\n\n  \n  <div id=\"tp-status-ops\" class=\"tp-muted\" aria-live=\"polite\">Choisissez une date et cliquez sur Afficher les travers\u00e9es<\/div>\n\n  <div id=\"tp-ops-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\">Chargement...<\/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-ops');\n  const daysEl = wrap.querySelector('#tp-range-ops');\n  const btn    = wrap.querySelector('#tp-load-ops');\n  const status = wrap.querySelector('#tp-status-ops');\n  const out    = wrap.querySelector('#tp-ops-results');\n  const loader = wrap.querySelector('.tp-loader');\n  const navHost = wrap.querySelector('.tp-day-nav-host');\n  const localTimesEl = wrap.querySelector('#tp-local-times-ops');\n\n  const showShip = (cfg.showShip !== false && cfg.showShip !== 0 && cfg.showShip !== '0');\n  const activityBoosters = !!cfg.activityBoosters;\n  const daySetup = (cfg.daySetup === 'modern') ? 'modern' : 'classic';\n  const limit10 = !!cfg.limit10;\n  let featuredKey = '';\n  let soonKey = '';\n  let revealAll = false;\n\n  if (daySetup === 'modern') {\n    const dayField = wrap.querySelector('.tp-day-field');\n    if (dayField) dayField.style.display = 'none';\n  }\n\n  dateEl.valueAsDate = new Date();\n  dateEl.min = new Date().toISOString().split('T')[0];\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'}); }\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 formatZoneTime(tz){\n    if (!tz) return '--:--';\n    try {\n      return new Intl.DateTimeFormat([], {hour:'2-digit', minute:'2-digit', hour12:false, timeZone: tz}).format(new Date());\n    } catch (e) {\n      return '--:--';\n    }\n  }\n\n  function renderLocalTimes(){\n    if (!localTimesEl) return;\n    if (!cfg.departureTimezone || !cfg.arrivalTimezone) {\n      localTimesEl.textContent = '';\n      return;\n    }\n    const depTime = formatZoneTime(cfg.departureTimezone);\n    const arrTime = formatZoneTime(cfg.arrivalTimezone);\n    const pairTpl = L.local_time_pair || 'Departure Port Local Time: %1$s \/ Arrival Port Local Time: %2$s';\n    const combinedTpl = L.local_time_combined || 'Departure & Arrival Port Local Time: %s';\n    if (depTime === arrTime) {\n      localTimesEl.textContent = combinedTpl.replace('%s', depTime);\n      return;\n    }\n    localTimesEl.textContent = pairTpl.replace('%1$s', depTime).replace('%2$s', arrTime);\n  }\n\n  function setStatusInline(html){\n    let box = wrap.querySelector('.tp-controls-status');\n    if (!box) {\n      box = document.createElement('div');\n      box.className = 'tp-controls-status';\n      wrap.querySelector('.tp-controls').appendChild(box);\n    }\n    box.innerHTML = html || '';\n  }\n\n  function clearStatusInline(){\n    const box = wrap.querySelector('.tp-controls-status');\n    if (box) box.innerHTML = '';\n  }\n\n  function navHtml(){\n    if (daySetup !== 'modern') return '';\n    const base = new Date(dateEl.value || new Date());\n    const today = new Date();\n    const tomorrow = new Date(today);\n    tomorrow.setDate(today.getDate() + 1);\n    const isToday = base.toDateString() === today.toDateString();\nlet prevLabel = L.day_nav_previous || 'Show previous day';\nlet nextLabel = L.day_nav_next || 'Show next day';\nif (isToday) nextLabel = L.day_nav_tomorrow || 'Show tomorrow';\nif (base.toDateString() === tomorrow.toDateString()) prevLabel = L.day_nav_today || 'Show today';\n    return '<div class=\"tp-day-nav\">'\n      + (isToday ? '' : '<a href=\"#\" data-shift=\"-1\">'+prevLabel+'<\/a>')\n      + '<a href=\"#\" data-shift=\"1\">'+nextLabel+'<\/a>'\n      + '<\/div>';\n  }\n\n  function shiftDate(delta){\n    const base = new Date(dateEl.value || new Date());\n    base.setDate(base.getDate() + delta);\n    dateEl.value = iso(base);\n    load();\n  }\n\n  function moreButtonHtml(hiddenCount){\n    if (!limit10 || revealAll || hiddenCount <= 0) return '';\n    return '<div style=\"margin-top:12px;text-align:center\">'\n      + '<button type=\"button\" class=\"tp-btn tp-more-btn\">'+(L.more_departures_button || 'Show more departures')+' ('+hiddenCount+')<\/button>'\n      + '<\/div>';\n  }\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 rowKey(r){\n    return [String(r.routeId||''), String(r.opId||''), String(+r.dep||0), String(+r.arr||0)].join('|');\n  }\n\n  function pickFeaturedKey(rows, avoidKey){\n    if (!activityBoosters || !rows.length) return '';\n    const routesSum = Array.isArray(cfg.routes) ? cfg.routes.reduce((acc, n)=>acc + (parseInt(n,10)||0), 0) : 0;\n    const dateSeed = parseInt(String(dateEl.value || '').replace(\/-\/g,''), 10) || 0;\n\n    let pool = rows;\n    if (avoidKey) {\n      const soonIdx = rows.findIndex(r => rowKey(r) === avoidKey);\n      if (soonIdx >= 0) {\n        const later = rows.slice(soonIdx + 1).filter(r => rowKey(r) !== avoidKey);\n        pool = later.length ? later : rows.filter(r => rowKey(r) !== avoidKey);\n      } else {\n        pool = rows.filter(r => rowKey(r) !== avoidKey);\n      }\n    }\n\n    if (!pool.length) return '';\n    const idx = Math.abs((routesSum + dateSeed + rows.length) % pool.length);\n    return rowKey(pool[idx]);\n  }\n\n  function pickSoonKey(rows){\n    if (!activityBoosters || !rows.length) return '';\n    const now = Date.now();\n    const todayStr = new Date(now).toDateString();\n    const firstUpcoming = rows.find(r => (r.dep instanceof Date) && r.dep.getTime() > now && r.dep.toDateString() === todayStr);\n    return firstUpcoming ? rowKey(firstUpcoming) : '';\n  }\n\n  function boostersFor(r){\n    if (!activityBoosters) return [];\n    const now = Date.now();\n    const depMs = (r.dep instanceof Date) ? r.dep.getTime() : 0;\n    const arrMs = (r.arr instanceof Date) ? r.arr.getTime() : 0;\n    const depIsToday = (r.dep instanceof Date) && (new Date(now).toDateString() === r.dep.toDateString());\n\n    if (depMs > 0 && arrMs > 0 && depMs <= now && arrMs > now) {\n      return [{cls:'tp-booster-sailing', text:(L.tag_currently_sailing || '\ud83d\udfe2 Currently sailing')}];\n    }\n    if (depIsToday && arrMs > 0 && arrMs <= now) {\n      return [{cls:'tp-booster-arrived', text:(L.tag_arrived || '\u26ab Arrived')}];\n    }\n    if (rowKey(r) === soonKey) return [{cls:'tp-booster-soon', text:(L.tag_leaving_soon || '\ud83d\udd34 Leaving soon')}];\n    if (r.dep && r.arr && r.dep.toDateString() !== r.arr.toDateString()) return [{cls:'tp-booster-overnight', text:(L.tag_overnight || 'Overnight')}];\n\n    return [];\n  }\n\n  function boostersHtml(r, floating){\n    const tags = boostersFor(r);\n    if (!tags.length) return '';\n    const cls = floating ? 'tp-boosters tp-boosters-float' : 'tp-boosters';\n    return '<div class=\"'+cls+'\">' + tags.map(t => '<span class=\"tp-booster '+t.cls+'\">'+boosterLabelHtml(t.text)+'<\/span>').join('') + '<\/div>';\n  }\n\n  function boosterLabelHtml(text){\n    return String(text || '').replace(\/^(\ud83d\udd34|\ud83d\udfe2|\u26ab|\u2b50)\\s*\/, '<span class=\"tp-booster-emoji\">$1<\/span>');\n  }\n\n  function routeTicketHtml(label){\n    const raw = String(label || '').trim();\n    if (!raw) return '';\n    if (cfg.theme !== 'small_cards') return escAttr(raw);\n    const parts = raw.split(\/\\s*[\\-\u2013]\\s*\/, 2);\n    if (parts.length < 2) return escAttr(raw);\n    return escAttr(parts[0]) + '<br>' + escAttr(parts[1]);\n  }\n\n  function escAttr(v){\n    return String(v||'').replace(\/[&<>\"']\/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[m]));\n  }\n\n  function bindRowLinks(){\n    if (cfg.theme !== 'max_clickouts') return;\n    out.querySelectorAll('tr.tp-row-link').forEach((row)=>{\n      row.setAttribute('role','link');\n      row.setAttribute('tabindex','0');\n      row.addEventListener('click', (e)=>{\n        if (e.target && e.target.closest('a')) return;\n        const href = row.getAttribute('data-row-link');\n        if (!href) return;\n        window.open(href, '_blank', 'noopener,noreferrer');\n      });\n      row.addEventListener('keydown', (e)=>{\n        if (e.key !== 'Enter' && e.key !== ' ') return;\n        e.preventDefault();\n        row.click();\n      });\n    });\n  }\n\n  function routeLabel(rid){\n    return (cfg.routeLabels && (cfg.routeLabels[String(rid)] || cfg.routeLabels[rid])) || String(rid);\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,route:L.th_route,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.route+'<\/th>');\n    headCells.push('<th>'+th.op+'<\/th>');\n\n    let html = '<table class=\"tp-table\"><thead><tr>'+headCells.join('')+'<\/tr><\/thead><tbody>';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const clickable = (cfg.theme === 'max_clickouts' && r.opLink);\n      const rowAttr = clickable ? (' class=\"tp-row-link\" data-row-link=\"'+escAttr(r.opLink)+'\"') : '';\n      const dateBoosters = (cfg.theme === 'max_clickouts') ? '' : boostersHtml(r, false);\n      const routeBoosters = (cfg.theme === 'max_clickouts') ? boostersHtml(r, false) : '';\n      const cells = [\n        '<td>'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span>'+dateBoosters+'<\/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>'+routeBoosters+'<div>'+routeLabel(r.routeId)+'<\/div><\/td>');\n      cells.push('<td>'+opCell(r)+'<\/td>');\n      html += '<tr'+rowAttr+'>'+cells.join('')+'<\/tr>';\n    });\n    html += '<\/tbody><\/table>';\n    return html;\n  }\n\n  function renderCards(rows){\n    if (cfg.theme === 'extended_cards') {\n      return renderExtendedCards(rows);\n    }\n\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\">'+boostersHtml(r, true)+\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) {\n        html +=\n        \/\/ Row 2: Ship\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+shipBadge(r.ship)+'<\/div>'+\n          '<div class=\"rhs\"><\/div>'+\n        '<\/div>';\n      }\n\n      html +=\n        \/\/ Row 3: Operator + route label\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+opCell(r)+'<\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-route-ticket\">'+routeTicketHtml(routeLabel(r.routeId))+'<\/span><\/div>'+\n        '<\/div>'+\n      '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  function renderExtendedCards(rows){\n    const ctaText = L.more_link || 'More sailings';\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const link = r.opLink ? ('<a class=\"tp-ext-cta\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/a>') : '<span class=\"tp-ext-cta\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/span>';\n      html += '<div class=\"tp-ext-card\">'\n        + boostersHtml(r, true)\n        + '<div class=\"tp-ext-left\">'\n        +   '<div>'+opCell(r)+'<\/div>'\n        +   (showShip ? ('<div>'+shipBadge(r.ship)+'<\/div>') : '')\n        + '<\/div>'\n        + '<div class=\"tp-ext-mid\">'\n        +   '<div class=\"tp-ext-top\"><span class=\"tp-sub\">'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-times\"><span class=\"tp-ext-time\">'+hhmm(r.dep)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-time\">'+hhmm(r.arr)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-route\">'+routeLabel(r.routeId)+'<\/div>'\n        + '<\/div>'\n        + '<div class=\"tp-ext-right\">'+link+'<\/div>'\n        + '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  \/\/ Safe fetch helper\n  async function fetchOne(routeId, from, to){\n    try{\n      const url = new URL(cfg.rest);\n      url.searchParams.set('route', String(routeId));\n      url.searchParams.set('from', from);\n      url.searchParams.set('to', to);\n      const res = await fetch(url.toString(), {credentials:'same-origin'});\n      if(!res.ok) return { rid: routeId, 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      return { rid: routeId, rows: list };\n    }catch(e){\n      return { rid: routeId, error: String(e && e.message ? e.message : e) };\n    }\n  }\n\n  async function load(){\n    btn.disabled = true; setLoader(true); status.textContent = L.status_loading;\n\n    const start = new Date(dateEl.value || new Date());\n    const days  = (daySetup === 'modern') ? 1 : Math.max(1, parseInt(daysEl.value,10)||1);\n    const end   = new Date(start); end.setDate(start.getDate()+days-1);\n    const fromIso = iso(start), toIso = iso(end);\n\n    try{\n      const results  = await Promise.all((cfg.routes||[]).map(rid=>fetchOne(rid, fromIso, toIso)));\n      const oks  = results.filter(r => !r.error);\n      const errs = results.filter(r =>  r.error);\n\n      const all = [];\n      oks.forEach(({rid, rows})=>{\n        rows.forEach(t=>{\n          all.push({\n            routeId: rid,\n            opId: t.operatorId || null,\n            opName: t.operatorName || '',\n            opLogo: t.operatorLogo || '',\n            opLink: t.operatorLink || '',\n            dep: toLocal(t.departureTime),\n            arr: toLocal(t.arrivalTime),\n            min: t.durationInMinutes || 0,\n            ship: t.shipName || ''\n          });\n        });\n      });\n\n      let rows = all;\n      if (Array.isArray(cfg.opFilter) && cfg.opFilter.length>0) {\n        rows = all.filter(r => r.opId && cfg.opFilter.includes(String(r.opId)));\n      }\n\n      rows.sort((a,b)=> a.dep - b.dep);\n\n      const todayStr = new Date().toDateString();\n      const nowMs = Date.now();\n      const arrivedToday = rows\n        .filter(r => (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs)\n        .sort((a,b) => b.arr - a.arr);\n      if (arrivedToday.length > 2) {\n        const keep = new Set(arrivedToday.slice(0,2).map(rowKey));\n        rows = rows.filter(r => {\n          const isArrivedToday = (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs;\n          return !isArrivedToday || keep.has(rowKey(r));\n        });\n      }\n\n      const total = rows.length;\n      if (total===0){\n        status.textContent = L.status_empty + (errs.length ? ' (some routes returned no data or errors)' : '');\n        clearStatusInline();\n        out.innerHTML='';\n        setLoader(false); btn.disabled=false; return;\n      }\n\n      const visibleRows = (limit10 && !revealAll && rows.length > 10) ? rows.slice(0,10) : rows;\n      const hiddenCount = rows.length - visibleRows.length;\n      soonKey = pickSoonKey(visibleRows);\n      featuredKey = pickFeaturedKey(visibleRows, soonKey);\n\n      status.textContent = errs.length ? ('Skipped '+errs.length+' route'+(errs.length>1?'s':'')) : '';\n      setStatusInline(\n  (L.status_found || '%d sailings found').replace('%d', '<strong>'+total+'<\/strong>')\n);\n      out.innerHTML = renderTable(visibleRows) + renderCards(visibleRows) + moreButtonHtml(hiddenCount);\n      bindRowLinks();\n      if (navHost) navHost.innerHTML = navHtml();\n\n    } catch(e){\n      status.textContent = 'Failed to load data';\n      out.innerHTML = '<pre>'+String(e.message||e)+'<\/pre>';\n    } finally {\n      setLoader(false);\n      btn.disabled = false;\n    }\n  }\n\n  wrap.addEventListener('click', function(e){\n    const nav = e.target.closest('.tp-day-nav a[data-shift]');\n    if (nav) {\n      e.preventDefault();\n      shiftDate(parseInt(nav.getAttribute('data-shift'),10) || 0);\n      return;\n    }\n    const more = e.target.closest('.tp-more-btn');\n    if (more) {\n      e.preventDefault();\n      revealAll = true;\n      load();\n    }\n  });\n\n  btn.addEventListener('click', load);\n  if (navHost) navHost.innerHTML = navHtml();\n  renderLocalTimes();\n  setInterval(renderLocalTimes, 30000);\n  if (cfg.autoload) load();\n})();\n<\/script>\n\n\t\t\t\t<h3>Douvres vers Dunkerque<\/h3>\n\t\t\t\t<div class=\"tp-wrap tp-theme-extended_cards tp-day-setup-modern\" data-config=\"{&quot;rest&quot;:&quot;https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/wp-json\\\/timetables-pro\\\/v1\\\/timetables&quot;,&quot;routes&quot;:[100],&quot;days&quot;:1,&quot;autoload&quot;:true,&quot;theme&quot;:&quot;extended_cards&quot;,&quot;daySetup&quot;:&quot;modern&quot;,&quot;limit10&quot;:false,&quot;routeLabels&quot;:{&quot;100&quot;:&quot;Douvres-Dunkerque&quot;},&quot;opFilter&quot;:[&quot;6&quot;],&quot;labels&quot;:{&quot;ui_date&quot;:&quot;Date&quot;,&quot;ui_days&quot;:&quot;Jours&quot;,&quot;ui_button&quot;:&quot;Afficher les travers\\u00e9es&quot;,&quot;status_idle&quot;:&quot;Choisissez une date et cliquez sur Afficher les travers\\u00e9es&quot;,&quot;status_loading&quot;:&quot;Chargement...&quot;,&quot;status_empty&quot;:&quot;Aucune travers\\u00e9e trouv\\u00e9e&quot;,&quot;status_found&quot;:&quot;%d travers\\u00e9es trouv\\u00e9es&quot;,&quot;th_date&quot;:&quot;Date&quot;,&quot;th_dep&quot;:&quot;D\\u00e9part&quot;,&quot;th_arr&quot;:&quot;Arriv\\u00e9e&quot;,&quot;th_dur&quot;:&quot;Dur\\u00e9e&quot;,&quot;th_ship&quot;:&quot;Navire&quot;,&quot;th_op&quot;:&quot;Op\\u00e9rateur&quot;,&quot;th_route&quot;:&quot;Route&quot;,&quot;wd_sun&quot;:&quot;DIM&quot;,&quot;wd_mon&quot;:&quot;LUN&quot;,&quot;wd_tue&quot;:&quot;MAR&quot;,&quot;wd_wed&quot;:&quot;MER&quot;,&quot;wd_thu&quot;:&quot;JEU&quot;,&quot;wd_fri&quot;:&quot;VEN&quot;,&quot;wd_sat&quot;:&quot;SAM&quot;,&quot;summary_footer_one&quot;:&quot;\\u00bb Voir tous les d\\u00e9parts %s dans notre horaire&quot;,&quot;summary_footer_two&quot;:&quot;\\u00bb Voir plus de d\\u00e9parts %1$s et %2$s dans notre horaire&quot;,&quot;summary_footer_generic&quot;:&quot;Consultez notre horaire pour plus de travers\\u00e9es&quot;,&quot;summary_header&quot;:&quot;Les deux prochains d\\u00e9parts :&quot;,&quot;summary_no_upcoming&quot;:&quot;Aucun prochain d\\u00e9part trouv\\u00e9&quot;,&quot;more_link&quot;:&quot;Plus de travers\\u00e9es&quot;,&quot;more_departures_button&quot;:&quot;Afficher plus de d\\u00e9parts&quot;,&quot;day_nav_previous&quot;:&quot;Afficher le jour pr\\u00e9c\\u00e9dent&quot;,&quot;day_nav_next&quot;:&quot;Afficher le jour suivant&quot;,&quot;day_nav_today&quot;:&quot;Afficher aujourd\\u2019hui&quot;,&quot;day_nav_tomorrow&quot;:&quot;Afficher demain&quot;,&quot;local_time_pair&quot;:&quot;Heure locale du port de d\\u00e9part : %1$s \\\/ Heure locale du port d&#039;arriv\\u00e9e : %2$s&quot;,&quot;local_time_combined&quot;:&quot;Heure locale des ports de d\\u00e9part et d&#039;arriv\\u00e9e : %s&quot;,&quot;tag_often_booked&quot;:&quot;\\u2b50 Souvent r\\u00e9serv\\u00e9&quot;,&quot;tag_leaving_soon&quot;:&quot;\\ud83d\\udd34 D\\u00e9part imminent&quot;,&quot;tag_currently_sailing&quot;:&quot;\\ud83d\\udfe2 En navigation&quot;,&quot;tag_arrived&quot;:&quot;\\u26ab Arriv\\u00e9&quot;,&quot;tag_overnight&quot;:&quot;Nuit \\u00e0 bord&quot;},&quot;showLogo&quot;:true,&quot;activityBoosters&quot;:true,&quot;title&quot;:&quot;&quot;,&quot;shipMap&quot;:[],&quot;shipLinks&quot;:[],&quot;showShip&quot;:false,&quot;departurePort&quot;:&quot;Dover&quot;,&quot;arrivalPort&quot;:&quot;Dunkirk&quot;,&quot;departureTimezone&quot;:&quot;Europe\\\/London&quot;,&quot;arrivalTimezone&quot;:&quot;Europe\\\/Paris&quot;}\">\n  <div class=\"tp-controls\" role=\"group\" aria-label=\"Timetable controls\">\n    <div>\n      <label for=\"tp-date-ops\">Date<\/label><br>\n      <input id=\"tp-date-ops\" class=\"tp-date\" type=\"date\" aria-label=\"Date\">\n    <\/div>\n    <div class=\"tp-day-field\">\n      <label for=\"tp-range-ops\">Jours<\/label><br>\n      <select id=\"tp-range-ops\" class=\"tp-range\" aria-label=\"Jours\">\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-ops\" class=\"tp-btn\">Afficher les travers\u00e9es<\/button><\/div>\n  <\/div>\n\n  <div class=\"tp-local-nav-row\">\n    <div class=\"tp-local-times\" id=\"tp-local-times-ops\" aria-live=\"polite\"><\/div>\n    <div class=\"tp-day-nav-host\"><\/div>\n  <\/div>\n\n  \n  <div id=\"tp-status-ops\" class=\"tp-muted\" aria-live=\"polite\">Choisissez une date et cliquez sur Afficher les travers\u00e9es<\/div>\n\n  <div id=\"tp-ops-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\">Chargement...<\/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-ops');\n  const daysEl = wrap.querySelector('#tp-range-ops');\n  const btn    = wrap.querySelector('#tp-load-ops');\n  const status = wrap.querySelector('#tp-status-ops');\n  const out    = wrap.querySelector('#tp-ops-results');\n  const loader = wrap.querySelector('.tp-loader');\n  const navHost = wrap.querySelector('.tp-day-nav-host');\n  const localTimesEl = wrap.querySelector('#tp-local-times-ops');\n\n  const showShip = (cfg.showShip !== false && cfg.showShip !== 0 && cfg.showShip !== '0');\n  const activityBoosters = !!cfg.activityBoosters;\n  const daySetup = (cfg.daySetup === 'modern') ? 'modern' : 'classic';\n  const limit10 = !!cfg.limit10;\n  let featuredKey = '';\n  let soonKey = '';\n  let revealAll = false;\n\n  if (daySetup === 'modern') {\n    const dayField = wrap.querySelector('.tp-day-field');\n    if (dayField) dayField.style.display = 'none';\n  }\n\n  dateEl.valueAsDate = new Date();\n  dateEl.min = new Date().toISOString().split('T')[0];\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'}); }\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 formatZoneTime(tz){\n    if (!tz) return '--:--';\n    try {\n      return new Intl.DateTimeFormat([], {hour:'2-digit', minute:'2-digit', hour12:false, timeZone: tz}).format(new Date());\n    } catch (e) {\n      return '--:--';\n    }\n  }\n\n  function renderLocalTimes(){\n    if (!localTimesEl) return;\n    if (!cfg.departureTimezone || !cfg.arrivalTimezone) {\n      localTimesEl.textContent = '';\n      return;\n    }\n    const depTime = formatZoneTime(cfg.departureTimezone);\n    const arrTime = formatZoneTime(cfg.arrivalTimezone);\n    const pairTpl = L.local_time_pair || 'Departure Port Local Time: %1$s \/ Arrival Port Local Time: %2$s';\n    const combinedTpl = L.local_time_combined || 'Departure & Arrival Port Local Time: %s';\n    if (depTime === arrTime) {\n      localTimesEl.textContent = combinedTpl.replace('%s', depTime);\n      return;\n    }\n    localTimesEl.textContent = pairTpl.replace('%1$s', depTime).replace('%2$s', arrTime);\n  }\n\n  function setStatusInline(html){\n    let box = wrap.querySelector('.tp-controls-status');\n    if (!box) {\n      box = document.createElement('div');\n      box.className = 'tp-controls-status';\n      wrap.querySelector('.tp-controls').appendChild(box);\n    }\n    box.innerHTML = html || '';\n  }\n\n  function clearStatusInline(){\n    const box = wrap.querySelector('.tp-controls-status');\n    if (box) box.innerHTML = '';\n  }\n\n  function navHtml(){\n    if (daySetup !== 'modern') return '';\n    const base = new Date(dateEl.value || new Date());\n    const today = new Date();\n    const tomorrow = new Date(today);\n    tomorrow.setDate(today.getDate() + 1);\n    const isToday = base.toDateString() === today.toDateString();\nlet prevLabel = L.day_nav_previous || 'Show previous day';\nlet nextLabel = L.day_nav_next || 'Show next day';\nif (isToday) nextLabel = L.day_nav_tomorrow || 'Show tomorrow';\nif (base.toDateString() === tomorrow.toDateString()) prevLabel = L.day_nav_today || 'Show today';\n    return '<div class=\"tp-day-nav\">'\n      + (isToday ? '' : '<a href=\"#\" data-shift=\"-1\">'+prevLabel+'<\/a>')\n      + '<a href=\"#\" data-shift=\"1\">'+nextLabel+'<\/a>'\n      + '<\/div>';\n  }\n\n  function shiftDate(delta){\n    const base = new Date(dateEl.value || new Date());\n    base.setDate(base.getDate() + delta);\n    dateEl.value = iso(base);\n    load();\n  }\n\n  function moreButtonHtml(hiddenCount){\n    if (!limit10 || revealAll || hiddenCount <= 0) return '';\n    return '<div style=\"margin-top:12px;text-align:center\">'\n      + '<button type=\"button\" class=\"tp-btn tp-more-btn\">'+(L.more_departures_button || 'Show more departures')+' ('+hiddenCount+')<\/button>'\n      + '<\/div>';\n  }\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 rowKey(r){\n    return [String(r.routeId||''), String(r.opId||''), String(+r.dep||0), String(+r.arr||0)].join('|');\n  }\n\n  function pickFeaturedKey(rows, avoidKey){\n    if (!activityBoosters || !rows.length) return '';\n    const routesSum = Array.isArray(cfg.routes) ? cfg.routes.reduce((acc, n)=>acc + (parseInt(n,10)||0), 0) : 0;\n    const dateSeed = parseInt(String(dateEl.value || '').replace(\/-\/g,''), 10) || 0;\n\n    let pool = rows;\n    if (avoidKey) {\n      const soonIdx = rows.findIndex(r => rowKey(r) === avoidKey);\n      if (soonIdx >= 0) {\n        const later = rows.slice(soonIdx + 1).filter(r => rowKey(r) !== avoidKey);\n        pool = later.length ? later : rows.filter(r => rowKey(r) !== avoidKey);\n      } else {\n        pool = rows.filter(r => rowKey(r) !== avoidKey);\n      }\n    }\n\n    if (!pool.length) return '';\n    const idx = Math.abs((routesSum + dateSeed + rows.length) % pool.length);\n    return rowKey(pool[idx]);\n  }\n\n  function pickSoonKey(rows){\n    if (!activityBoosters || !rows.length) return '';\n    const now = Date.now();\n    const todayStr = new Date(now).toDateString();\n    const firstUpcoming = rows.find(r => (r.dep instanceof Date) && r.dep.getTime() > now && r.dep.toDateString() === todayStr);\n    return firstUpcoming ? rowKey(firstUpcoming) : '';\n  }\n\n  function boostersFor(r){\n    if (!activityBoosters) return [];\n    const now = Date.now();\n    const depMs = (r.dep instanceof Date) ? r.dep.getTime() : 0;\n    const arrMs = (r.arr instanceof Date) ? r.arr.getTime() : 0;\n    const depIsToday = (r.dep instanceof Date) && (new Date(now).toDateString() === r.dep.toDateString());\n\n    if (depMs > 0 && arrMs > 0 && depMs <= now && arrMs > now) {\n      return [{cls:'tp-booster-sailing', text:(L.tag_currently_sailing || '\ud83d\udfe2 Currently sailing')}];\n    }\n    if (depIsToday && arrMs > 0 && arrMs <= now) {\n      return [{cls:'tp-booster-arrived', text:(L.tag_arrived || '\u26ab Arrived')}];\n    }\n    if (rowKey(r) === soonKey) return [{cls:'tp-booster-soon', text:(L.tag_leaving_soon || '\ud83d\udd34 Leaving soon')}];\n    if (r.dep && r.arr && r.dep.toDateString() !== r.arr.toDateString()) return [{cls:'tp-booster-overnight', text:(L.tag_overnight || 'Overnight')}];\n\n    return [];\n  }\n\n  function boostersHtml(r, floating){\n    const tags = boostersFor(r);\n    if (!tags.length) return '';\n    const cls = floating ? 'tp-boosters tp-boosters-float' : 'tp-boosters';\n    return '<div class=\"'+cls+'\">' + tags.map(t => '<span class=\"tp-booster '+t.cls+'\">'+boosterLabelHtml(t.text)+'<\/span>').join('') + '<\/div>';\n  }\n\n  function boosterLabelHtml(text){\n    return String(text || '').replace(\/^(\ud83d\udd34|\ud83d\udfe2|\u26ab|\u2b50)\\s*\/, '<span class=\"tp-booster-emoji\">$1<\/span>');\n  }\n\n  function routeTicketHtml(label){\n    const raw = String(label || '').trim();\n    if (!raw) return '';\n    if (cfg.theme !== 'small_cards') return escAttr(raw);\n    const parts = raw.split(\/\\s*[\\-\u2013]\\s*\/, 2);\n    if (parts.length < 2) return escAttr(raw);\n    return escAttr(parts[0]) + '<br>' + escAttr(parts[1]);\n  }\n\n  function escAttr(v){\n    return String(v||'').replace(\/[&<>\"']\/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[m]));\n  }\n\n  function bindRowLinks(){\n    if (cfg.theme !== 'max_clickouts') return;\n    out.querySelectorAll('tr.tp-row-link').forEach((row)=>{\n      row.setAttribute('role','link');\n      row.setAttribute('tabindex','0');\n      row.addEventListener('click', (e)=>{\n        if (e.target && e.target.closest('a')) return;\n        const href = row.getAttribute('data-row-link');\n        if (!href) return;\n        window.open(href, '_blank', 'noopener,noreferrer');\n      });\n      row.addEventListener('keydown', (e)=>{\n        if (e.key !== 'Enter' && e.key !== ' ') return;\n        e.preventDefault();\n        row.click();\n      });\n    });\n  }\n\n  function routeLabel(rid){\n    return (cfg.routeLabels && (cfg.routeLabels[String(rid)] || cfg.routeLabels[rid])) || String(rid);\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,route:L.th_route,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.route+'<\/th>');\n    headCells.push('<th>'+th.op+'<\/th>');\n\n    let html = '<table class=\"tp-table\"><thead><tr>'+headCells.join('')+'<\/tr><\/thead><tbody>';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const clickable = (cfg.theme === 'max_clickouts' && r.opLink);\n      const rowAttr = clickable ? (' class=\"tp-row-link\" data-row-link=\"'+escAttr(r.opLink)+'\"') : '';\n      const dateBoosters = (cfg.theme === 'max_clickouts') ? '' : boostersHtml(r, false);\n      const routeBoosters = (cfg.theme === 'max_clickouts') ? boostersHtml(r, false) : '';\n      const cells = [\n        '<td>'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span>'+dateBoosters+'<\/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>'+routeBoosters+'<div>'+routeLabel(r.routeId)+'<\/div><\/td>');\n      cells.push('<td>'+opCell(r)+'<\/td>');\n      html += '<tr'+rowAttr+'>'+cells.join('')+'<\/tr>';\n    });\n    html += '<\/tbody><\/table>';\n    return html;\n  }\n\n  function renderCards(rows){\n    if (cfg.theme === 'extended_cards') {\n      return renderExtendedCards(rows);\n    }\n\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\">'+boostersHtml(r, true)+\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) {\n        html +=\n        \/\/ Row 2: Ship\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+shipBadge(r.ship)+'<\/div>'+\n          '<div class=\"rhs\"><\/div>'+\n        '<\/div>';\n      }\n\n      html +=\n        \/\/ Row 3: Operator + route label\n        '<div class=\"tp-mrow\">'+\n          '<div class=\"lhs\">'+opCell(r)+'<\/div>'+\n          '<div class=\"rhs\"><span class=\"tp-route-ticket\">'+routeTicketHtml(routeLabel(r.routeId))+'<\/span><\/div>'+\n        '<\/div>'+\n      '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  function renderExtendedCards(rows){\n    const ctaText = L.more_link || 'More sailings';\n    let html = '<div class=\"tp-cardlist\">';\n    rows.forEach(r=>{\n      const dow = WD[r.dep.getDay()] || '';\n      const link = r.opLink ? ('<a class=\"tp-ext-cta\" href=\"'+r.opLink+'\" target=\"_blank\" rel=\"nofollow noopener\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/a>') : '<span class=\"tp-ext-cta\">'+ctaText+' <span class=\"tp-ext-cta-arrow\">\u00bb<\/span><\/span>';\n      html += '<div class=\"tp-ext-card\">'\n        + boostersHtml(r, true)\n        + '<div class=\"tp-ext-left\">'\n        +   '<div>'+opCell(r)+'<\/div>'\n        +   (showShip ? ('<div>'+shipBadge(r.ship)+'<\/div>') : '')\n        + '<\/div>'\n        + '<div class=\"tp-ext-mid\">'\n        +   '<div class=\"tp-ext-top\"><span class=\"tp-sub\">'+dShort(r.dep)+' <span class=\"tp-day\">'+dow+'<\/span><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-times\"><span class=\"tp-ext-time\">'+hhmm(r.dep)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-dur\">'+dur(r.min)+'<\/span><span class=\"tp-ext-line\"><\/span><span class=\"tp-ext-time\">'+hhmm(r.arr)+'<\/span><\/div>'\n        +   '<div class=\"tp-ext-route\">'+routeLabel(r.routeId)+'<\/div>'\n        + '<\/div>'\n        + '<div class=\"tp-ext-right\">'+link+'<\/div>'\n        + '<\/div>';\n    });\n    html += '<\/div>';\n    return html;\n  }\n\n  \/\/ Safe fetch helper\n  async function fetchOne(routeId, from, to){\n    try{\n      const url = new URL(cfg.rest);\n      url.searchParams.set('route', String(routeId));\n      url.searchParams.set('from', from);\n      url.searchParams.set('to', to);\n      const res = await fetch(url.toString(), {credentials:'same-origin'});\n      if(!res.ok) return { rid: routeId, 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      return { rid: routeId, rows: list };\n    }catch(e){\n      return { rid: routeId, error: String(e && e.message ? e.message : e) };\n    }\n  }\n\n  async function load(){\n    btn.disabled = true; setLoader(true); status.textContent = L.status_loading;\n\n    const start = new Date(dateEl.value || new Date());\n    const days  = (daySetup === 'modern') ? 1 : Math.max(1, parseInt(daysEl.value,10)||1);\n    const end   = new Date(start); end.setDate(start.getDate()+days-1);\n    const fromIso = iso(start), toIso = iso(end);\n\n    try{\n      const results  = await Promise.all((cfg.routes||[]).map(rid=>fetchOne(rid, fromIso, toIso)));\n      const oks  = results.filter(r => !r.error);\n      const errs = results.filter(r =>  r.error);\n\n      const all = [];\n      oks.forEach(({rid, rows})=>{\n        rows.forEach(t=>{\n          all.push({\n            routeId: rid,\n            opId: t.operatorId || null,\n            opName: t.operatorName || '',\n            opLogo: t.operatorLogo || '',\n            opLink: t.operatorLink || '',\n            dep: toLocal(t.departureTime),\n            arr: toLocal(t.arrivalTime),\n            min: t.durationInMinutes || 0,\n            ship: t.shipName || ''\n          });\n        });\n      });\n\n      let rows = all;\n      if (Array.isArray(cfg.opFilter) && cfg.opFilter.length>0) {\n        rows = all.filter(r => r.opId && cfg.opFilter.includes(String(r.opId)));\n      }\n\n      rows.sort((a,b)=> a.dep - b.dep);\n\n      const todayStr = new Date().toDateString();\n      const nowMs = Date.now();\n      const arrivedToday = rows\n        .filter(r => (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs)\n        .sort((a,b) => b.arr - a.arr);\n      if (arrivedToday.length > 2) {\n        const keep = new Set(arrivedToday.slice(0,2).map(rowKey));\n        rows = rows.filter(r => {\n          const isArrivedToday = (r.dep instanceof Date) && (r.arr instanceof Date) && r.dep.toDateString() === todayStr && r.arr.getTime() <= nowMs;\n          return !isArrivedToday || keep.has(rowKey(r));\n        });\n      }\n\n      const total = rows.length;\n      if (total===0){\n        status.textContent = L.status_empty + (errs.length ? ' (some routes returned no data or errors)' : '');\n        clearStatusInline();\n        out.innerHTML='';\n        setLoader(false); btn.disabled=false; return;\n      }\n\n      const visibleRows = (limit10 && !revealAll && rows.length > 10) ? rows.slice(0,10) : rows;\n      const hiddenCount = rows.length - visibleRows.length;\n      soonKey = pickSoonKey(visibleRows);\n      featuredKey = pickFeaturedKey(visibleRows, soonKey);\n\n      status.textContent = errs.length ? ('Skipped '+errs.length+' route'+(errs.length>1?'s':'')) : '';\n      setStatusInline(\n  (L.status_found || '%d sailings found').replace('%d', '<strong>'+total+'<\/strong>')\n);\n      out.innerHTML = renderTable(visibleRows) + renderCards(visibleRows) + moreButtonHtml(hiddenCount);\n      bindRowLinks();\n      if (navHost) navHost.innerHTML = navHtml();\n\n    } catch(e){\n      status.textContent = 'Failed to load data';\n      out.innerHTML = '<pre>'+String(e.message||e)+'<\/pre>';\n    } finally {\n      setLoader(false);\n      btn.disabled = false;\n    }\n  }\n\n  wrap.addEventListener('click', function(e){\n    const nav = e.target.closest('.tp-day-nav a[data-shift]');\n    if (nav) {\n      e.preventDefault();\n      shiftDate(parseInt(nav.getAttribute('data-shift'),10) || 0);\n      return;\n    }\n    const more = e.target.closest('.tp-more-btn');\n    if (more) {\n      e.preventDefault();\n      revealAll = true;\n      load();\n    }\n  });\n\n  btn.addEventListener('click', load);\n  if (navHost) navHost.innerHTML = navHtml();\n  renderLocalTimes();\n  setInterval(renderLocalTimes, 30000);\n  if (cfg.autoload) load();\n})();\n<\/script>\n\n\t\t\t<\/section>\n\n\t\t\t<section id=\"duree\">\n\t\t\t\t<h2>Combien de temps dure la travers\u00e9e Dunkerque vers Douvres ?<\/h2>\n\t\t\t\t<p>La travers\u00e9e dure deux heures dans les deux sens, quoi qu&rsquo;indique le billet. Comme l&rsquo;Angleterre a une heure de retard sur la France, votre billet vers Douvres affiche une arriv\u00e9e une heure seulement apr\u00e8s le d\u00e9part. Au retour vers Dunkerque, il affiche trois heures d&rsquo;\u00e9cart. \u00c0 bord, rien ne change : vous reculez votre montre d&rsquo;une heure \u00e0 l&rsquo;arriv\u00e9e, et l&rsquo;avancez d&rsquo;une heure au retour.<\/p>\n\t\t\t\t<div class=\"dd-panel dd-tw\"><table class=\"dd-table\">\n\t\t\t\t\t<thead><tr><th>Sens<\/th><th>D\u00e9part (heure locale)<\/th><th>Arriv\u00e9e (heure locale)<\/th><th>Dur\u00e9e r\u00e9elle<\/th><\/tr><\/thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t<tr><td>Dunkerque vers Douvres<\/td><td class=\"dd-num\">14h00 (heure fran\u00e7aise)<\/td><td class=\"dd-num\">15h00 (heure anglaise)<\/td><td class=\"dd-num\">2 h<\/td><\/tr>\n\t\t\t\t\t\t<tr><td>Douvres vers Dunkerque<\/td><td class=\"dd-num\">12h00 (heure anglaise)<\/td><td class=\"dd-num\">15h00 (heure fran\u00e7aise)<\/td><td class=\"dd-num\">2 h<\/td><\/tr>\n\t\t\t\t\t<\/tbody>\n\t\t\t\t<\/table><\/div>\n\t\t\t\t<p>Comptez 3 h 15 \u00e0 3 h 30 pour l&rsquo;ensemble : une heure au port avant le d\u00e9part, deux heures de mer, et 15 \u00e0 30 minutes pour d\u00e9barquer et sortir du port.<\/p>\n\t\t\t\t<div class=\"dd-figs\"><figure class=\"dd-figure\"><img loading=\"lazy\" src=\"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2026\/09\/wake-leaving-dunkirk.webp\" alt=\"Le sillage du ferry \u00e0 la sortie du port de Dunkerque\" width=\"1800\" height=\"1350\" loading=\"lazy\" decoding=\"async\"><figcaption>D\u00e9part de Dunkerque : en un quart d&rsquo;heure, le port est derri\u00e8re vous.<\/figcaption><\/figure><figure class=\"dd-figure\"><img loading=\"lazy\" src=\"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2026\/09\/entering-dover-harbour.webp\" alt=\"Le ferry passe entre les jet\u00e9es de Douvres\" width=\"1800\" height=\"1350\" loading=\"lazy\" decoding=\"async\"><figcaption>Deux heures plus tard : entre les jet\u00e9es de Douvres.<\/figcaption><\/figure><\/div>\t\t\t<\/section>\n\n\t\t\t<section id=\"enregistrement\">\n\t\t\t\t<h2>Quand ferme l&rsquo;enregistrement ?<\/h2>\n\t\t\t\t<p>L&rsquo;enregistrement ferme 60 minutes avant le d\u00e9part. \u00c0 Dunkerque, pr\u00e9voyez 75 \u00e0 90 minutes avant le d\u00e9part, et 90 \u00e0 120 minutes pendant les vacances scolaires et le vendredi et le samedi. \u00c0 Douvres, le contr\u00f4le des passeports fran\u00e7ais a lieu avant l&#8217;embarquement ; comptez 60 \u00e0 90 minutes hors vacances et 90 \u00e0 120 minutes pendant les vacances scolaires. Ce qui se passe si vous manquez votre d\u00e9part d\u00e9pend de votre type de billet ; consultez les conditions de votre r\u00e9servation.<\/p>\n\t\t\t\t<p>Le d\u00e9roul\u00e9 complet, du guichet \u00e0 la rampe, avec photos : <a href=\"https:\/\/dover-dunkirk.com\/fr\/enregistrement\/\">l&rsquo;enregistrement pas \u00e0 pas<\/a>. Adresse et acc\u00e8s du terminal : <a href=\"https:\/\/dover-dunkirk.com\/fr\/port-de-dunkerque\/\">port de Dunkerque<\/a>.<\/p>\n\t\t\t\t<div class=\"dd-tip\"><svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\"\/><path d=\"M12 11v5M12 8h.01\"\/><\/svg><span>Les animaux restent dans la voiture pendant la travers\u00e9e (voir <a href=\"https:\/\/dover-dunkirk.com\/fr\/a-bord\/\">\u00e0 bord et animaux<\/a>). Promenez votre chien avant l&rsquo;enregistrement ; une aire est am\u00e9nag\u00e9e \u00e0 c\u00f4t\u00e9 du b\u00e2timent du terminal.<\/span><\/div>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"nuit\">\n\t\t\t\t<h2>D\u00e9parts de nuit et week-end<\/h2>\n\t\t\t\t<p>Le d\u00e9part de 23h59 de Dunkerque et celui de 04h00 ne sont pas assur\u00e9s tous les jours ; le week-end, quelques d\u00e9parts sont supprim\u00e9s. Le tableau ci-dessus montre jour par jour ce qui part. Ne r\u00e9servez un d\u00e9part de nuit que s&rsquo;il figure dans la grille horaire, et sachez que le terminal a des services limit\u00e9s la nuit. Pour un d\u00e9part de nuit tous les jours, Calais a plus de rotations : voir <a href=\"https:\/\/dover-dunkirk.com\/fr\/calais-ou-dunkerque\/\">Calais ou Dunkerque<\/a>.<\/p>\n\t\t\t\t<div class=\"dd-tip\"><svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\"\/><path d=\"M12 11v5M12 8h.01\"\/><\/svg><span><strong>Notre conseil.<\/strong> Pour le d\u00e9part de 04h00, l&rsquo;enregistrement ferme \u00e0 03h00 et le terminal n&rsquo;offre la nuit qu&rsquo;un petit kiosque. Si vous venez de plus loin que Lille, dormir \u00e0 Dunkerque ou \u00e0 Loon-Plage la veille \u00e9vite de rouler de nuit : les guichets sont \u00e0 5 \u00e0 20 minutes. <a href=\"https:\/\/dover-dunkirk.com\/fr\/go\/stay22-dunkirk\/\" rel=\"sponsored nofollow noopener\" target=\"_blank\">Voir les h\u00f4tels pr\u00e8s du terminal de Loon-Plage<\/a><\/span><\/div>\n\t\t\t<\/section>\n\n\t\t\t<section id=\"questions\">\n\t\t\t\t<h2>Questions fr\u00e9quentes sur les horaires<\/h2>\n\t\t\t\t<div class=\"dd-faq\">\n\t\t\t\t\t<details open><summary>\u00c0 quelle fr\u00e9quence part le ferry de Dunkerque vers Douvres ? <svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"\/><\/svg><\/summary><p>Jusqu&rsquo;\u00e0 onze fois par jour en haute saison ; en semaine, g\u00e9n\u00e9ralement dix : \u00e0 04h00, 06h00, 08h00, 10h00, 12h00, 14h00, 16h00, 18h00, 20h00 et 23h59. Le week-end, quelques d\u00e9parts sont supprim\u00e9s.<\/p><\/details>\n\t\t\t\t\t<details open><summary>Les horaires sont-ils en heure fran\u00e7aise ? <svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"\/><\/svg><\/summary><p>Les d\u00e9parts de Dunkerque sont en heure fran\u00e7aise. Les d\u00e9parts de Douvres sont en heure anglaise, une heure plus t\u00f4t. Les arriv\u00e9es sont toujours en heure locale du port d&rsquo;arriv\u00e9e.<\/p><\/details>\n\t\t\t\t\t<details open><summary>Quels sont le premier et le dernier d\u00e9part ? <svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"\/><\/svg><\/summary><p>Le premier d\u00e9part de Dunkerque est \u00e0 04h00, le dernier \u00e0 23h59 les jours o\u00f9 il est assur\u00e9. De Douvres, le premier part \u00e0 02h00 et le dernier \u00e0 22h00, heure anglaise.<\/p><\/details>\n\t\t\t\t\t<details open><summary>Que se passe-t-il en cas de retard ou d&rsquo;annulation ? <svg class=\"dd-ic\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 9l6 6 6-6\"\/><\/svg><\/summary><p>En cas de <a href=\"https:\/\/dover-dunkirk.com\/fr\/meteo\/\">temp\u00eate<\/a> ou de probl\u00e8me technique, DFDS navigue parfois avec moins de navires. Vous \u00eates alors plac\u00e9 sur le d\u00e9part suivant. Les infos en direct sont sur la page <a href=\"https:\/\/dover-dunkirk.com\/fr\/infos-trafic\/\">infos trafic<\/a>.<\/p><\/details>\n\t\t\t\t<\/div>\n\t\t\t<\/section>\n\t\t<\/div>\n\n\t\t<aside class=\"dd-aside\">\n\t\t\t<div class=\"dd-panel\"><h3>R\u00e9server un d\u00e9part<\/h3><p class=\"dd-small dd-muted\" style=\"margin:0 0 12px\">Les tarifs varient selon le d\u00e9part et le jour. Comparez-les pour l&rsquo;heure choisie.<\/p><a class=\"dd-btn\" href=\"https:\/\/dover-dunkirk.com\/fr\/go\/directferries-dunkirk-dover\/\" target=\"_blank\" rel=\"sponsored nofollow noopener\">Comparer les tarifs<\/a><p class=\"dd-disc\">Vous r\u00e9servez via notre partenaire DirectFerries.<\/p><\/div>\n\t\t\t<div class=\"dd-panel\"><h3>La ligne en chiffres<\/h3><div class=\"dd-panel dd-facts\"><dl><div><dt>Travers\u00e9e<\/dt><dd class=\"dd-num\">2 heures<\/dd><\/div><div><dt>D\u00e9parts par jour<\/dt><dd class=\"dd-num\">jusqu&#039;\u00e0 11 par sens<\/dd><\/div><div><dt>Enregistrement<\/dt><dd class=\"dd-num\">cl\u00f4ture 60 min avant<\/dd><\/div><div><dt>Voiture + 5, aller simple<\/dt><dd class=\"dd-num\">d\u00e8s 114 \u20ac<\/dd><\/div><div><dt>Pi\u00e9tons<\/dt><dd class=\"dd-num\">non accept\u00e9s<\/dd><\/div><div><dt>Animaux<\/dt><dd class=\"dd-num\">restent dans la voiture<\/dd><\/div><\/dl><\/div><\/div>\n\t\t\t<div class=\"dd-panel\"><h3>Sur cette page<\/h3><nav class=\"dd-toc\"><a href=\"#aujourdhui\">D\u00e9parts du jour<\/a><a href=\"#semaine\">Semaine vers Douvres<\/a><a href=\"#semaine-retour\">Semaine vers Dunkerque<\/a><a href=\"#date\">Autre date<\/a><a href=\"#duree\">Dur\u00e9e de la travers\u00e9e<\/a><a href=\"#enregistrement\">Enregistrement<\/a><a href=\"#nuit\">Nuit et week-end<\/a><a href=\"#questions\">Questions<\/a><\/nav><\/div>\n\t\t<\/aside>\n\t<\/div>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>Horaires du ferry Dunkerque vers Douvres Les d\u00e9parts DFDS ont lieu environ toutes les deux heures, dans les deux sens, avec un d\u00e9part de nuit certains jours. Ci-dessous les d\u00e9parts du jour, les horaires de la semaine \u00e0 venir et les heures de fermeture de l&rsquo;enregistrement. Les heures de d\u00e9part sont en heure locale du&#8230;<\/p>\n","protected":false},"author":2,"featured_media":234,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_kad_post_transparent":"","_kad_post_title":"hide","_kad_post_layout":"fullwidth","_kad_post_sidebar_id":"","_kad_post_content_style":"unboxed","_kad_post_vertical_padding":"","_kad_post_feature":"hide","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"class_list":["post-89","page","type-page","status-publish","has-post-thumbnail","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Horaires ferry Dunkerque Douvres : jour et semaine<\/title>\n<meta name=\"description\" content=\"Horaires du ferry DFDS Dunkerque vers Douvres : d\u00e9parts du jour, grille de la semaine, dur\u00e9e r\u00e9elle de deux heures et fermeture de l&#039;enregistrement.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Horaires ferry Dunkerque Douvres : jour et semaine\" \/>\n<meta property=\"og:description\" content=\"Horaires du ferry DFDS Dunkerque vers Douvres : d\u00e9parts du jour, grille de la semaine, dur\u00e9e r\u00e9elle de deux heures et fermeture de l&#039;enregistrement.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/\" \/>\n<meta property=\"og:site_name\" content=\"Dunkerque Douvres Ferry\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-28T20:04:57+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2026\/09\/delft-seaways-bow-loading-ramp.webp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/horaires-des-traversees\\\/\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/horaires-des-traversees\\\/\",\"name\":\"Horaires ferry Dunkerque Douvres : jour et semaine\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/horaires-des-traversees\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/horaires-des-traversees\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/wp-content\\\/uploads\\\/sites\\\/4\\\/2026\\\/09\\\/delft-seaways-bow-loading-ramp.webp\",\"datePublished\":\"2025-01-09T12:56:55+00:00\",\"dateModified\":\"2026-09-28T20:04:57+00:00\",\"description\":\"Horaires du ferry DFDS Dunkerque vers Douvres : d\u00e9parts du jour, grille de la semaine, dur\u00e9e r\u00e9elle de deux heures et fermeture de l'enregistrement.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/horaires-des-traversees\\\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/horaires-des-traversees\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/horaires-des-traversees\\\/#primaryimage\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/wp-content\\\/uploads\\\/sites\\\/4\\\/2026\\\/09\\\/delft-seaways-bow-loading-ramp.webp\",\"contentUrl\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/wp-content\\\/uploads\\\/sites\\\/4\\\/2026\\\/09\\\/delft-seaways-bow-loading-ramp.webp\",\"width\":1400,\"height\":1050,\"caption\":\"Le Delft Seaways \u00e0 quai \u00e0 Dunkerque, rampe abaiss\u00e9e\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/horaires-des-traversees\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Horaires du ferry Dunkerque vers Douvres\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/#website\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/\",\"name\":\"Dunkerque Douvres Ferry\",\"description\":\"De Dunkerque \u00e0 Douvres\",\"publisher\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/#organization\",\"name\":\"Dunkerque Douvres Ferry\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/wp-content\\\/uploads\\\/sites\\\/4\\\/2025\\\/01\\\/cropped-D.png\",\"contentUrl\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/wp-content\\\/uploads\\\/sites\\\/4\\\/2025\\\/01\\\/cropped-D.png\",\"width\":512,\"height\":512,\"caption\":\"Dunkerque Douvres Ferry\"},\"image\":{\"@id\":\"https:\\\/\\\/dover-dunkirk.com\\\/fr\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Horaires ferry Dunkerque Douvres : jour et semaine","description":"Horaires du ferry DFDS Dunkerque vers Douvres : d\u00e9parts du jour, grille de la semaine, dur\u00e9e r\u00e9elle de deux heures et fermeture de l'enregistrement.","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:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/","og_locale":"fr_FR","og_type":"article","og_title":"Horaires ferry Dunkerque Douvres : jour et semaine","og_description":"Horaires du ferry DFDS Dunkerque vers Douvres : d\u00e9parts du jour, grille de la semaine, dur\u00e9e r\u00e9elle de deux heures et fermeture de l'enregistrement.","og_url":"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/","og_site_name":"Dunkerque Douvres Ferry","article_modified_time":"2026-09-28T20:04:57+00:00","og_image":[{"url":"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2026\/09\/delft-seaways-bow-loading-ramp.webp","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Dur\u00e9e de lecture estim\u00e9e":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/","url":"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/","name":"Horaires ferry Dunkerque Douvres : jour et semaine","isPartOf":{"@id":"https:\/\/dover-dunkirk.com\/fr\/#website"},"primaryImageOfPage":{"@id":"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/#primaryimage"},"image":{"@id":"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/#primaryimage"},"thumbnailUrl":"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2026\/09\/delft-seaways-bow-loading-ramp.webp","datePublished":"2025-01-09T12:56:55+00:00","dateModified":"2026-09-28T20:04:57+00:00","description":"Horaires du ferry DFDS Dunkerque vers Douvres : d\u00e9parts du jour, grille de la semaine, dur\u00e9e r\u00e9elle de deux heures et fermeture de l'enregistrement.","breadcrumb":{"@id":"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/"]}]},{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/#primaryimage","url":"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2026\/09\/delft-seaways-bow-loading-ramp.webp","contentUrl":"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2026\/09\/delft-seaways-bow-loading-ramp.webp","width":1400,"height":1050,"caption":"Le Delft Seaways \u00e0 quai \u00e0 Dunkerque, rampe abaiss\u00e9e"},{"@type":"BreadcrumbList","@id":"https:\/\/dover-dunkirk.com\/fr\/horaires-des-traversees\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/dover-dunkirk.com\/fr\/"},{"@type":"ListItem","position":2,"name":"Horaires du ferry Dunkerque vers Douvres"}]},{"@type":"WebSite","@id":"https:\/\/dover-dunkirk.com\/fr\/#website","url":"https:\/\/dover-dunkirk.com\/fr\/","name":"Dunkerque Douvres Ferry","description":"De Dunkerque \u00e0 Douvres","publisher":{"@id":"https:\/\/dover-dunkirk.com\/fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/dover-dunkirk.com\/fr\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/dover-dunkirk.com\/fr\/#organization","name":"Dunkerque Douvres Ferry","url":"https:\/\/dover-dunkirk.com\/fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/dover-dunkirk.com\/fr\/#\/schema\/logo\/image\/","url":"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2025\/01\/cropped-D.png","contentUrl":"https:\/\/dover-dunkirk.com\/fr\/wp-content\/uploads\/sites\/4\/2025\/01\/cropped-D.png","width":512,"height":512,"caption":"Dunkerque Douvres Ferry"},"image":{"@id":"https:\/\/dover-dunkirk.com\/fr\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/dover-dunkirk.com\/fr\/wp-json\/wp\/v2\/pages\/89","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dover-dunkirk.com\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/dover-dunkirk.com\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/dover-dunkirk.com\/fr\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dover-dunkirk.com\/fr\/wp-json\/wp\/v2\/comments?post=89"}],"version-history":[{"count":24,"href":"https:\/\/dover-dunkirk.com\/fr\/wp-json\/wp\/v2\/pages\/89\/revisions"}],"predecessor-version":[{"id":309,"href":"https:\/\/dover-dunkirk.com\/fr\/wp-json\/wp\/v2\/pages\/89\/revisions\/309"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dover-dunkirk.com\/fr\/wp-json\/wp\/v2\/media\/234"}],"wp:attachment":[{"href":"https:\/\/dover-dunkirk.com\/fr\/wp-json\/wp\/v2\/media?parent=89"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}