diff --git a/Directory.Packages.props b/Directory.Packages.props
index efaeb772e15..0eb337a8b8d 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -45,6 +45,7 @@
     
     
     
+    
     
     
     
@@ -123,4 +124,4 @@
     
     
   
-
+
\ No newline at end of file
diff --git a/src/Orleans.Runtime/Catalog/ActivationCollector.cs b/src/Orleans.Runtime/Catalog/ActivationCollector.cs
index e2b6d679226..c2647ba120c 100644
--- a/src/Orleans.Runtime/Catalog/ActivationCollector.cs
+++ b/src/Orleans.Runtime/Catalog/ActivationCollector.cs
@@ -27,23 +27,21 @@ internal partial class ActivationCollector : IActivationWorkingSetObserver, ILif
         private Task _collectionLoopTask;
         private int collectionNumber;
         private int _activationCount;
-        private readonly IOptions _options;
 
         /// 
         /// Initializes a new instance of the  class.
         /// 
-        /// The timer factory.
+        /// The time provider.
         /// The options.
         /// The logger.
         public ActivationCollector(
-            IAsyncTimerFactory timerFactory,
+            TimeProvider timeProvider,
             IOptions options,
             ILogger logger)
         {
-            _options = options;
             quantum = options.Value.CollectionQuantum;
             shortestAgeLimit = new(options.Value.ClassSpecificCollectionAge.Values.Aggregate(options.Value.CollectionAge.Ticks, (a, v) => Math.Min(a, v.Ticks)));
-            nextTicket = MakeTicketFromDateTime(DateTime.UtcNow);
+            nextTicket = MakeTicketFromDateTime(timeProvider.GetUtcNow().UtcDateTime);
             this.logger = logger;
             _collectionTimer = new PeriodicTimer(quantum);
         }
@@ -325,11 +323,17 @@ private bool IsExpired(DateTime ticket)
             return ticket < nextTicket;
         }
 
-        private DateTime MakeTicketFromDateTime(DateTime timestamp)
+        public DateTime MakeTicketFromDateTime(DateTime timestamp)
         {
             // Round the timestamp to the next quantum. e.g. if the quantum is 1 minute and the timestamp is 3:45:22, then the ticket will be 3:46.
             // Note that TimeStamp.Ticks and DateTime.Ticks both return a long.
-            var ticket = new DateTime(((timestamp.Ticks - 1) / quantum.Ticks + 1) * quantum.Ticks, DateTimeKind.Utc);
+            var ticketTicks = ((timestamp.Ticks - 1) / quantum.Ticks + 1) * quantum.Ticks;
+            if (ticketTicks > DateTime.MaxValue.Ticks)
+            {
+                return DateTime.MaxValue;
+            }
+
+            var ticket = new DateTime(ticketTicks, DateTimeKind.Utc);
             if (ticket < nextTicket)
             {
                 throw new ArgumentException(string.Format("The earliest collection that can be scheduled from now is for {0}", new DateTime(nextTicket.Ticks - quantum.Ticks + 1, DateTimeKind.Utc)));
diff --git a/test/NonSilo.Tests/NonSilo.Tests.csproj b/test/NonSilo.Tests/NonSilo.Tests.csproj
index 3868e1121e7..c139dd41679 100644
--- a/test/NonSilo.Tests/NonSilo.Tests.csproj
+++ b/test/NonSilo.Tests/NonSilo.Tests.csproj
@@ -14,6 +14,7 @@
   
 
   
+    
     
     
     
diff --git a/test/NonSilo.Tests/Runtime/ActivationCollectorTests.cs b/test/NonSilo.Tests/Runtime/ActivationCollectorTests.cs
new file mode 100644
index 00000000000..3524942e9fe
--- /dev/null
+++ b/test/NonSilo.Tests/Runtime/ActivationCollectorTests.cs
@@ -0,0 +1,60 @@
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Time.Testing;
+using Orleans.Configuration;
+using Xunit;
+
+namespace UnitTests.Runtime
+{
+    [TestCategory("BVT"), TestCategory("Runtime")]
+    public class ActivationCollectorTests
+    {
+        private readonly FakeTimeProvider timeProvider;
+        private readonly ActivationCollector collector;
+
+        public ActivationCollectorTests()
+        {
+            var grainCollectionOptions = Options.Create(new GrainCollectionOptions());
+            var logger = NullLogger.Instance;
+
+            this.timeProvider = new FakeTimeProvider(DateTimeOffset.Parse("2025-01-01T00:00:00.000+00:00"));
+            this.collector = new ActivationCollector(timeProvider, grainCollectionOptions, logger);
+        }
+
+        [Theory, TestCategory("Activation")]
+        [InlineData("2025-01-01T00:00:00", "2025-01-01T00:00:00")]
+        [InlineData("2025-01-01T00:00:01", "2025-01-01T00:01:00")]
+        [InlineData("2025-01-01T00:00:59", "2025-01-01T00:01:00")]
+        [InlineData("2025-01-01T00:01:01", "2025-01-01T00:02:00")]
+        public void MakeTicketFromDateTime(string timestampString, string expectedTicketString)
+        {
+            var timestamp = DateTime.Parse(timestampString);
+            var expectedTicket = DateTime.Parse(expectedTicketString);
+
+            var actualTicket = collector.MakeTicketFromDateTime(timestamp);
+
+            Assert.Equal(expectedTicket, actualTicket);
+        }
+
+        [Fact, TestCategory("Activation")]
+        public void MakeTicketFromDateTime_MaxValue()
+        {
+            var expectedTicket = DateTime.MaxValue;
+
+            var actualTicket = collector.MakeTicketFromDateTime(DateTime.MaxValue);
+
+            Assert.Equal(expectedTicket, actualTicket);
+        }
+
+        [Fact, TestCategory("Activation")]
+        public void MakeTicketFromDateTime_Invalid_BeforeNextTicket()
+        {
+            var timestamp = this.timeProvider.GetUtcNow().AddMinutes(-5).UtcDateTime;
+
+            Assert.Throws(() =>
+            {
+                var ticket = collector.MakeTicketFromDateTime(timestamp);
+            });
+        }
+    }
+}