From 3bb6df22cdff4ef537cffe803cb15905b943a86c Mon Sep 17 00:00:00 2001
From: Igor Drozdov <idrozdov@gitlab.com>
Date: Wed, 5 Jul 2023 12:57:57 +0000
Subject: [PATCH] Ban deprecation warnings related to date and time formatting

---
 .../concerns/membership_actions.rb            |  2 +-
 app/helpers/issuables_helper.rb               |  6 +---
 app/helpers/time_helper.rb                    |  4 ---
 app/helpers/timeboxes_helper.rb               |  4 +--
 app/helpers/users_helper.rb                   |  2 +-
 app/models/concerns/milestoneish.rb           |  4 +--
 app/models/deployment.rb                      |  2 +-
 app/serializers/lfs_file_lock_entity.rb       |  2 +-
 app/services/issues/export_csv_service.rb     | 10 +++---
 .../system_notes/time_tracking_service.rb     |  4 +--
 app/services/work_items/export_csv_service.rb |  2 +-
 app/views/admin/groups/show.html.haml         |  2 +-
 app/views/admin/projects/show.html.haml       |  6 ++--
 app/views/admin/users/_profile.html.haml      |  2 +-
 app/views/admin/users/show.html.haml          |  8 ++---
 app/views/events/_event_push.atom.haml        |  2 +-
 app/views/notify/issue_due_email.html.haml    |  2 +-
 .../notify/repository_push_email.html.haml    |  2 +-
 .../notify/repository_push_email.text.haml    |  2 +-
 .../profiles/keys/_key_details.html.haml      |  2 +-
 .../profiles/two_factor_auths/show.html.haml  |  2 +-
 .../issues/service_desk/_issue.html.haml      |  2 +-
 .../shared/deploy_tokens/_table.html.haml     |  2 +-
 app/views/shared/members/_member.html.haml    |  2 +-
 .../shared/milestones/_sidebar.html.haml      |  4 +--
 app/views/users/calendar_activities.html.haml |  2 +-
 config/initializers/00_deprecations.rb        |  4 ++-
 .../groups/seat_usage_controller.rb           |  2 +-
 ee/app/helpers/ee/projects_helper.rb          |  2 +-
 ee/app/models/iteration.rb                    |  2 +-
 ee/app/presenters/epic_presenter.rb           |  2 +-
 ee/app/serializers/epic_base_entity.rb        |  2 +-
 .../groups/memberships/export_service.rb      |  2 +-
 .../historical_user_data/csv_service.rb       |  8 ++---
 .../admin/users/_credit_card_info.html.haml   |  2 +-
 ee/app/views/admin/users/card_match.html.haml |  4 +--
 ...sonal_access_token_revoked_email.html.haml |  2 +-
 ...sonal_access_token_revoked_email.text.haml |  2 +-
 .../ssh_key_deleted_email.html.haml           |  2 +-
 .../ssh_key_deleted_email.text.haml           |  2 +-
 .../_eoa_bronze_plan_banner.html.haml         |  2 +-
 .../count_secure_pipelines_metric.rb          |  4 +--
 .../count_ci_builds_metric_spec.rb            |  4 +--
 ..._ci_environments_approval_required_spec.rb |  4 +--
 .../count_deployment_approvals_metric_spec.rb |  4 +--
 ...ned_security_policy_project_metric_spec.rb |  4 +--
 ...pplied_scan_result_policies_metric_spec.rb |  4 +--
 ...pplied_scan_result_policies_metric_spec.rb |  4 +--
 ...ned_security_policy_project_metric_spec.rb |  4 +--
 .../count_secure_pipelines_metric_spec.rb     |  4 +--
 .../count_security_scans_metric_spec.rb       |  4 +--
 ...pplied_scan_result_policies_metric_spec.rb |  4 +--
 ...pplied_scan_result_policies_metric_spec.rb |  4 +--
 ...nt_users_creating_ci_builds_metric_spec.rb |  4 +--
 ..._required_approvals_average_metric_spec.rb |  4 +--
 ..._required_approvals_average_metric_spec.rb |  4 +--
 .../credentials_inventory_mailer_spec.rb      |  4 +--
 .../consistency_check_service_spec.rb         |  4 +--
 .../historical_user_data/csv_service_spec.rb  | 10 +++---
 .../refresh_seats_worker_spec.rb              |  2 +-
 lib/gitlab/pagination/keyset/order.rb         |  2 +-
 .../groups/group_members_controller_spec.rb   |  2 +-
 .../project_members_controller_spec.rb        |  2 +-
 .../issues/user_creates_issue_spec.rb         |  2 +-
 spec/features/issues/user_edits_issue_spec.rb |  2 +-
 .../user_sees_deployment_widget_spec.rb       |  2 +-
 spec/helpers/issuables_helper_spec.rb         |  6 ++--
 spec/helpers/page_layout_helper_spec.rb       |  2 +-
 .../pagination/keyset/connection_spec.rb      |  2 +-
 .../gitlab/pagination/keyset/iterator_spec.rb |  2 +-
 ...count_bulk_imports_entities_metric_spec.rb | 32 +++++++++----------
 .../count_imported_projects_metric_spec.rb    |  8 ++---
 ...unt_imported_projects_total_metric_spec.rb |  4 +--
 ...count_users_creating_issues_metric_spec.rb |  4 +--
 spec/models/concerns/milestoneish_spec.rb     | 16 ++++++++++
 .../quick_actions/interpret_service_spec.rb   |  2 +-
 .../time_tracking_service_spec.rb             | 12 +++----
 .../work_items/export_csv_service_spec.rb     |  2 +-
 .../helpers/features/iteration_helpers.rb     |  2 +-
 .../sidebar_due_date_shared_examples.rb       |  2 +-
 .../stage_event_model_examples.rb             |  2 +-
 spec/views/profiles/show.html.haml_spec.rb    |  2 +-
 82 files changed, 164 insertions(+), 152 deletions(-)

diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index 31675a5816353..0c15c4d0d3f63 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -16,7 +16,7 @@ def update
     member_data = if member.expires?
                     {
                       expires_soon: member.expires_soon?,
-                      expires_at_formatted: member.expires_at.to_time.in_time_zone.to_s(:medium)
+                      expires_at_formatted: member.expires_at.to_time.in_time_zone.to_fs(:medium)
                     }
                   else
                     {}
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index e247577aed034..e921e9bae4d79 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -43,14 +43,10 @@ def sidebar_milestone_remaining_days(milestone)
     due_date_with_remaining_days(milestone[:due_date], milestone[:start_date])
   end
 
-  def sidebar_due_date_tooltip_label(due_date)
-    [_('Due date'), due_date_with_remaining_days(due_date)].compact.join('<br/>')
-  end
-
   def due_date_with_remaining_days(due_date, start_date = nil)
     return unless due_date
 
-    "#{due_date.to_s(:medium)} (#{remaining_days_in_words(due_date, start_date)})"
+    "#{due_date.to_fs(:medium)} (#{remaining_days_in_words(due_date, start_date)})"
   end
 
   def multi_label_name(current_labels, default_label)
diff --git a/app/helpers/time_helper.rb b/app/helpers/time_helper.rb
index cb6f60ab79b81..ad473875a53f5 100644
--- a/app/helpers/time_helper.rb
+++ b/app/helpers/time_helper.rb
@@ -17,10 +17,6 @@ def time_interval_in_words(interval_in_seconds)
     end
   end
 
-  def date_from_to(from, to)
-    "#{from.to_s(:short)} - #{to.to_s(:short)}"
-  end
-
   def duration_in_numbers(duration_in_seconds)
     seconds = duration_in_seconds % 1.minute
     minutes = (duration_in_seconds / 1.minute) % (1.hour / 1.minute)
diff --git a/app/helpers/timeboxes_helper.rb b/app/helpers/timeboxes_helper.rb
index 66c9011fbcc18..cb6ed059ec9f9 100644
--- a/app/helpers/timeboxes_helper.rb
+++ b/app/helpers/timeboxes_helper.rb
@@ -109,7 +109,7 @@ def milestone_time_for(date, date_type)
       content = [
         title,
         "<br />",
-        date.to_s(:medium),
+        date.to_fs(:medium),
         "(#{time_ago} #{state})"
       ].join(" ")
 
@@ -172,7 +172,7 @@ def recent_releases_with_counts(milestone, user)
 
   def milestone_tooltip_due_date(milestone)
     if milestone.due_date
-      "#{milestone.due_date.to_s(:medium)} (#{remaining_days_in_words(milestone.due_date, milestone.start_date)})"
+      "#{milestone.due_date.to_fs(:medium)} (#{remaining_days_in_words(milestone.due_date, milestone.start_date)})"
     else
       _('Milestone')
     end
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index c8002c437a9e6..893cf8851c080 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -12,7 +12,7 @@ def user_clear_status_at(user)
     # The user.status can be nil when the user has no status, so we need to protect against that case.
     # iso8601 is the official RFC supported format for frontend parsing of date:
     # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date
-    user.status&.clear_status_at&.to_s(:iso8601)
+    user.status&.clear_status_at&.to_fs(:iso8601)
   end
 
   def user_link(user)
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index 4f2ea58f36d86..7968fe1cd86f5 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -90,9 +90,9 @@ def upcoming?
   def expires_at
     if due_date
       if due_date.past?
