diff --git a/Gemfile b/Gemfile
index 75f3b0ab1399bf1211a73b7a3bd5bc6ff0bf5ba5..2f7e2ed7957967224a67a91d6a889d1e2d28e65e 100644
--- a/Gemfile
+++ b/Gemfile
@@ -5,6 +5,7 @@ ruby "3.1.4"
 
 gem "activestorage-scaleway-service"#, path: "../activestorage-scaleway-service"
 gem "active_storage_validations", "~> 1"
+gem "add_to_calendar"
 gem "angularjs-rails"
 gem "aws-sdk-s3"
 gem "bootstrap"
diff --git a/Gemfile.lock b/Gemfile.lock
index bc76df4372f722c3b7318ece1ab5990d7ec37672..4666d936e59f49960999d53398a2473eb592b7ba 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -110,6 +110,9 @@ GEM
       minitest (>= 5.1)
       mutex_m
       tzinfo (~> 2.0)
+    add_to_calendar (0.4.0)
+      tzinfo (>= 1.1, < 3)
+      tzinfo-data (~> 1.2020)
     addressable (2.8.6)
       public_suffix (>= 2.0.2, < 6.0)
     angularjs-rails (1.8.0)
@@ -580,6 +583,8 @@ GEM
       ethon (>= 0.9.0)
     tzinfo (2.0.6)
       concurrent-ruby (~> 1.0)
+    tzinfo-data (1.2023.4)
+      tzinfo (>= 1.0.0)
     unaccent (0.4.0)
     unicode-display_width (2.5.0)
     unsplash (3.1.1)
@@ -624,6 +629,7 @@ PLATFORMS
 DEPENDENCIES
   active_storage_validations (~> 1)
   activestorage-scaleway-service
+  add_to_calendar
   angularjs-rails
   annotate
   aws-sdk-s3
diff --git a/app/models/communication/website/agenda/event.rb b/app/models/communication/website/agenda/event.rb
index d920a93635851de9d8dfead16447f89dfe7e19d7..d8066aa58f069cfd8404531bff867b3dea6ff6d1 100644
--- a/app/models/communication/website/agenda/event.rb
+++ b/app/models/communication/website/agenda/event.rb
@@ -148,12 +148,49 @@ class Communication::Website::Agenda::Event < ApplicationRecord
     "#{Static.remove_trailing_slash website.url}#{Static.clean_path current_permalink_in_website(website).path}"
   end
 
+  def cal
+    @cal ||= AddToCalendar::URLs.new(
+      start_datetime: from_time, 
+      end_datetime: to_time,
+      timezone: 'Europe/Paris',
+      title: "#{title} #{subtitle}",
+      url: url,
+      description: summary,
+      all_day: (from_hour.nil? && to_hour.nil?)
+    )
+  end
+
   def to_s
     "#{title}"
   end
 
   protected
 
+  def from_time
+    from_hour.nil?  ? from_day.to_time
+                    : date_and_time(from_day, from_hour)
+  end
+
+  def to_time
+    if to_day.nil? && to_hour.nil?
+      # Pas de fin
+      nil
+    elsif to_day.nil? && to_hour.present?
+      # Heure de fin sans jour de fin, donc on se base sur le jour de début
+      date_and_time(from_day, to_hour)
+    elsif to_day.present? && to_hour.nil?
+      # Jour de fin seul
+      to_day.to_time
+    elsif to_day.present? && to_hour.nil?
+      # Jour et heure de fin
+      date_and_time(to_day, to_hour)
+    end
+  end
+
+  def date_and_time(date, time)
+    Time.new(date.year, date.month, date.day, time.hour, time.min, time.sec, time.zone)
+  end
+
   def check_accessibility
     accessibility_merge_array blocks
   end
diff --git a/app/views/admin/communication/websites/agenda/events/_dates_static.html.erb b/app/views/admin/communication/websites/agenda/events/_dates_static.html.erb
index 0723bc7565c8e4e475ee947a6f8d01b7cf5d13ee..430c71b23097670fcc1fcc910eeadd1b5e17498d 100644
--- a/app/views/admin/communication/websites/agenda/events/_dates_static.html.erb
+++ b/app/views/admin/communication/websites/agenda/events/_dates_static.html.erb
@@ -24,4 +24,10 @@ indentation = '  ' * depth
 <%= indentation %>    day: <%= event.to_day || event.from_day %>
 <% if event.to_hour %>
 <%= indentation %>    hour: <%= event.to_hour.strftime "%H:%M" %>
-<% end %>
\ No newline at end of file
+<% end %>
+<%= indentation %>  add_to_calendar:
+<%= indentation %>    google: "<%= @event.cal.google_url %>"
+<%= indentation %>    yahoo: "<%= @event.cal.yahoo_url %>"
+<%= indentation %>    office: "<%= @event.cal.office365_url %>"
+<%= indentation %>    outlook: "<%= @event.cal.outlook_com_url %>"
+<%= indentation %>    ical: "<%= @event.cal.ical_url %>"