diff --git a/app/finders/concerns/created_at_filter.rb b/app/finders/concerns/created_at_filter.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ac9ac77732cccc9edcdfded2e23a09d4ee1d5c07
--- /dev/null
+++ b/app/finders/concerns/created_at_filter.rb
@@ -0,0 +1,8 @@
+module CreatedAtFilter
+  def by_created_at(items)
+    items = items.created_before(params[:created_before]) if params[:created_before].present?
+    items = items.created_after(params[:created_after]) if params[:created_after].present?
+
+    items
+  end
+end
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index d81e9ed17d48cb619ce547e90ef97165ebd9975f..2e5a6493134bf6afa43900065a54796d2a37a380 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -19,6 +19,8 @@
 #     iids: integer[]
 #
 class IssuableFinder
+  include CreatedAtFilter
+  
   NONE = '0'.freeze
   IRRELEVANT_PARAMS_FOR_CACHE_KEY = %i[utf8 sort page].freeze
 
@@ -32,6 +34,7 @@ class IssuableFinder
   def execute
     items = init_collection
     items = by_scope(items)
+    items = by_created_at(items)
     items = by_state(items)
     items = by_group(items)
     items = by_search(items)
@@ -42,7 +45,6 @@ class IssuableFinder
     items = by_iids(items)
     items = by_milestone(items)
     items = by_label(items)
-    items = by_created_at(items)
 
     # Filtering by project HAS TO be the last because we use the project IDs yielded by the issuable query thus far
     items = by_project(items)
@@ -411,18 +413,6 @@ class IssuableFinder
     params[:non_archived].present? ? items.non_archived : items
   end
 
-  def by_created_at(items)
-    if params[:created_after].present?
-      items = items.where(items.klass.arel_table[:created_at].gteq(params[:created_after]))
-    end
-
-    if params[:created_before].present?
-      items = items.where(items.klass.arel_table[:created_at].lteq(params[:created_before]))
-    end
-
-    items
-  end
-
   def current_user_related?
     params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me'
   end
diff --git a/app/finders/users_finder.rb b/app/finders/users_finder.rb
index 07deceb827bb7999ac338b573729c8616eef73ed..33f7ae905987b0e415c3025af28c276ca8114254 100644
--- a/app/finders/users_finder.rb
+++ b/app/finders/users_finder.rb
@@ -14,6 +14,8 @@
 #     external: boolean
 #
 class UsersFinder
+  include CreatedAtFilter
+
   attr_accessor :current_user, :params
 
   def initialize(current_user, params = {})
@@ -29,6 +31,7 @@ class UsersFinder
     users = by_active(users)
     users = by_external_identity(users)
     users = by_external(users)
+    users = by_created_at(users)
 
     users
   end
diff --git a/app/models/concerns/created_at_filterable.rb b/app/models/concerns/created_at_filterable.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e8a3e41203d80599620a3c178ce529038034823e
--- /dev/null
+++ b/app/models/concerns/created_at_filterable.rb
@@ -0,0 +1,12 @@
+module CreatedAtFilterable
+  extend ActiveSupport::Concern
+
+  included do
+    scope :created_before, ->(date) { where(scoped_table[:created_at].lteq(date)) }
+    scope :created_after, ->(date) { where(scoped_table[:created_at].gteq(date)) }
+
+    def self.scoped_table
+      arel_table.alias(table_name)
+    end
+  end
+end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 01f985823e14d0d3c4b301a6606c2d04c72f21a2..400bb55d2f0998b4c34317bf68dd9e1e344cfc62 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -10,6 +10,7 @@ class Issue < ActiveRecord::Base
   include FasterCacheKeys
   include RelativePositioning
   include IgnorableColumn
+  include CreatedAtFilterable
 
   ignore_column :position
 
@@ -50,8 +51,6 @@ class Issue < ActiveRecord::Base
   scope :order_due_date_asc, -> { reorder('issues.due_date IS NULL, issues.due_date ASC') }
   scope :order_due_date_desc, -> { reorder('issues.due_date IS NULL, issues.due_date DESC') }
 
-  scope :created_after, -> (datetime) { where("created_at >= ?", datetime) }
-
   scope :preload_associations, -> { preload(:labels, project: :namespace) }
 
   after_save :expire_etag_cache
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 6ea774470afb5c6554992aa28b11502a0c54ec0c..30caa3598d1ca3fdea1da104f3e4e14bfc18fa2a 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -5,6 +5,7 @@ class MergeRequest < ActiveRecord::Base
   include Referable
   include Sortable
   include IgnorableColumn
+  include CreatedAtFilterable
 
   ignore_column :position
 
diff --git a/app/models/user.rb b/app/models/user.rb
index 4411a06d429b45b9451616313646c6f2d5718765..4b01c2f19f079494c680a8260c02b74a759fa87c 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -12,6 +12,7 @@ class User < ActiveRecord::Base
   include TokenAuthenticatable
   include IgnorableColumn
   include FeatureGate