-        "expired on #{due_date.to_s(:medium)}"
+        "expired on #{due_date.to_fs(:medium)}"
       else
-        "expires on #{due_date.to_s(:medium)}"
+        "expires on #{due_date.to_fs(:medium)}"
       end
     end
   end
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 5af0216a3ca85..b59b22c10c4c3 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -351,7 +351,7 @@ def deployed_at
   end
 
   def formatted_deployment_time
-    deployed_at&.to_time&.in_time_zone&.to_s(:medium)
+    deployed_at&.to_time&.in_time_zone&.to_fs(:medium)
   end
 
   def deployed_by
diff --git a/app/serializers/lfs_file_lock_entity.rb b/app/serializers/lfs_file_lock_entity.rb
index 7961c4e666b37..787d201d0a1af 100644
--- a/app/serializers/lfs_file_lock_entity.rb
+++ b/app/serializers/lfs_file_lock_entity.rb
@@ -5,7 +5,7 @@ class LfsFileLockEntity < Grape::Entity
 
   expose :path
   expose(:id) { |entity| entity.id.to_s }
-  expose(:created_at, as: :locked_at) { |entity| entity.created_at.to_s(:iso8601) }
+  expose(:created_at, as: :locked_at) { |entity| entity.created_at.to_fs(:iso8601) }
 
   expose :owner do
     expose(:name) { |entity| entity.user&.name }
diff --git a/app/services/issues/export_csv_service.rb b/app/services/issues/export_csv_service.rb
index 9e524d90505fc..99c0e9f1a37a5 100644
--- a/app/services/issues/export_csv_service.rb
+++ b/app/services/issues/export_csv_service.rb
@@ -34,14 +34,14 @@ def header_to_value_hash
         'Assignee Username' => -> (issue) { issue.assignees.map(&:username).join(', ') },
         'Confidential' => -> (issue) { issue.confidential? ? 'Yes' : 'No' },
         'Locked' => -> (issue) { issue.discussion_locked? ? 'Yes' : 'No' },
-        'Due Date' => -> (issue) { issue.due_date&.to_s(:csv) },
-        'Created At (UTC)' => -> (issue) { issue.created_at&.to_s(:csv) },
-        'Updated At (UTC)' => -> (issue) { issue.updated_at&.to_s(:csv) },
-        'Closed At (UTC)' => -> (issue) { issue.closed_at&.to_s(:csv) },
+        'Due Date' => -> (issue) { issue.due_date&.to_fs(:csv) },
+        'Created At (UTC)' => -> (issue) { issue.created_at&.to_fs(:csv) },
+        'Updated At (UTC)' => -> (issue) { issue.updated_at&.to_fs(:csv) },
+        'Closed At (UTC)' => -> (issue) { issue.closed_at&.to_fs(:csv) },
         'Milestone' => -> (issue) { issue.milestone&.title },
         'Weight' => -> (issue) { issue.weight },
         'Labels' => -> (issue) { issue_labels(issue) },
-        'Time Estimate' => ->(issue) { issue.time_estimate.to_s(:csv) },
+        'Time Estimate' => ->(issue) { issue.time_estimate.to_fs(:csv) },
         'Time Spent' => -> (issue) { issue_time_spent(issue) }
       }
     end
diff --git a/app/services/system_notes/time_tracking_service.rb b/app/services/system_notes/time_tracking_service.rb
index b7a2afbaf156b..f9084ed67d3bf 100644
--- a/app/services/system_notes/time_tracking_service.rb
+++ b/app/services/system_notes/time_tracking_service.rb
@@ -147,9 +147,9 @@ def message_for_changed_date(changed_dates, date_key)
       readable_date = date_key.humanize.downcase
 
       if changed_date.nil?
-        "removed #{readable_date} #{changed_dates[date_key].first.to_s(:long)}"
+        "removed #{readable_date} #{changed_dates[date_key].first.to_fs(:long)}"
       else
-        "changed #{readable_date} to #{changed_date.to_s(:long)}"
+        "changed #{readable_date} to #{changed_date.to_fs(:long)}"
       end
     end
 
diff --git a/app/services/work_items/export_csv_service.rb b/app/services/work_items/export_csv_service.rb
index ee20a2832ce88..74bc1f526bffe 100644
--- a/app/services/work_items/export_csv_service.rb
+++ b/app/services/work_items/export_csv_service.rb
@@ -28,7 +28,7 @@ def header_to_value_hash
         'Type' => ->(work_item) { work_item.work_item_type.name },
         'Author' => 'author_name',
         'Author Username' => ->(work_item) { work_item.author.username },
-        'Created At (UTC)' => ->(work_item) { work_item.created_at.to_s(:csv) }
+        'Created At (UTC)' => ->(work_item) { work_item.created_at.to_fs(:csv) }
       }
     end
 
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 4ba6912690650..5f5f6c986639f 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -43,7 +43,7 @@
           %li
             %span.light= _('Created on:')
             %strong
-              = @group.created_at.to_s(:medium)
+              = @group.created_at.to_fs(:medium)
 
           %li
             %span.light= _('ID:')
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 8eb72fa281e0c..0637b0eae4724 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -60,7 +60,7 @@
             %span.light
               = _('Created on:')
             %strong
-              = @project.created_at.to_s(:medium)
+              = @project.created_at.to_fs(:medium)
 
           %li{ class: 'gl-px-5!' }
             %span.light
@@ -158,10 +158,10 @@
               = _("This repository has never been checked.")
             - elsif @project.last_repository_check_failed?
               - failed_message = _("This repository was last checked %{last_check_timestamp}. The check %{strong_start}failed.%{strong_end} See the 'repocheck.log' file for error messages.")
-              - failed_message = failed_message % { last_check_timestamp: @project.last_repository_check_at.to_s(:medium), strong_start: "<strong class='cred'>", strong_end: "</strong>" }
+              - failed_message = failed_message % { last_check_timestamp: @project.last_repository_check_at.to_fs(:medium), strong_start: "<strong class='cred'>", strong_end: "</strong>" }
               = failed_message.html_safe
             - else
-              = _("This repository was last checked %{last_check_timestamp}. The check passed.") % { last_check_timestamp: @project.last_repository_check_at.to_s(:medium) }
+              = _("This repository was last checked %{last_check_timestamp}. The check passed.") % { last_check_timestamp: @project.last_repository_check_at.to_fs(:medium) }
 
             = link_to sprite_icon('question-o'), help_page_path('administration/repository_checks')
 
diff --git a/app/views/admin/users/_profile.html.haml b/app/views/admin/users/_profile.html.haml
index b4f61a1b66523..bb89b5baf28cf 100644
--- a/app/views/admin/users/_profile.html.haml
+++ b/app/views/admin/users/_profile.html.haml
@@ -5,7 +5,7 @@
     %ul.content-list
       %li
         %span.light= _('Member since')
-        %strong= user.created_at.to_s(:medium)
+        %strong= user.created_at.to_fs(:medium)
       - unless user.public_email.blank?
         %li
           %span.light= _('E-mail:')
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index ea6525e1b96a9..d793dcaccd51d 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -86,12 +86,12 @@
           %li
             %span.light= _('Member since:')
             %strong
-              = @user.created_at.to_s(:medium)
+              = @user.created_at.to_fs(:medium)
           - if @user.confirmed_at
             %li
               %span.light= _('Confirmed at:')
               %strong
-                = @user.confirmed_at.to_s(:medium)
+                = @user.confirmed_at.to_fs(:medium)
           - else
             %li
               %span.ligh= _('Confirmed:')
@@ -106,7 +106,7 @@
           %li
             %span.light= _('Current sign-in at:')
             %strong
-              = @user.current_sign_in_at&.to_s(:medium) || _('never')
+              = @user.current_sign_in_at&.to_fs(:medium) || _('never')
 
           %li
             %span.light= _('Last sign-in IP:')
@@ -116,7 +116,7 @@
           %li
             %span.light= _('Last sign-in at:')
             %strong
-              = @user.last_sign_in_at&.to_s(:medium) || _('never')
+              = @user.last_sign_in_at&.to_fs(:medium) || _('never')
 
           %li
             %span.light= _('Sign-in count:')
diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml
index c3786d7c16d87..51b60fe01523b 100644
--- a/app/views/events/_event_push.atom.haml
+++ b/app/views/events/_event_push.atom.haml
@@ -6,7 +6,7 @@
     = link_to "(#{truncate_sha(event.commit_id)})", event_url if event_url
     %i
       at
-      = event.created_at.to_s(:short)
+      = event.created_at.to_fs(:short)
   - unless event.rm_ref?
     .blockquote= markdown(escape_once(event.commit_title), pipeline: :atom, project: event.project, author: event.author)
     - if event.commits_count > 1
diff --git a/app/views/notify/issue_due_email.html.haml b/app/views/notify/issue_due_email.html.haml
index 9dd501022dd4d..f1959ce2557a1 100644
--- a/app/views/notify/issue_due_email.html.haml
+++ b/app/views/notify/issue_due_email.html.haml
@@ -5,7 +5,7 @@
   %p
     = assignees_label(@issue)
 %p
-  = sprintf(s_('Notify|This issue is due on: %{issue_due_date}'), { issue_due_date: @issue.due_date.to_s(:medium) }).html_safe
+  = sprintf(s_('Notify|This issue is due on: %{issue_due_date}'), { issue_due_date: @issue.due_date.to_fs(:medium) }).html_safe
 
 - if @issue.description
   .md
diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml
index d493f9d5d9839..199865ba644cc 100644
--- a/app/views/notify/repository_push_email.html.haml
+++ b/app/views/notify/repository_push_email.html.haml
@@ -19,7 +19,7 @@
       %li
         %strong= link_to(commit.short_id, project_commit_url(@message.project, commit))
         %div
-          = html_escape(s_('Notify|%{committed_by_start} by %{author_name} %{committed_by_end} %{committed_at_start} at %{committed_date} %{committed_at_end}')) % {committed_by_start: '<span>'.html_safe, author_name: commit.author_name, committed_by_end: '</span>'.html_safe, committed_at_start: '<i>'.html_safe, committed_date: commit.committed_date.to_s(:iso8601), committed_at_end: '</i>'.html_safe}
+          = html_escape(s_('Notify|%{committed_by_start} by %{author_name} %{committed_by_end} %{committed_at_start} at %{committed_date} %{committed_at_end}')) % {committed_by_start: '<span>'.html_safe, author_name: commit.author_name, committed_by_end: '</span>'.html_safe, committed_at_start: '<i>'.html_safe, committed_date: commit.committed_date.to_fs(:iso8601), committed_at_end: '</i>'.html_safe}
         %pre.commit-message
           = commit.safe_message
 
diff --git a/app/views/notify/repository_push_email.text.haml b/app/views/notify/repository_push_email.text.haml
index 2ba0a2cf4abb4..38a439864b735 100644
--- a/app/views/notify/repository_push_email.text.haml
+++ b/app/views/notify/repository_push_email.text.haml
@@ -8,7 +8,7 @@
     \
   = @message.reverse_compare? ? "Deleted commits:" : "Commits:"
   - @message.commits.each do |commit|
-    #{commit.short_id} by #{commit.author_name} at #{commit.committed_date.to_s(:iso8601)}
+    #{commit.short_id} by #{commit.author_name} at #{commit.committed_date.to_fs(:iso8601)}
     #{commit.safe_message}
     \- - - - -
   \
diff --git a/app/views/profiles/keys/_key_details.html.haml b/app/views/profiles/keys/_key_details.html.haml
index 4f3d97fb90c60..d835366348a91 100644
--- a/app/views/profiles/keys/_key_details.html.haml
+++ b/app/views/profiles/keys/_key_details.html.haml
@@ -14,7 +14,7 @@
             %strong= ssh_key_usage_types.invert[@key.usage_type]
           %li
             %span.light= _('Created on:')
-            %strong= @key.created_at.to_s(:medium)
+            %strong= @key.created_at.to_fs(:medium)
           %li
             %span.light= _('Expires:')
             %strong= @key.expires_at.try(:to_s, :medium) || _('Never')
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index 461164e1ae913..bfd6b133a937e 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -101,7 +101,7 @@
                     - else
                       %span.gl-text-gray-500
                         = _("no name set")