+  include CreatedAtFilterable
 
   DEFAULT_NOTIFICATION_LEVEL = :participating
 
diff --git a/changelogs/unreleased/feature-user-datetime-search-api-mysql.yml b/changelogs/unreleased/feature-user-datetime-search-api-mysql.yml
new file mode 100644
index 0000000000000000000000000000000000000000..27ac50c6cc268cab3230de26343290578a275279
--- /dev/null
+++ b/changelogs/unreleased/feature-user-datetime-search-api-mysql.yml
@@ -0,0 +1,4 @@
+---
+title: Add creation time filters to user search API for admins
+merge_request: 12682
+author:
diff --git a/config/application.rb b/config/application.rb
index d88740ef8d7327d1a62c698574c631da6228b385..2f4e26241951ffc6cda954f675a1461c86af8b50 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -26,7 +26,8 @@ module Gitlab
                                      #{config.root}/app/models/members
                                      #{config.root}/app/models/project_services
                                      #{config.root}/app/workers/concerns
-                                     #{config.root}/app/services/concerns))
+                                     #{config.root}/app/services/concerns
+                                     #{config.root}/app/finders/concerns))
 
     config.generators.templates.push("#{config.root}/generator_templates")
 
diff --git a/doc/api/users.md b/doc/api/users.md
index cf09b8f44aa3e528b448fe0d9ae6aeba54a95d24..91170e79645d192db0cf85513d514b265b70a7d6 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -146,6 +146,12 @@ GET /users?extern_uid=1234567&provider=github
 
 You can search for users who are external with: `/users?external=true`
 
+You can search users by creation date time range with:
+
+```
+GET /users?created_before=2001-01-02T00:00:00.060Z&created_after=1999-01-02T00:00:00.060
+```
+
 ## Single user
 
 Get a single user.
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 88bca235692f66b10638ec0c6cf15e4057515c72..c469751c31c8419525e761f46177aba2fd74bec0 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -48,6 +48,8 @@ module API
         optional :active, type: Boolean, default: false, desc: 'Filters only active users'
         optional :external, type: Boolean, default: false, desc: 'Filters only external users'
         optional :blocked, type: Boolean, default: false, desc: 'Filters only blocked users'
+        optional :created_after, type: DateTime, desc: 'Return users created after the specified time'
+        optional :created_before, type: DateTime, desc: 'Return users created before the specified time'
         all_or_none_of :extern_uid, :provider
 
         use :pagination
@@ -55,6 +57,10 @@ module API
       get do
         authenticated_as_admin! if params[:external].present? || (params[:extern_uid].present? && params[:provider].present?)
 
+        unless current_user&.admin?
+          params.except!(:created_after, :created_before)
+        end
+
         users = UsersFinder.new(current_user, params).execute
 
         authorized = can?(current_user, :read_users_list)
diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb
index 780b309b45e2305f5e685852cb04fc8af34c8536..1bab6d6438814e1d18e38492500ad2aee01fab7a 100644
--- a/spec/finders/users_finder_spec.rb
+++ b/spec/finders/users_finder_spec.rb
@@ -45,6 +45,17 @@ describe UsersFinder do
 
         expect(users).to contain_exactly(user, user1, user2, omniauth_user)
       end
+
+      it 'filters by created_at' do
+        filtered_user_before = create(:user, created_at: 3.days.ago)
+        filtered_user_after = create(:user, created_at: Time.now + 3.days)
+
+        users = described_class.new(user,
+                                    created_after: 2.days.ago,
+                                    created_before: Time.now + 2.days).execute
+
+        expect(users.map(&:username)).not_to include([filtered_user_before.username, filtered_user_after.username])
+      end
     end
 
     context 'with an admin user' do
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 70b94a09e6b635fa7be234afb1958399c1ec6526..c34b88f07410b570c98fcc32b466042272351055 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -163,6 +163,35 @@ describe API::Users do
 
         expect(response).to have_http_status(400)
       end
+
+      it "returns a user created before a specific date" do
+        user = create(:user, created_at: Date.new(2000, 1, 1))
+
+        get api("/users?created_before=2000-01-02T00:00:00.060Z", admin)
+
+        expect(response).to have_http_status(200)
+        expect(json_response.size).to eq(1)
+        expect(json_response.first['username']).to eq(user.username)
+      end
+
+      it "returns no users created before a specific date" do
+        create(:user, created_at: Date.new(2001, 1, 1))
+
+        get api("/users?created_before=2000-01-02T00:00:00.060Z", admin)
+
+        expect(response).to have_http_status(200)
+        expect(json_response.size).to eq(0)
+      end
+
+      it "returns users created before and after a specific date" do
+        user = create(:user, created_at: Date.new(2001, 1, 1))
+
+        get api("/users?created_before=2001-01-02T00:00:00.060Z&created_after=1999-01-02T00:00:00.060", admin)
+
+        expect(response).to have_http_status(200)
+        expect(json_response.size).to eq(1)
+        expect(json_response.first['username']).to eq(user.username)
+      end
     end
   end