-                  %td= registration[:created_at].to_date.to_s(:medium)
+                  %td= registration[:created_at].to_date.to_fs(:medium)
                   %td
                     = render Pajamas::ButtonComponent.new(variant: :danger,
                       href: registration[:delete_path],
diff --git a/app/views/projects/issues/service_desk/_issue.html.haml b/app/views/projects/issues/service_desk/_issue.html.haml
index 04ea6103b832b..5b98712d3eb2a 100644
--- a/app/views/projects/issues/service_desk/_issue.html.haml
+++ b/app/views/projects/issues/service_desk/_issue.html.haml
@@ -33,7 +33,7 @@
           %span.issuable-due-date.d-none.d-sm-inline-block.has-tooltip{ class: "#{'cred' if issue.overdue? && !issue.closed?}", title: _('Due date') }
             &nbsp;
             = sprite_icon('calendar')
-            = issue.due_date.to_s(:medium)
+            = issue.due_date.to_fs(:medium)
 
         = render_if_exists "projects/issues/issue_weight", issue: issue
         = render_if_exists "projects/issues/health_status", issue: issue
diff --git a/app/views/shared/deploy_tokens/_table.html.haml b/app/views/shared/deploy_tokens/_table.html.haml
index a7bf3bfb81e65..3827ecf73a47a 100644
--- a/app/views/shared/deploy_tokens/_table.html.haml
+++ b/app/views/shared/deploy_tokens/_table.html.haml
@@ -16,7 +16,7 @@
           %tr
             %td= token.name
             %td= token.username
-            %td= token.created_at.to_date.to_s(:medium)
+            %td= token.created_at.to_date.to_fs(:medium)
             %td
               - if token.expires?
                 %span{ class: ('text-warning' if token.expires_soon?) }
diff --git a/app/views/shared/members/_member.html.haml b/app/views/shared/members/_member.html.haml
index 376e51a6b1556..c86993f5b776b 100644
--- a/app/views/shared/members/_member.html.haml
+++ b/app/views/shared/members/_member.html.haml
@@ -43,7 +43,7 @@
             = _("Given access %{time_ago}").html_safe % { time_ago: time_ago_with_tooltip(member.created_at) }
           %span.js-expires-in{ class: ('gl-display-none' unless member.expires?) }
             &middot;
-            %span.js-expires-in-text{ class: "has-tooltip#{' text-warning' if member.expires_soon?}", title: (member.expires_at.to_time.in_time_zone.to_s(:medium) if member.expires?) }
+            %span.js-expires-in-text{ class: "has-tooltip#{' text-warning' if member.expires_soon?}", title: (member.expires_at.to_time.in_time_zone.to_fs(:medium) if member.expires?) }
               - if member.expires?
                 - preposition = current_user.time_display_relative ? '' : 'on'
                 = _("Expires %{preposition} %{expires_at}").html_safe % { expires_at: time_ago_with_tooltip(member.expires_at), preposition: preposition }
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index 5477b9395eabd..1b0eeb424c208 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -26,7 +26,7 @@
       .value
         %span.value-content{ data: { qa_selector: 'start_date_content' } }
           - if milestone.start_date
-            %span.bold= milestone.start_date.to_s(:medium)
+            %span.bold= milestone.start_date.to_fs(:medium)
           - else
             %span.no-value= s_('MilestoneSidebar|No start date')
 
@@ -63,7 +63,7 @@
       .value.hide-collapsed
         %span.value-content{ data: { qa_selector: 'due_date_content' } }
           - if milestone.due_date
-            %span.bold= milestone.due_date.to_s(:medium)
+            %span.bold= milestone.due_date.to_fs(:medium)
           - else
             %span.no-value= s_('MilestoneSidebar|No due date')
         - remaining_days = remaining_days_in_words(milestone.due_date, milestone.start_date)
diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml
index 3571031fbfa51..e98dd87a3075c 100644
--- a/app/views/users/calendar_activities.html.haml
+++ b/app/views/users/calendar_activities.html.haml
@@ -1,5 +1,5 @@
 %h4.prepend-top-20
-  = html_escape(_("Contributions for %{calendar_date}")) % { calendar_date: tag.strong(@calendar_date.to_s(:medium)) }
+  = html_escape(_("Contributions for %{calendar_date}")) % { calendar_date: tag.strong(@calendar_date.to_fs(:medium)) }
 
 - if @events.any?
   %ul.bordered-list
diff --git a/config/initializers/00_deprecations.rb b/config/initializers/00_deprecations.rb
index c45f7ab7a5a96..3d6a649117609 100644
--- a/config/initializers/00_deprecations.rb
+++ b/config/initializers/00_deprecations.rb
@@ -42,7 +42,9 @@
     # https://gitlab.com/gitlab-org/gitlab/-/issues/410086
     /Using `return`, `break` or `throw` to exit a transaction block/,
     # https://gitlab.com/gitlab-org/gitlab/-/issues/414556
-    /Merging .* no longer maintain both conditions, and will be replaced by the latter in Rails 7\.0/
+    /Merging .* no longer maintain both conditions, and will be replaced by the latter in Rails 7\.0/,
+    # https://gitlab.com/gitlab-org/gitlab/-/issues/415890
+    /(Date|Time|TimeWithZone)#to_s.+ is deprecated/
   ]
 
   view_component_3_warnings = [
diff --git a/ee/app/controllers/groups/seat_usage_controller.rb b/ee/app/controllers/groups/seat_usage_controller.rb
index e6e477d882fd5..3975d7dcb855d 100644
--- a/ee/app/controllers/groups/seat_usage_controller.rb
+++ b/ee/app/controllers/groups/seat_usage_controller.rb
@@ -39,7 +39,7 @@ def redirect_to_seat_usage_tab
   end
 
   def csv_filename
-    "seat-usage-export-#{Time.current.to_s(:number)}.csv"
+    "seat-usage-export-#{Time.current.to_fs(:number)}.csv"
   end
 
   def verify_top_level_group
diff --git a/ee/app/helpers/ee/projects_helper.rb b/ee/app/helpers/ee/projects_helper.rb
index 26e4040f7fb32..ab7be46bff80d 100644
--- a/ee/app/helpers/ee/projects_helper.rb
+++ b/ee/app/helpers/ee/projects_helper.rb
@@ -322,7 +322,7 @@ def security_dashboard_pipeline_data(project)
         pipeline: {
           id: pipeline.id,
           path: pipeline_path(pipeline),
-          created_at: pipeline.created_at.to_s(:iso8601),
+          created_at: pipeline.created_at.to_fs(:iso8601),
           has_warnings: pipeline.has_security_report_ingestion_warnings?.to_s,
           has_errors: pipeline.has_security_report_ingestion_errors?.to_s,
           security_builds: {
diff --git a/ee/app/models/iteration.rb b/ee/app/models/iteration.rb
index 8c47f25d671c7..130a034f70209 100644
--- a/ee/app/models/iteration.rb
+++ b/ee/app/models/iteration.rb
@@ -177,7 +177,7 @@ def contains_digits?(query)
   end
 
   def period
-    "#{start_date.to_s(:medium)} - #{due_date.to_s(:medium)}"
+    "#{start_date.to_fs(:medium)} - #{due_date.to_fs(:medium)}"
   end
 
   def display_text
diff --git a/ee/app/presenters/epic_presenter.rb b/ee/app/presenters/epic_presenter.rb
index fbb94b644b394..f6524c37c7cb3 100644
--- a/ee/app/presenters/epic_presenter.rb
+++ b/ee/app/presenters/epic_presenter.rb
@@ -139,7 +139,7 @@ def epic_ancestors(epics)
         title: epic.title,
         url: url_builder.epic_path(epic),
         state: epic.state,
-        human_readable_end_date: epic.end_date&.to_s(:medium),
+        human_readable_end_date: epic.end_date&.to_fs(:medium),
         human_readable_timestamp: remaining_days_in_words(epic.end_date, epic.start_date)
       }
     end
diff --git a/ee/app/serializers/epic_base_entity.rb b/ee/app/serializers/epic_base_entity.rb
index de8c0bfd9751d..02a7310f2aa3c 100644
--- a/ee/app/serializers/epic_base_entity.rb
+++ b/ee/app/serializers/epic_base_entity.rb
@@ -12,7 +12,7 @@ class EpicBaseEntity < Grape::Entity
   end
   expose :group_id
   expose :human_readable_end_date, if: -> (epic, _) { epic.end_date.present? } do |epic|
-    epic.end_date&.to_s(:medium)
+    epic.end_date&.to_fs(:medium)
   end
   expose :human_readable_timestamp, if: -> (epic, _) { epic.end_date.present? || epic.start_date.present? } do |epic|
     remaining_days_in_words(epic.end_date, epic.start_date)
diff --git a/ee/app/services/groups/memberships/export_service.rb b/ee/app/services/groups/memberships/export_service.rb
index f77c9c4d707b1..52a9b6e58e523 100644
--- a/ee/app/services/groups/memberships/export_service.rb
+++ b/ee/app/services/groups/memberships/export_service.rb
@@ -23,7 +23,7 @@ def header_to_value_hash
         {
           'Username' => -> (member) { member&.user&.username },
           'Name' => -> (member) { member&.user&.name },
-          'Access granted' => -> (member) { member.created_at.to_s(:csv) },
+          'Access granted' => -> (member) { member.created_at.to_fs(:csv) },
           'Access expires' => -> (member) { member.expires_at },
           'Max role' => 'human_access',
           'Source' => -> (member) { member_source(member) }
diff --git a/ee/app/services/historical_user_data/csv_service.rb b/ee/app/services/historical_user_data/csv_service.rb
index 9c2d0d64e5df4..1337a634a2c55 100644
--- a/ee/app/services/historical_user_data/csv_service.rb
+++ b/ee/app/services/historical_user_data/csv_service.rb
@@ -22,7 +22,7 @@ def csv_builder
 
     def header_to_value_hash
       {
-        'Date' => -> (historical_datum) { historical_datum.recorded_at.utc.to_s(:csv) },
+        'Date' => -> (historical_datum) { historical_datum.recorded_at.utc.to_fs(:csv) },
         'Billable User Count' => 'active_user_count'
       }
     end
@@ -35,10 +35,10 @@ def header_csv
       CSV.generate do |csv|
         csv << ['License Key', license.normalized_data]
         csv << ['Email', license.licensee_email]
-        csv << ['License Start Date', license.starts_at&.to_s(:csv)]
-        csv << ['License End Date', license.expires_at&.to_s(:csv)]
+        csv << ['License Start Date', license.starts_at&.to_fs(:csv)]
+        csv << ['License End Date', license.expires_at&.to_fs(:csv)]
         csv << ['Company', license.licensee_company]
-        csv << ['Generated At', Time.current.utc.to_s(:csv)]
+        csv << ['Generated At', Time.current.utc.to_fs(:csv)]
         csv << ['', '']
       end
     end
diff --git a/ee/app/views/admin/users/_credit_card_info.html.haml b/ee/app/views/admin/users/_credit_card_info.html.haml
index 6c0c4eeaa7739..e5239672341be 100644
--- a/ee/app/views/admin/users/_credit_card_info.html.haml
+++ b/ee/app/views/admin/users/_credit_card_info.html.haml
@@ -16,7 +16,7 @@
         - else
           %span.light= _('Validated at:')
           %strong
-            = credit_card_validation.credit_card_validated_at.to_s(:medium)
+            = credit_card_validation.credit_card_validated_at.to_fs(:medium)
 
       - if credit_card_validation&.holder_name
         %li
diff --git a/ee/app/views/admin/users/card_match.html.haml b/ee/app/views/admin/users/card_match.html.haml
index a21f77fc85189..11430af05ef24 100644
--- a/ee/app/views/admin/users/card_match.html.haml
+++ b/ee/app/views/admin/users/card_match.html.haml
@@ -36,10 +36,10 @@
             %td
               = credit_card_validation.holder_name
             %td.gl-text-right
-              = validated_at.to_s(:medium)
+              = validated_at.to_fs(:medium)
               \/
               = validated_at.in_time_zone(stripe_time_zone).strftime(stripe_time_format)
-            %td.gl-text-right= user.created_at.to_s(:medium)
+            %td.gl-text-right= user.created_at.to_fs(:medium)
             %td.gl-text-right
               - if user.current_sign_in_ip
                 = user.current_sign_in_ip
diff --git a/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml b/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml
index e215844a0ee61..16d9e763e98be 100644
--- a/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml
+++ b/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml
@@ -5,7 +5,7 @@
   %li
     = @token.name
   %li
-    = _("Created on %{created_at}") % { created_at: @token.created_at.to_date.to_s(:medium) }
+    = _("Created on %{created_at}") % { created_at: @token.created_at.to_date.to_fs(:medium) }
   - if @token.last_used_at
     %li
       = _("Last used %{last_used_at} ago") % { last_used_at: time_ago_in_words(@token.last_used_at) }
diff --git a/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.text.haml b/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.text.haml
index 4311ec85ec6ae..84b72f1415a64 100644
--- a/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.text.haml
+++ b/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.text.haml
@@ -2,7 +2,7 @@
 
 = @token.name
 
-= _("Created on %{created_at}") % { created_at: @token.created_at.to_date.to_s(:medium) }
+= _("Created on %{created_at}") % { created_at: @token.created_at.to_date.to_fs(:medium) }
 
 - if @token.last_used_at
   = _("Last used %{last_used_at} ago") % { last_used_at: time_ago_in_words(@token.last_used_at) }
diff --git a/ee/app/views/credentials_inventory_mailer/ssh_key_deleted_email.html.haml b/ee/app/views/credentials_inventory_mailer/ssh_key_deleted_email.html.haml
index 0f149fa20fbae..0ab2935455bd1 100644
--- a/ee/app/views/credentials_inventory_mailer/ssh_key_deleted_email.html.haml
+++ b/ee/app/views/credentials_inventory_mailer/ssh_key_deleted_email.html.haml
@@ -5,7 +5,7 @@
   %li
     = @params[:title]
   %li
-    = _("Created on %{created_at}") % { created_at: @params[:created_at].to_date.to_s(:medium) }
+    = _("Created on %{created_at}") % { created_at: @params[:created_at].to_date.to_fs(:medium) }
   - if @params[:last_used_at]
     %li
       = _("Last used %{last_used_at} ago") % { last_used_at: time_ago_in_words(@params[:last_used_at]) }
diff --git a/ee/app/views/credentials_inventory_mailer/ssh_key_deleted_email.text.haml b/ee/app/views/credentials_inventory_mailer/ssh_key_deleted_email.text.haml
index 1b31d4e3b0432..13bab44b668b6 100644
--- a/ee/app/views/credentials_inventory_mailer/ssh_key_deleted_email.text.haml
+++ b/ee/app/views/credentials_inventory_mailer/ssh_key_deleted_email.text.haml
@@ -2,7 +2,7 @@
 
 = @params[:title]
 
-= _("Created on %{created_at}") % { created_at: @params[:created_at].to_date.to_s(:medium) }
+= _("Created on %{created_at}") % { created_at: @params[:created_at].to_date.to_fs(:medium) }
 
 - if @params[:last_used_at]
   = _("Last used %{last_used_at} ago") % { last_used_at: time_ago_in_words(@params[:last_used_at]) }
diff --git a/ee/app/views/shared/billings/_eoa_bronze_plan_banner.html.haml b/ee/app/views/shared/billings/_eoa_bronze_plan_banner.html.haml
index cef0787e71ebf..ecf01286d992c 100644
--- a/ee/app/views/shared/billings/_eoa_bronze_plan_banner.html.haml
+++ b/ee/app/views/shared/billings/_eoa_bronze_plan_banner.html.haml
@@ -6,4 +6,4 @@
                                dismiss_endpoint: callouts_path }}) do |c|
       - c.with_body do
         - announcement_link = external_link("announcement blog", "https://about.gitlab.com/blog/2021/01/26/new-gitlab-product-subscription-model")
-        = s_("BillingPlans|While GitLab is ending availability of the Bronze plan, you can still renew your Bronze subscription one additional time before %{eoa_bronze_plan_end_date}. We are also offering a limited time free upgrade to our Premium Plan (up to 25 users)! Learn more about the changes and offers in our %{announcement_link}.").html_safe % { announcement_link: announcement_link, eoa_bronze_plan_end_date: eoa_bronze_plan_end_date.in_time_zone.to_date.to_s(:medium) }
+        = s_("BillingPlans|While GitLab is ending availability of the Bronze plan, you can still renew your Bronze subscription one additional time before %{eoa_bronze_plan_end_date}. We are also offering a limited time free upgrade to our Premium Plan (up to 25 users)! Learn more about the changes and offers in our %{announcement_link}.").html_safe % { announcement_link: announcement_link, eoa_bronze_plan_end_date: eoa_bronze_plan_end_date.in_time_zone.to_date.to_fs(:medium) }
diff --git a/ee/lib/gitlab/usage/metrics/instrumentations/count_secure_pipelines_metric.rb b/ee/lib/gitlab/usage/metrics/instrumentations/count_secure_pipelines_metric.rb
index 4f9ac7d2c738a..d59e2cd23d71b 100644
--- a/ee/lib/gitlab/usage/metrics/instrumentations/count_secure_pipelines_metric.rb
+++ b/ee/lib/gitlab/usage/metrics/instrumentations/count_secure_pipelines_metric.rb
@@ -80,8 +80,8 @@ def inner_relation
           def outer_relation
             ::Security::Scan
               .from("generate_series(
-                                '#{time_constraints.values[0].first.to_time.to_s(:db)}'::timestamp,
-                                '#{time_constraints.values[0].last.to_time.to_s(:db)}'::timestamp,
+                                '#{time_constraints.values[0].first.to_time.to_fs(:db)}'::timestamp,
+                                '#{time_constraints.values[0].last.to_time.to_fs(:db)}'::timestamp,
                                 '1 day'::interval) date_range_source")
           end
 
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_builds_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_builds_metric_spec.rb
index 00404d5a03bc7..608582e36df9c 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_builds_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_builds_metric_spec.rb
@@ -99,8 +99,8 @@
   end
 
   context 'with time_frame 28d' do
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) { "SELECT COUNT(\"#{builds_table_name}\".\"id\") FROM \"#{builds_table_name}\" WHERE \"#{builds_table_name}\".\"type\" = 'Ci::Build' AND \"#{builds_table_name}\".\"created_at\" BETWEEN '#{start}' AND '#{finish}' AND \"#{builds_table_name}\".\"name\" = '#{secure_type}'" }
 
     it_behaves_like 'a correct secure type instrumented metric value', { time_frame: '28d', expected_value: 1 }
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_environments_approval_required_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_environments_approval_required_spec.rb
index 05827d8f48c62..17686365bfd05 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_environments_approval_required_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_environments_approval_required_spec.rb
@@ -42,8 +42,8 @@
       create_list(:protected_environment_approval_rule, 2, :maintainer_access, created_at: 3.days.ago)
     end
 
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
 
     let(:expected_value) { 2 }
     let(:expected_query) do
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_deployment_approvals_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_deployment_approvals_metric_spec.rb
index e81a22bf30f66..347af12c8dbf1 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_deployment_approvals_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_deployment_approvals_metric_spec.rb
@@ -16,8 +16,8 @@
     let_it_be(:old_deployment_approval) { create(:deployment_approval, created_at: 30.days.ago) }
     let_it_be(:deployment_approvals) { create_list(:deployment_approval, 2, created_at: 2.days.ago) }
 
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
 
     let(:expected_value) { 2 }
     let(:expected_query) do
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_groups_with_assigned_security_policy_project_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_groups_with_assigned_security_policy_project_metric_spec.rb
index 3ed55f7a83cfb..87d911ef762b9 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_groups_with_assigned_security_policy_project_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_groups_with_assigned_security_policy_project_metric_spec.rb
@@ -21,8 +21,8 @@
 
   it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d', data_source: 'database' } do
     let(:expected_value) { 1 }
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) do
       "SELECT COUNT(DISTINCT \"security_orchestration_policy_configurations\".\"namespace_id\") " \
         "FROM \"security_orchestration_policy_configurations\" " \
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_merge_requests_with_applied_scan_result_policies_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_merge_requests_with_applied_scan_result_policies_metric_spec.rb
index ea895f0a34899..1ae1c77d57613 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_merge_requests_with_applied_scan_result_policies_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_merge_requests_with_applied_scan_result_policies_metric_spec.rb
@@ -23,8 +23,8 @@
 
   it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d', data_source: 'database' } do
     let(:expected_value) { 1 }
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) do
       "SELECT COUNT(DISTINCT \"approval_merge_request_rules\".\"merge_request_id\") " \
         "FROM \"approval_merge_request_rules\" WHERE \"approval_merge_request_rules\".\"report_type\" = 4 " \
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_applied_scan_result_policies_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_applied_scan_result_policies_metric_spec.rb
index 31babb246bf08..5c2e296331ca5 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_applied_scan_result_policies_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_applied_scan_result_policies_metric_spec.rb
@@ -25,8 +25,8 @@
 
   it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d', data_source: 'database' } do
     let(:expected_value) { 1 }
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) do
       "SELECT COUNT(DISTINCT \"approval_project_rules\".\"project_id\") FROM \"approval_project_rules\" " \
         "WHERE \"approval_project_rules\".\"report_type\" = 4 " \
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_assigned_security_policy_project_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_assigned_security_policy_project_metric_spec.rb
index d2aade60216e6..01c5649e82da3 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_assigned_security_policy_project_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_assigned_security_policy_project_metric_spec.rb
@@ -21,8 +21,8 @@
 
   it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d', data_source: 'database' } do
     let(:expected_value) { 1 }
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) do
       "SELECT COUNT(DISTINCT \"security_orchestration_policy_configurations\".\"project_id\") " \
         "FROM \"security_orchestration_policy_configurations\" " \
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_secure_pipelines_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_secure_pipelines_metric_spec.rb
index cda69c558e0d6..60a1cb70080d0 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_secure_pipelines_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_secure_pipelines_metric_spec.rb
@@ -109,8 +109,8 @@
 
   ::Security::Scan.scan_types.except('cluster_image_scanning').each do |name, scan_type|
     context "with scan_type #{name}" do
-      let(:start) { 30.days.ago.to_s(:db) }
-      let(:finish) { 2.days.ago.to_s(:db) }
+      let(:start) { 30.days.ago.to_fs(:db) }
+      let(:finish) { 2.days.ago.to_fs(:db) }
       let(:expected_query) do
         %{SELECT COUNT(DISTINCT "security_scans"."pipeline_id") FROM "security_scans" WHERE "security_scans"."created_at" BETWEEN '#{start}' AND '#{finish}' AND "security_scans"."scan_type" = #{scan_type}} # rubocop:disable Layout/LineLength
       end
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_security_scans_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_security_scans_metric_spec.rb
index 6f19a56ef739d..2d453af1afaae 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_security_scans_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_security_scans_metric_spec.rb
@@ -36,8 +36,8 @@
   end
 
   context 'with time_frame 28d' do
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
 
     it_behaves_like 'a correct secure type instrumented metric value', { time_frame: '28d', expected_value: 1 }
   end
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_for_projects_with_applied_scan_result_policies_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_for_projects_with_applied_scan_result_policies_metric_spec.rb
index 9ba5c341fa051..026b73061ea24 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_for_projects_with_applied_scan_result_policies_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_for_projects_with_applied_scan_result_policies_metric_spec.rb
@@ -60,8 +60,8 @@
 
   it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d', data_source: 'database' } do
     let(:expected_value) { 1 }
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) do
       "SELECT COUNT(DISTINCT \"merge_requests\".\"author_id\") FROM \"merge_requests\" " \
         "INNER JOIN security_orchestration_policy_configurations " \
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_with_applied_scan_result_policies_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_with_applied_scan_result_policies_metric_spec.rb
index 4d17e844cd91e..e91402aabbbf3 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_with_applied_scan_result_policies_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_with_applied_scan_result_policies_metric_spec.rb
@@ -46,8 +46,8 @@
 
   it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d', data_source: 'database' } do
     let(:expected_value) { 1 }
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) do
       "SELECT COUNT(DISTINCT \"merge_requests\".\"author_id\") FROM \"merge_requests\" " \
         "INNER JOIN \"approval_merge_request_rules\" " \
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_ci_builds_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_ci_builds_metric_spec.rb
index 61f9d76950b9f..22f14db4f3280 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_ci_builds_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_ci_builds_metric_spec.rb
@@ -113,8 +113,8 @@
   end
 
   context 'with time_frame 28d' do
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) { "SELECT COUNT(DISTINCT \"#{builds_table_name}\".\"user_id\") FROM \"#{builds_table_name}\" WHERE \"#{builds_table_name}\".\"type\" = 'Ci::Build' AND \"#{builds_table_name}\".\"created_at\" BETWEEN '#{start}' AND '#{finish}' AND \"#{builds_table_name}\".\"name\" = '#{secure_type}'" }
 
     it_behaves_like 'a correct secure type instrumented metric value', { time_frame: '28d', expected_value: 1 }
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environment_approval_rules_required_approvals_average_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environment_approval_rules_required_approvals_average_metric_spec.rb
index 7d2e9dae34778..d5cc00e461a70 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environment_approval_rules_required_approvals_average_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environment_approval_rules_required_approvals_average_metric_spec.rb
@@ -9,8 +9,8 @@
   let_it_be(:rule_for_developer_within_timeframe) { create(:protected_environment_approval_rule, :developer_access, required_approvals: 1, created_at: 3.days.ago) }
   # rubocop:enable Layout/LineLength
 
-  let(:start) { 30.days.ago.to_s(:db) }
-  let(:finish) { 2.days.ago.to_s(:db) }
+  let(:start) { 30.days.ago.to_fs(:db) }
+  let(:finish) { 2.days.ago.to_fs(:db) }
 
   let(:expected_value) { 1.5 }
   let(:expected_query) do
diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environments_required_approvals_average_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environments_required_approvals_average_metric_spec.rb
index 81ecf2708d63f..436f6601d3dd2 100644
--- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environments_required_approvals_average_metric_spec.rb
+++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/protected_environments_required_approvals_average_metric_spec.rb
@@ -11,8 +11,8 @@
     create(:protected_environment, :staging, required_approval_count: 1, created_at: 3.days.ago)
   end
 
-  let(:start) { 30.days.ago.to_s(:db) }
-  let(:finish) { 2.days.ago.to_s(:db) }
+  let(:start) { 30.days.ago.to_fs(:db) }
+  let(:finish) { 2.days.ago.to_fs(:db) }
 
   let(:expected_value) { 1.5 }
   let(:expected_query) do
diff --git a/ee/spec/mailers/credentials_inventory_mailer_spec.rb b/ee/spec/mailers/credentials_inventory_mailer_spec.rb
index 7c89935b9e23c..a288a9ce0ab54 100644
--- a/ee/spec/mailers/credentials_inventory_mailer_spec.rb
+++ b/ee/spec/mailers/credentials_inventory_mailer_spec.rb
@@ -15,7 +15,7 @@
     it { is_expected.to have_subject 'Your Personal Access Token was revoked' }
     it { is_expected.to have_body_text 'The following Personal Access Token was revoked by an administrator, Revoker' }
     it { is_expected.to have_body_text token.name }
-    it { is_expected.to have_body_text "Created on #{token.created_at.to_date.to_s(:medium)}" }
+    it { is_expected.to have_body_text "Created on #{token.created_at.to_date.to_fs(:medium)}" }
     it { is_expected.to have_body_text 'Scopes: api, sudo' }
     it { is_expected.to be_delivered_to [token.user.notification_email_or_default] }
     it { is_expected.to have_body_text 'Last used 21 days ago' }
@@ -39,7 +39,7 @@
     it { is_expected.to have_body_text 'The following SSH key was deleted by an administrator, Revoker' }
     it { is_expected.to be_delivered_to [ssh_key.user.notification_email_or_default] }
     it { is_expected.to have_body_text ssh_key.title }
-    it { is_expected.to have_body_text "Created on #{ssh_key.created_at.to_date.to_s(:medium)}" }
+    it { is_expected.to have_body_text "Created on #{ssh_key.created_at.to_date.to_fs(:medium)}" }
     it { is_expected.to have_body_text 'Last used 21 days ago' }
   end
 end
diff --git a/ee/spec/services/analytics/cycle_analytics/consistency_check_service_spec.rb b/ee/spec/services/analytics/cycle_analytics/consistency_check_service_spec.rb
index d3c852a4568f1..c7418731d518c 100644
--- a/ee/spec/services/analytics/cycle_analytics/consistency_check_service_spec.rb
+++ b/ee/spec/services/analytics/cycle_analytics/consistency_check_service_spec.rb
@@ -63,8 +63,8 @@
             last_processed_event = initial_events[i]
 
             expect(response.payload[:cursor]).to eq({
-              'start_event_timestamp' => last_processed_event.start_event_timestamp.to_s(:inspect),
-              'end_event_timestamp' => last_processed_event.end_event_timestamp&.to_s(:inspect),
+              'start_event_timestamp' => last_processed_event.start_event_timestamp.to_fs(:inspect),
+              'end_event_timestamp' => last_processed_event.end_event_timestamp&.to_fs(:inspect),
               event_model.issuable_id_column.to_s => last_processed_event[event_model.issuable_id_column].to_s
             })
 
diff --git a/ee/spec/services/historical_user_data/csv_service_spec.rb b/ee/spec/services/historical_user_data/csv_service_spec.rb
index f6031507b6536..c778dc66ff638 100644
--- a/ee/spec/services/historical_user_data/csv_service_spec.rb
+++ b/ee/spec/services/historical_user_data/csv_service_spec.rb
@@ -57,7 +57,7 @@
       end
 
       it 'shows the license start date' do
-        expect(csv[2][1]).to eq(license_start_date.to_s(:csv))
+        expect(csv[2][1]).to eq(license_start_date.to_fs(:csv))
       end
     end
 
@@ -67,7 +67,7 @@
       end
 
       it 'shows the license end date' do
-        expect(csv[3][1]).to eq(license_end_date.to_s(:csv))
+        expect(csv[3][1]).to eq(license_end_date.to_fs(:csv))
       end
     end
 
@@ -87,7 +87,7 @@
       end
 
       it 'shows the CSV generation time' do
-        expect(csv[5][1]).to eq(datetime.utc.to_s(:csv))
+        expect(csv[5][1]).to eq(datetime.utc.to_fs(:csv))
       end
     end
   end
@@ -114,11 +114,11 @@
 
     it 'includes proper values for each column type', :aggregate_failures do
       expect(csv[8]).to contain_exactly(
-        historical_datum.recorded_at.utc.to_s(:csv),
+        historical_datum.recorded_at.utc.to_fs(:csv),
         historical_datum.active_user_count.to_s
       )
       expect(csv[9]).to contain_exactly(
-        historical_datum2.recorded_at.utc.to_s(:csv),
+        historical_datum2.recorded_at.utc.to_fs(:csv),
         historical_datum2.active_user_count.to_s
       )
     end
diff --git a/ee/spec/workers/gitlab_subscriptions/refresh_seats_worker_spec.rb b/ee/spec/workers/gitlab_subscriptions/refresh_seats_worker_spec.rb
index c0489a696430c..c1e93ab9a84c4 100644
--- a/ee/spec/workers/gitlab_subscriptions/refresh_seats_worker_spec.rb
+++ b/ee/spec/workers/gitlab_subscriptions/refresh_seats_worker_spec.rb
@@ -107,7 +107,7 @@
           namespace: create(:namespace, :with_namespace_settings),
           seats: 11,
           max_seats_used: 11,
-          last_seat_refresh_at: 1.hour.ago.to_s(:db)
+          last_seat_refresh_at: 1.hour.ago.to_fs(:db)
         )
       end
 
diff --git a/lib/gitlab/pagination/keyset/order.rb b/lib/gitlab/pagination/keyset/order.rb
index 0d8e4ea6fee2c..e31e83c90daeb 100644
--- a/lib/gitlab/pagination/keyset/order.rb
+++ b/lib/gitlab/pagination/keyset/order.rb
@@ -98,7 +98,7 @@ def cursor_attributes_for_node(node)
             hash[column_definition.attribute_name] = if field_value.is_a?(Time)
                                                        # use :inspect formatter to provide specific timezone info
                                                        # eg 2022-07-05 21:57:56.041499000 +0800
-                                                       field_value.to_s(:inspect)
+                                                       field_value.to_fs(:inspect)
                                                      elsif field_value.nil?
                                                        nil
                                                      elsif lower_named_function?(column_definition)
diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb
index fe4b80e12fead..feebdd972aa7f 100644
--- a/spec/controllers/groups/group_members_controller_spec.rb
+++ b/spec/controllers/groups/group_members_controller_spec.rb
@@ -234,7 +234,7 @@
         it 'returns correct json response' do
           expect(json_response).to eq({
             "expires_soon" => false,
-            "expires_at_formatted" => expiry_date.to_time.in_time_zone.to_s(:medium)
+            "expires_at_formatted" => expiry_date.to_time.in_time_zone.to_fs(:medium)
           })
         end
       end
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index ad49529b4262a..9657cf33afd87 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -320,7 +320,7 @@
           it 'returns correct json response' do
             expect(json_response).to eq({
               "expires_soon" => false,
-              "expires_at_formatted" => expiry_date.to_time.in_time_zone.to_s(:medium)
+              "expires_at_formatted" => expiry_date.to_time.in_time_zone.to_fs(:medium)
             })
           end
         end
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index d4148717f0a64..57183b2e8d91d 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -159,7 +159,7 @@
         click_button 'Create issue'
 
         page.within '.issuable-sidebar' do
-          expect(page).to have_content date.to_s(:medium)
+          expect(page).to have_content date.to_fs(:medium)
         end
       end
     end
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index 7e54580b0851b..47c532c396313 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -82,7 +82,7 @@
           click_button _('Save changes')
 
           page.within '.issuable-sidebar' do
-            expect(page).to have_content date.to_s(:medium)
+            expect(page).to have_content date.to_fs(:medium)
           end
         end
 
diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
index 44660b247a163..d237faba66381 100644
--- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
@@ -39,7 +39,7 @@ def assert_env_widget(text, env_name)
         wait_for_requests
 
         assert_env_widget("Deployed to", environment.name)
-        expect(find('.js-deploy-time')['title']).to eq(deployment.created_at.to_time.in_time_zone.to_s(:medium))
+        expect(find('.js-deploy-time')['title']).to eq(deployment.created_at.to_time.in_time_zone.to_fs(:medium))
       end
 
       context 'when a user created a new merge request with the same SHA' do
diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb
index ffaffa251d1f3..a2b8ee061bb31 100644
--- a/spec/helpers/issuables_helper_spec.rb
+++ b/spec/helpers/issuables_helper_spec.rb
@@ -666,9 +666,11 @@
 
   describe '#sidebar_milestone_tooltip_label' do
     it 'escapes HTML in the milestone title' do
-      milestone = build(:milestone, title: '&lt;img onerror=alert(1)&gt;')
+      milestone = build(:milestone, title: '&lt;img onerror=alert(1)&gt;', due_date: Date.new(2022, 6, 26))
 
-      expect(helper.sidebar_milestone_tooltip_label(milestone)).to eq('&lt;img onerror=alert(1)&gt;<br/>Milestone')
+      expect(helper.sidebar_milestone_tooltip_label(milestone)).to eq(
+        '&lt;img onerror=alert(1)&gt;<br/>Jun 26, 2022 (<strong>Past due</strong>)'
+      )
     end
   end
 
diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb
index b14789fd5d235..43500d985917f 100644
--- a/spec/helpers/page_layout_helper_spec.rb
+++ b/spec/helpers/page_layout_helper_spec.rb
@@ -270,7 +270,7 @@
 
       it 'merges the status properties with the defaults' do
         is_expected.to eq({
-          current_clear_status_after: time.to_s(:iso8601),
+          current_clear_status_after: time.to_fs(:iso8601),
           current_availability: 'busy',
           current_emoji: 'basketball',
           current_message: 'Some message',
diff --git a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
index 773df9b20eeff..56fef37f93996 100644
--- a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
+++ b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
@@ -104,7 +104,7 @@ def decoded_cursor(cursor)
         let(:nodes) { Project.all.order(Gitlab::Pagination::Keyset::Order.build([column_order_updated_at, column_order_created_at, column_order_id])) }
 
         it 'returns the encoded value of the order' do
-          expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.to_s(:inspect))
+          expect(decoded_cursor(cursor)).to include('updated_at' => project.updated_at.to_fs(:inspect))
         end
       end
     end
diff --git a/spec/lib/gitlab/pagination/keyset/iterator_spec.rb b/spec/lib/gitlab/pagination/keyset/iterator_spec.rb
index eee743c5e48c1..afaad48d363e8 100644
--- a/spec/lib/gitlab/pagination/keyset/iterator_spec.rb
+++ b/spec/lib/gitlab/pagination/keyset/iterator_spec.rb
@@ -87,7 +87,7 @@
         time = Time.current
 
         iterator.each_batch(of: 2) do |relation|
-          Issue.connection.execute("UPDATE issues SET updated_at = '#{time.to_s(:inspect)}' WHERE id IN (#{relation.reselect(:id).to_sql})")
+          Issue.connection.execute("UPDATE issues SET updated_at = '#{time.to_fs(:inspect)}' WHERE id IN (#{relation.reselect(:id).to_sql})")
         end
 
         expect(Issue.pluck(:updated_at)).to all(be_within(5.seconds).of(time))
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_bulk_imports_entities_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_bulk_imports_entities_metric_spec.rb
index 317929f77e685..eee5396bdbf52 100644
--- a/spec/lib/gitlab/usage/metrics/instrumentations/count_bulk_imports_entities_metric_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_bulk_imports_entities_metric_spec.rb
@@ -30,8 +30,8 @@
 
     context 'for 28d time frame' do
       let(:expected_value) { 6 }
-      let(:start) { 30.days.ago.to_s(:db) }
-      let(:finish) { 2.days.ago.to_s(:db) }
+      let(:start) { 30.days.ago.to_fs(:db) }
+      let(:finish) { 2.days.ago.to_fs(:db) }
       let(:expected_query) do
         "SELECT COUNT(\"bulk_import_entities\".\"id\") FROM \"bulk_import_entities\""\
         " WHERE \"bulk_import_entities\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'"
@@ -63,8 +63,8 @@
 
     context 'for 28d time frame' do
       let(:expected_value) { 3 }
-      let(:start) { 30.days.ago.to_s(:db) }
-      let(:finish) { 2.days.ago.to_s(:db) }
+      let(:start) { 30.days.ago.to_fs(:db) }
+      let(:finish) { 2.days.ago.to_fs(:db) }
       let(:expected_query) do
         "SELECT COUNT(\"bulk_import_entities\".\"id\") FROM \"bulk_import_entities\""\
         " WHERE \"bulk_import_entities\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'"\
@@ -92,8 +92,8 @@
 
     context 'for 28d time frame' do
       let(:expected_value) { 3 }
-      let(:start) { 30.days.ago.to_s(:db) }
-      let(:finish) { 2.days.ago.to_s(:db) }
+      let(:start) { 30.days.ago.to_fs(:db) }
+      let(:finish) { 2.days.ago.to_fs(:db) }
       let(:expected_query) do
         "SELECT COUNT(\"bulk_import_entities\".\"id\") FROM \"bulk_import_entities\""\
         " WHERE \"bulk_import_entities\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'"\
@@ -121,8 +121,8 @@
 
     context 'for 28d time frame' do
       let(:expected_value) { 4 }
-      let(:start) { 30.days.ago.to_s(:db) }
-      let(:finish) { 2.days.ago.to_s(:db) }
+      let(:start) { 30.days.ago.to_fs(:db) }
+      let(:finish) { 2.days.ago.to_fs(:db) }
       let(:expected_query) do
         "SELECT COUNT(\"bulk_import_entities\".\"id\") FROM \"bulk_import_entities\""\
         " WHERE \"bulk_import_entities\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'"\
@@ -150,8 +150,8 @@
 
     context 'for 28d time frame' do
       let(:expected_value) { 2 }
-      let(:start) { 30.days.ago.to_s(:db) }
-      let(:finish) { 2.days.ago.to_s(:db) }
+      let(:start) { 30.days.ago.to_fs(:db) }
+      let(:finish) { 2.days.ago.to_fs(:db) }
       let(:expected_query) do
         "SELECT COUNT(\"bulk_import_entities\".\"id\") FROM \"bulk_import_entities\""\
         " WHERE \"bulk_import_entities\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'"\
@@ -202,8 +202,8 @@
 
     context 'for 28d time frame' do
       let(:expected_value) { 3 }
-      let(:start) { 30.days.ago.to_s(:db) }
-      let(:finish) { 2.days.ago.to_s(:db) }
+      let(:start) { 30.days.ago.to_fs(:db) }
+      let(:finish) { 2.days.ago.to_fs(:db) }
       let(:expected_query) do
         "SELECT COUNT(\"bulk_import_entities\".\"id\") FROM \"bulk_import_entities\" " \
           "WHERE \"bulk_import_entities\".\"created_at\" BETWEEN '#{start}' AND '#{finish}' " \
@@ -249,8 +249,8 @@
     context 'for 28d time frame' do
       context 'with project entity' do
         let(:expected_value) { 2 }
-        let(:start) { 30.days.ago.to_s(:db) }
-        let(:finish) { 2.days.ago.to_s(:db) }
+        let(:start) { 30.days.ago.to_fs(:db) }
+        let(:finish) { 2.days.ago.to_fs(:db) }
         let(:expected_query) do
           "SELECT COUNT(\"bulk_import_entities\".\"id\") FROM \"bulk_import_entities\" " \
             "WHERE \"bulk_import_entities\".\"created_at\" BETWEEN '#{start}' AND '#{finish}' " \
@@ -265,8 +265,8 @@
 
       context 'with group entity' do
         let(:expected_value) { 2 }
-        let(:start) { 30.days.ago.to_s(:db) }
-        let(:finish) { 2.days.ago.to_s(:db) }
+        let(:start) { 30.days.ago.to_fs(:db) }
+        let(:finish) { 2.days.ago.to_fs(:db) }
         let(:expected_query) do
           "SELECT COUNT(\"bulk_import_entities\".\"id\") FROM \"bulk_import_entities\" " \
             "WHERE \"bulk_import_entities\".\"created_at\" BETWEEN '#{start}' AND '#{finish}' " \
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_metric_spec.rb
index b7da9b27e1943..8ae64e8db2346 100644
--- a/spec/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_metric_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_metric_spec.rb
@@ -43,8 +43,8 @@
 
     context 'for 28d time frame' do
       let(:expected_value) { 3 }
-      let(:start) { 30.days.ago.to_s(:db) }
-      let(:finish) { 2.days.ago.to_s(:db) }
+      let(:start) { 30.days.ago.to_fs(:db) }
+      let(:finish) { 2.days.ago.to_fs(:db) }
       let(:expected_query) do
         "SELECT COUNT(\"projects\".\"id\") FROM \"projects\" WHERE \"projects\".\"created_at\""\
         " BETWEEN '#{start}' AND '#{finish}' AND \"projects\".\"import_type\" = 'gitea'"
@@ -70,8 +70,8 @@
 
     context 'for 28d time frame' do
       let(:expected_value) { 2 }
-      let(:start) { 30.days.ago.to_s(:db) }
-      let(:finish) { 2.days.ago.to_s(:db) }
+      let(:start) { 30.days.ago.to_fs(:db) }
+      let(:finish) { 2.days.ago.to_fs(:db) }
       let(:expected_query) do
         "SELECT COUNT(\"projects\".\"id\") FROM \"projects\" WHERE \"projects\".\"created_at\""\
         " BETWEEN '#{start}' AND '#{finish}' AND \"projects\".\"import_type\" = 'bitbucket'"
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_total_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_total_metric_spec.rb
index bfc4240def69d..bd432b614e7e8 100644
--- a/spec/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_total_metric_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_imported_projects_total_metric_spec.rb
@@ -45,8 +45,8 @@
 
   context 'for 28d time frame' do
     let(:expected_value) { 8 }
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) do
       "SELECT (SELECT COUNT(\"projects\".\"id\") FROM \"projects\" WHERE \"projects\".\"import_type\""\
       " IN ('gitlab_project', 'gitlab', 'github', 'bitbucket', 'bitbucket_server', 'gitea', 'git', 'manifest',"\
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_issues_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_issues_metric_spec.rb
index 3fb4c3a4e3fcb..86aa37b494a21 100644
--- a/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_issues_metric_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_issues_metric_spec.rb
@@ -16,8 +16,8 @@
 
   context 'for 28d time frame' do
     let(:expected_value) { 1 }
-    let(:start) { 30.days.ago.to_s(:db) }
-    let(:finish) { 2.days.ago.to_s(:db) }
+    let(:start) { 30.days.ago.to_fs(:db) }
+    let(:finish) { 2.days.ago.to_fs(:db) }
     let(:expected_query) { "SELECT COUNT(DISTINCT \"issues\".\"author_id\") FROM \"issues\" WHERE \"issues\".\"created_at\" BETWEEN '#{start}' AND '#{finish}'" }
 
     it_behaves_like 'a correct instrumented metric value and query', { time_frame: '28d' }
diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb
index 46a876f34e994..01efe66a4193c 100644
--- a/spec/models/concerns/milestoneish_spec.rb
+++ b/spec/models/concerns/milestoneish_spec.rb
@@ -356,4 +356,20 @@
       expect(milestone.human_total_time_estimate).to be_nil
     end
   end
+
+  describe '#expires_at' do
+    it 'returns the date when milestone expires' do
+      due_date = Date.today + 1.day
+      milestone.due_date = due_date
+
+      expect(milestone.expires_at).to eq("expires on #{due_date.to_fs(:medium)}")
+    end
+
+    it 'returns the date when milestone expires' do
+      due_date = Date.today - 1.day
+      milestone.due_date = due_date
+
+      expect(milestone.expires_at).to eq("expired on #{due_date.to_fs(:medium)}")
+    end
+  end
 end
diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index bd09dae0a5a74..fd614fba091e5 100644
--- a/spec/services/quick_actions/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -301,7 +301,7 @@
       it 'returns due_date message: Date.new(2016, 8, 28) if content contains /due 2016-08-28' do
         _, _, message = service.execute(content, issuable)
 
-        expect(message).to eq("Set the due date to #{expected_date.to_s(:medium)}.")
+        expect(message).to eq("Set the due date to #{expected_date.to_fs(:medium)}.")
       end
     end
 
diff --git a/spec/services/system_notes/time_tracking_service_spec.rb b/spec/services/system_notes/time_tracking_service_spec.rb
index 71228050085f0..a3793880ff17d 100644
--- a/spec/services/system_notes/time_tracking_service_spec.rb
+++ b/spec/services/system_notes/time_tracking_service_spec.rb
@@ -25,7 +25,7 @@
 
       context 'when both dates are added' do
         it 'sets the correct note message' do
-          expect(note.note).to eq("changed start date to #{start_date.to_s(:long)} and changed due date to #{due_date.to_s(:long)}")
+          expect(note.note).to eq("changed start date to #{start_date.to_fs(:long)} and changed due date to #{due_date.to_fs(:long)}")
         end
       end
 
@@ -37,7 +37,7 @@
         end
 
         it 'sets the correct note message' do
-          expect(note.note).to eq("removed start date #{start_date.to_s(:long)} and removed due date #{due_date.to_s(:long)}")
+          expect(note.note).to eq("removed start date #{start_date.to_fs(:long)} and removed due date #{due_date.to_fs(:long)}")
         end
       end
 
@@ -45,14 +45,14 @@
         let(:changed_dates) { { 'due_date' => [nil, due_date] } }
 
         it 'sets the correct note message' do
-          expect(note.note).to eq("changed due date to #{due_date.to_s(:long)}")
+          expect(note.note).to eq("changed due date to #{due_date.to_fs(:long)}")
         end
 
         context 'and start date removed' do
           let(:changed_dates) { { 'due_date' => [nil, due_date], 'start_date' => [start_date, nil] } }
 
           it 'sets the correct note message' do
-            expect(note.note).to eq("removed start date #{start_date.to_s(:long)} and changed due date to #{due_date.to_s(:long)}")
+            expect(note.note).to eq("removed start date #{start_date.to_fs(:long)} and changed due date to #{due_date.to_fs(:long)}")
           end
         end
       end
@@ -73,14 +73,14 @@
         end
 
         it 'sets the correct note message' do
-          expect(note.note).to eq("changed start date to #{start_date.to_s(:long)}")
+          expect(note.note).to eq("changed start date to #{start_date.to_fs(:long)}")
         end
 
         context 'and due date removed' do
           let(:changed_dates) { { 'due_date' => [due_date, nil], 'start_date' => [nil, start_date] } }
 
           it 'sets the correct note message' do
-            expect(note.note).to eq("changed start date to #{start_date.to_s(:long)} and removed due date #{due_date.to_s(:long)}")
+            expect(note.note).to eq("changed start date to #{start_date.to_fs(:long)} and removed due date #{due_date.to_fs(:long)}")
           end
         end
       end
diff --git a/spec/services/work_items/export_csv_service_spec.rb b/spec/services/work_items/export_csv_service_spec.rb
index 948ff89245e4c..4566289231faa 100644
--- a/spec/services/work_items/export_csv_service_spec.rb
+++ b/spec/services/work_items/export_csv_service_spec.rb
@@ -61,7 +61,7 @@ def csv
   end
 
   specify 'created_at' do
-    expect(csv[0]['Created At (UTC)']).to eq(work_item_1.created_at.to_s(:csv))
+    expect(csv[0]['Created At (UTC)']).to eq(work_item_1.created_at.to_fs(:csv))
   end
 
   specify 'description' do
diff --git a/spec/support/helpers/features/iteration_helpers.rb b/spec/support/helpers/features/iteration_helpers.rb
index fab373a547f10..7ae546fb83c19 100644
--- a/spec/support/helpers/features/iteration_helpers.rb
+++ b/spec/support/helpers/features/iteration_helpers.rb
@@ -3,7 +3,7 @@
 module Features
   module IterationHelpers
     def iteration_period(iteration)
-      "#{iteration.start_date.to_s(:medium)} - #{iteration.due_date.to_s(:medium)}"
+      "#{iteration.start_date.to_fs(:medium)} - #{iteration.due_date.to_fs(:medium)}"
     end
   end
 end
diff --git a/spec/support/shared_examples/features/sidebar/sidebar_due_date_shared_examples.rb b/spec/support/shared_examples/features/sidebar/sidebar_due_date_shared_examples.rb
index 206116d66c8fe..865f5aff476ab 100644
--- a/spec/support/shared_examples/features/sidebar/sidebar_due_date_shared_examples.rb
+++ b/spec/support/shared_examples/features/sidebar/sidebar_due_date_shared_examples.rb
@@ -26,7 +26,7 @@
 
         wait_for_requests
 
-        expect(page).to have_content(today.to_s(:medium))
+        expect(page).to have_content(today.to_fs(:medium))
         expect(due_date_value.text).to have_content Time.current.strftime('%b %-d, %Y')
       end
     end
diff --git a/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb b/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb
index 6f104f400bcc6..52f0e7847b090 100644
--- a/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb
+++ b/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb
@@ -2,7 +2,7 @@
 
 RSpec.shared_examples 'StageEventModel' do
   describe '.upsert_data' do
-    let(:time) { Time.parse(Time.current.to_s(:db)) } # truncating the timestamp so we can compare it with the timestamp loaded from the DB
+    let(:time) { Time.parse(Time.current.to_fs(:db)) } # truncating the timestamp so we can compare it with the timestamp loaded from the DB
     let(:input_data) do
       [
         {
diff --git a/spec/views/profiles/show.html.haml_spec.rb b/spec/views/profiles/show.html.haml_spec.rb
index ea0a9ebb02cde..e88b1bf40533d 100644
--- a/spec/views/profiles/show.html.haml_spec.rb
+++ b/spec/views/profiles/show.html.haml_spec.rb
@@ -46,7 +46,7 @@
       )
       expect(rendered).to have_field(
         'user[status][clear_status_after]',
-        with: user_status.clear_status_at.to_s(:iso8601),
+        with: user_status.clear_status_at.to_fs(:iso8601),
         type: :hidden
       )
     end
-- 
GitLab