You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2021/07/24 19:01:54 UTC

[lucenenet] branch master updated: SWEEP: Factored out Lucene.Net.Support.Time in favor of J2N.Time. Replaced all calls (except Lucene.Net.Tests.Search.TestDateFilter) to Environment.TickCount and Time.CurrentTimeMilliseconds() to use Time.NanoTime() / Time.MillisecondsPerNanosecond for more accurate results. (fixes #492)

This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git


The following commit(s) were added to refs/heads/master by this push:
     new 1da0c5f  SWEEP: Factored out Lucene.Net.Support.Time in favor of J2N.Time. Replaced all calls (except Lucene.Net.Tests.Search.TestDateFilter) to Environment.TickCount and Time.CurrentTimeMilliseconds() to use Time.NanoTime() / Time.MillisecondsPerNanosecond for more accurate results. (fixes #492)
1da0c5f is described below

commit 1da0c5fb036ac212f543a8c754f506d3a1d4ba47
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sun Jul 11 03:34:16 2021 +0700

    SWEEP: Factored out Lucene.Net.Support.Time in favor of J2N.Time. Replaced all calls (except Lucene.Net.Tests.Search.TestDateFilter) to Environment.TickCount and Time.CurrentTimeMilliseconds() to use Time.NanoTime() / Time.MillisecondsPerNanosecond for more accurate results. (fixes #492)
---
 src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs     |  2 +-
 src/Lucene.Net.Benchmark/ByTask/Stats/TaskStats.cs |  8 ++--
 .../ByTask/Tasks/NearRealtimeReaderTask.cs         |  8 ++--
 src/Lucene.Net.Benchmark/ByTask/Tasks/PerfTask.cs  |  2 +-
 .../ByTask/Tasks/TaskSequence.cs                   | 18 ++++----
 .../Quality/QualityBenchmark.cs                    | 11 ++---
 src/Lucene.Net.Benchmark/Utils/ExtractWikipedia.cs |  4 +-
 src/Lucene.Net.Demo/Facet/RangeFacetsExample.cs    |  2 +-
 src/Lucene.Net.Replicator/LocalReplicator.cs       |  6 +--
 .../Util/ShapeFieldCacheProvider.cs                |  4 +-
 .../Suggest/Analyzing/AnalyzingInfixSuggester.cs   |  4 +-
 .../Index/ThreadedIndexingAndSearchingTestCase.cs  | 18 ++++----
 src/Lucene.Net.TestFramework/Search/QueryUtils.cs  |  4 +-
 .../Search/ShardSearchingTestBase.cs               |  4 +-
 .../Util/ThrottledIndexOutput.cs                   |  4 +-
 .../TestLucene47WordDelimiterFilter.cs             |  6 +--
 .../Miscellaneous/TestWordDelimiterFilter.cs       |  6 +--
 .../Pattern/TestPatternReplaceCharFilter.cs        | 48 +++++++++++-----------
 .../Analysis/Sinks/TestTeeSinkTokenFilter.cs       | 15 +++----
 .../TestJapaneseTokenizer.cs                       | 15 +++----
 .../ByTask/Feeds/DocMakerTest.cs                   |  2 +-
 .../ByTask/Tasks/CountingSearchTestTask.cs         |  2 +-
 .../ClassificationTestBase.cs                      |  7 ++--
 .../Spell/TestSpellChecker.cs                      |  4 +-
 src/Lucene.Net.Tests/Index/Test2BTerms.cs          |  8 ++--
 src/Lucene.Net.Tests/Index/TestAtomicUpdate.cs     |  4 +-
 .../Index/TestDocValuesWithThreads.cs              |  4 +-
 .../Index/TestDocumentsWriterStallControl.cs       |  4 +-
 .../Index/TestIndexWriterCommit.cs                 |  4 +-
 .../Index/TestIndexWriterExceptions.cs             |  6 +--
 .../Index/TestIndexWriterReader.cs                 | 12 +++---
 .../Index/TestIndexWriterWithThreads.cs            |  5 ++-
 .../Index/TestNRTReaderWithThreads.cs              |  4 +-
 src/Lucene.Net.Tests/Index/TestNRTThreads.cs       |  4 +-
 src/Lucene.Net.Tests/Index/TestNeverDelete.cs      |  6 +--
 .../Index/TestSnapshotDeletionPolicy.cs            |  4 +-
 src/Lucene.Net.Tests/Index/TestStressIndexing.cs   |  4 +-
 src/Lucene.Net.Tests/Index/TestTermdocPerf.cs      |  8 ++--
 src/Lucene.Net.Tests/Index/TestTransactions.cs     |  4 +-
 .../Search/TestControlledRealTimeReopenThread.cs   |  4 +-
 src/Lucene.Net.Tests/Search/TestDateFilter.cs      |  6 +--
 .../Search/TestMultiThreadTermVectors.cs           |  8 ++--
 src/Lucene.Net.Tests/Search/TestShardSearching.cs  |  6 +--
 src/Lucene.Net.Tests/Util/Fst/TestFSTs.cs          | 18 ++++----
 .../Util/TestDoubleBarrelLRUCache.cs               |  8 ++--
 src/Lucene.Net/Index/BufferedUpdatesStream.cs      |  6 +--
 src/Lucene.Net/Index/ConcurrentMergeScheduler.cs   |  4 +-
 src/Lucene.Net/Index/DocTermOrds.cs                |  6 +--
 src/Lucene.Net/Index/IndexFileDeleter.cs           |  4 +-
 src/Lucene.Net/Index/IndexWriter.cs                |  8 ++--
 src/Lucene.Net/Index/SegmentMerger.cs              |  4 +-
 src/Lucene.Net/Index/SimpleMergedSegmentWarmer.cs  | 11 +++--
 .../Search/ControlledRealTimeReopenThread.cs       |  9 ++--
 src/Lucene.Net/Search/SearcherLifetimeManager.cs   |  4 +-
 src/Lucene.Net/Store/RateLimiter.cs                |  2 +-
 src/Lucene.Net/Support/Time.cs                     | 35 ----------------
 src/Lucene.Net/Util/OfflineSorter.cs               | 16 ++++----
 57 files changed, 205 insertions(+), 239 deletions(-)

diff --git a/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs b/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs
index 2248443..670e72b 100644
--- a/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/PerfRunData.cs
@@ -231,7 +231,7 @@ namespace Lucene.Net.Benchmarks.ByTask
 
         public virtual long SetStartTimeMillis()
         {
-            startTimeMillis = J2N.Time.CurrentTimeMilliseconds();
+            startTimeMillis = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond;
             return startTimeMillis;
         }
 
diff --git a/src/Lucene.Net.Benchmark/ByTask/Stats/TaskStats.cs b/src/Lucene.Net.Benchmark/ByTask/Stats/TaskStats.cs
index 72fc61d..c2ff01b 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Stats/TaskStats.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Stats/TaskStats.cs
@@ -37,8 +37,8 @@ namespace Lucene.Net.Benchmarks.ByTask.Stats
         /// <summary>Round in which task run started.</summary>
         private int round;
 
-        ///// <summary>Task start time.</summary>
-        //private long start; // LUCENENET: Never read
+        /// <summary>Task start time.</summary>
+        private long start;
 
         /// <summary>Task elapsed time.  elapsed >= 0 indicates run completion!</summary>
         private long elapsed = -1;
@@ -80,7 +80,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Stats
             this.round = round;
             maxTotMem = GC.GetTotalMemory(false); //Runtime.getRuntime().totalMemory();
             maxUsedMem = maxTotMem; // - Runtime.getRuntime().freeMemory(); // LUCENENET TODO: available RAM
-            //start = Stopwatch.GetTimestamp(); // LUCENENET: Never read
+            start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
         }
 
         /// <summary>
@@ -88,7 +88,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Stats
         /// </summary>
         internal void MarkEnd(int numParallelTasks, int count)
         {
-            elapsed = J2N.Time.CurrentTimeMilliseconds();
+            elapsed = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - start; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             long totMem = GC.GetTotalMemory(false); //Runtime.getRuntime().totalMemory();
             if (totMem > maxTotMem)
             {
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/NearRealtimeReaderTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/NearRealtimeReaderTask.cs
index f51aa6d..fc0c264 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Tasks/NearRealtimeReaderTask.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/NearRealtimeReaderTask.cs
@@ -63,7 +63,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
             }
 
 
-            long t = J2N.Time.CurrentTimeMilliseconds();
+            long t = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             DirectoryReader r = DirectoryReader.Open(w, true);
             runData.SetIndexReader(r);
             // Transfer our reference to runData
@@ -76,18 +76,18 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
             reopenCount = 0;
             while (!Stop)
             {
-                long waitForMsec = (pauseMSec - (J2N.Time.CurrentTimeMilliseconds() - t));
+                long waitForMsec = (pauseMSec - ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t)); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 if (waitForMsec > 0)
                 {
                     Thread.Sleep((int)waitForMsec);
                     //System.out.println("NRT wait: " + waitForMsec + " msec");
                 }
 
-                t = J2N.Time.CurrentTimeMilliseconds();
+                t = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 DirectoryReader newReader = DirectoryReader.OpenIfChanged(r);
                 if (newReader != null)
                 {
-                    int delay = (int)(J2N.Time.CurrentTimeMilliseconds() - t);
+                    int delay = (int)((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     if (reopenTimes.Length == reopenCount)
                     {
                         reopenTimes = ArrayUtil.Grow(reopenTimes, 1 + reopenCount);
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/PerfTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/PerfTask.cs
index a85b132..8f225dc 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Tasks/PerfTask.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/PerfTask.cs
@@ -308,7 +308,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
         {
             if (++logStepCount % m_logStep == 0)
             {
-                double time = (((Stopwatch.GetTimestamp() / Stopwatch.Frequency) * 1000) - runData.StartTimeMillis) / 1000.0;
+                double time = ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - runData.StartTimeMillis) / 1000.0; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:0000000.00}", time) + " sec --> "
                     + Thread.CurrentThread.Name + " " + GetLogMessage(logStepCount));
             }
diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/TaskSequence.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/TaskSequence.cs
index 7710d22..4286163 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Tasks/TaskSequence.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/TaskSequence.cs
@@ -189,7 +189,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
             long runTime = (long)(runTimeSec * 1000);
             List<RunBackgroundTask> bgTasks = null;
 
-            long t0 = J2N.Time.CurrentTimeMilliseconds();
+            long t0 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             for (int k = 0; fixedTime || (repetitions == REPEAT_EXHAUST && !exhausted) || k < repetitions; k++)
             {
                 if (Stop)
@@ -220,7 +220,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
                             count += inc;
                             if (countsByTime != null)
                             {
-                                int slot = (int)((J2N.Time.CurrentTimeMilliseconds() - t0) / logByTimeMsec);
+                                int slot = (int)(((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0) / logByTimeMsec); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                                 if (slot >= countsByTime.Length)
                                 {
                                     countsByTime = ArrayUtil.Grow(countsByTime, 1 + slot);
@@ -236,7 +236,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
                         }
                     }
                 }
-                if (fixedTime && J2N.Time.CurrentTimeMilliseconds() - t0 > runTime)
+                if (fixedTime && (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0 > runTime) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 {
                     repetitions = k + 1;
                     break;
@@ -270,9 +270,9 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
         {
             InitTasksArray();
             long delayStep = (perMin ? 60000 : 1000) / rate;
-            long nextStartTime = J2N.Time.CurrentTimeMilliseconds();
+            long nextStartTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             int count = 0;
-            long t0 = J2N.Time.CurrentTimeMilliseconds();
+            long t0 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             for (int k = 0; (repetitions == REPEAT_EXHAUST && !exhausted) || k < repetitions; k++)
             {
                 if (Stop)
@@ -284,7 +284,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
                     PerfTask task = tasksArray[l];
                     while (!Stop)
                     {
-                        long waitMore = nextStartTime - J2N.Time.CurrentTimeMilliseconds();
+                        long waitMore = nextStartTime - (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                         if (waitMore > 0)
                         {
                             // TODO: better to use condition to notify
@@ -306,7 +306,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
                         count += inc;
                         if (countsByTime != null)
                         {
-                            int slot = (int)((J2N.Time.CurrentTimeMilliseconds() - t0) / logByTimeMsec);
+                            int slot = (int)(((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0) / logByTimeMsec); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                             if (slot >= countsByTime.Length)
                             {
                                 countsByTime = ArrayUtil.Grow(countsByTime, 1 + slot);
@@ -486,10 +486,10 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
         private void StartlThreadsWithRate(ParallelTask[] t)
         {
             long delayStep = (perMin ? 60000 : 1000) / rate;
-            long nextStartTime = J2N.Time.CurrentTimeMilliseconds();
+            long nextStartTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             for (int i = 0; i < t.Length; i++)
             {
-                long waitMore = nextStartTime - J2N.Time.CurrentTimeMilliseconds();
+                long waitMore = nextStartTime - (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 if (waitMore > 0)
                 {
                     Thread.Sleep((int)waitMore);
diff --git a/src/Lucene.Net.Benchmark/Quality/QualityBenchmark.cs b/src/Lucene.Net.Benchmark/Quality/QualityBenchmark.cs
index 335b8c9..ac63f30 100644
--- a/src/Lucene.Net.Benchmark/Quality/QualityBenchmark.cs
+++ b/src/Lucene.Net.Benchmark/Quality/QualityBenchmark.cs
@@ -95,9 +95,9 @@ namespace Lucene.Net.Benchmarks.Quality
                 // generate query
                 Query q = m_qqParser.Parse(qq);
                 // search with this query 
-                long t1 = J2N.Time.CurrentTimeMilliseconds();
+                long t1 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 TopDocs td = m_searcher.Search(q, null, maxResults);
-                long searchTime = J2N.Time.CurrentTimeMilliseconds() - t1;
+                long searchTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t1; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 //most likely we either submit or judge, but check both 
                 if (judge != null)
                 {
@@ -120,13 +120,14 @@ namespace Lucene.Net.Benchmarks.Quality
         {
             QualityStats stts = new QualityStats(judge.MaxRecall(qq), searchTime);
             ScoreDoc[] sd = td.ScoreDocs;
-            long t1 = J2N.Time.CurrentTimeMilliseconds(); // extraction of first doc name we measure also construction of doc name extractor, just in case.
+            // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
+            long t1 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // extraction of first doc name we measure also construction of doc name extractor, just in case.
             DocNameExtractor xt = new DocNameExtractor(m_docNameField);
             for (int i = 0; i < sd.Length; i++)
             {
                 string docName = xt.DocName(m_searcher, sd[i].Doc);
-                long docNameExtractTime = J2N.Time.CurrentTimeMilliseconds() - t1;
-                t1 = J2N.Time.CurrentTimeMilliseconds();
+                long docNameExtractTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t1; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
+                t1 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 bool isRelevant = judge.IsRelevant(docName, qq);
                 stts.AddResult(i + 1, isRelevant, docNameExtractTime);
             }
diff --git a/src/Lucene.Net.Benchmark/Utils/ExtractWikipedia.cs b/src/Lucene.Net.Benchmark/Utils/ExtractWikipedia.cs
index 71e7e48..87165d3 100644
--- a/src/Lucene.Net.Benchmark/Utils/ExtractWikipedia.cs
+++ b/src/Lucene.Net.Benchmark/Utils/ExtractWikipedia.cs
@@ -101,7 +101,7 @@ namespace Lucene.Net.Benchmarks.Utils
         {
             Document doc; // LUCENENET: IDE0059: Remove unnecessary value assignment
             Console.WriteLine("Starting Extraction");
-            long start = J2N.Time.CurrentTimeMilliseconds();
+            long start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             try
             {
                 while ((doc = m_docMaker.MakeDocument()) != null)
@@ -114,7 +114,7 @@ namespace Lucene.Net.Benchmarks.Utils
             {
                 //continue
             }
-            long finish = J2N.Time.CurrentTimeMilliseconds();
+            long finish = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             Console.WriteLine("Extraction took " + (finish - start) + " ms");
         }
 
diff --git a/src/Lucene.Net.Demo/Facet/RangeFacetsExample.cs b/src/Lucene.Net.Demo/Facet/RangeFacetsExample.cs
index 264925a..a5c1d26 100644
--- a/src/Lucene.Net.Demo/Facet/RangeFacetsExample.cs
+++ b/src/Lucene.Net.Demo/Facet/RangeFacetsExample.cs
@@ -48,7 +48,7 @@ namespace Lucene.Net.Demo.Facet
 
         private readonly Directory indexDir = new RAMDirectory();
         private IndexSearcher searcher;
-        private readonly long nowSec = DateTime.Now.Ticks;
+        private readonly long nowSec = Environment.TickCount;
 
         internal readonly Int64Range PAST_HOUR;
         internal readonly Int64Range PAST_SIX_HOURS;
diff --git a/src/Lucene.Net.Replicator/LocalReplicator.cs b/src/Lucene.Net.Replicator/LocalReplicator.cs
index 4b12e69..1129421 100644
--- a/src/Lucene.Net.Replicator/LocalReplicator.cs
+++ b/src/Lucene.Net.Replicator/LocalReplicator.cs
@@ -103,17 +103,17 @@ namespace Lucene.Net.Replicator
             {
                 Session = session;
                 Revision = revision;
-                lastAccessTime = Stopwatch.GetTimestamp();
+                lastAccessTime = Stopwatch.GetTimestamp(); // LUCENENET: Use the most accurate timer to determine expiration
             }
 
             public virtual bool IsExpired(long expirationThreshold)
             {
-                return lastAccessTime < Stopwatch.GetTimestamp() - expirationThreshold * Stopwatch.Frequency / 1000; // LUCENENET TODO: CurrentTimeMilliseconds()
+                return lastAccessTime < Stopwatch.GetTimestamp() - expirationThreshold * Stopwatch.Frequency / 1000; // LUCENENET: Use the most accurate timer to determine expiration
             }
 
             public virtual void MarkAccessed()
             {
-                lastAccessTime = Stopwatch.GetTimestamp(); // LUCENENET TODO: CurrentTimeMilliseconds()
+                lastAccessTime = Stopwatch.GetTimestamp(); // LUCENENET: Use the most accurate timer to determine expiration
             }
         }
 
diff --git a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
index 3c9f011..117b809 100644
--- a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
@@ -63,7 +63,7 @@ namespace Lucene.Net.Spatial.Util
             // read operation. For the create case, we use Lazy<T> to ensure atomicity.
             return sidx.GetValue(reader, (key) => new Lazy<ShapeFieldCache<T>>(() =>
             {
-                /*long startTime = Runtime.CurrentTimeMillis();
+                /*long startTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 log.Fine("Building Cache [" + reader.MaxDoc() + "]");*/
                 ShapeFieldCache<T> idx = new ShapeFieldCache<T>(key.MaxDoc, m_defaultSize);
                 int count = 0;
@@ -89,7 +89,7 @@ namespace Lucene.Net.Spatial.Util
                         }
                     }
                 }
-                /*long elapsed = Runtime.CurrentTimeMillis() - startTime;
+                /*long elapsed = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond - startTime; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 log.Fine("Cached: [" + count + " in " + elapsed + "ms] " + idx);*/
                 return idx;
             })).Value;
diff --git a/src/Lucene.Net.Suggest/Suggest/Analyzing/AnalyzingInfixSuggester.cs b/src/Lucene.Net.Suggest/Suggest/Analyzing/AnalyzingInfixSuggester.cs
index 6bb4748..a3e5f77 100644
--- a/src/Lucene.Net.Suggest/Suggest/Analyzing/AnalyzingInfixSuggester.cs
+++ b/src/Lucene.Net.Suggest/Suggest/Analyzing/AnalyzingInfixSuggester.cs
@@ -487,7 +487,7 @@ namespace Lucene.Net.Search.Suggest.Analyzing
             {
                 ts = m_queryAnalyzer.GetTokenStream("", new StringReader(key));
 
-                //long t0 = System.currentTimeMillis();
+                //long t0 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 ts.Reset();
                 var termAtt = ts.AddAttribute<ICharTermAttribute>();
                 var offsetAtt = ts.AddAttribute<IOffsetAttribute>();
@@ -595,7 +595,7 @@ namespace Lucene.Net.Search.Suggest.Analyzing
                 m_searcherMgr.Release(searcher);
             }
 
-            //System.out.println((System.currentTimeMillis() - t0) + " msec for infix suggest");
+            //System.out.println(((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0) + " msec for infix suggest"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             //System.out.println(results);
 
             return results;
diff --git a/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs b/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs
index cbe7e44..a3e2aa0 100644
--- a/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs
+++ b/src/Lucene.Net.TestFramework/Index/ThreadedIndexingAndSearchingTestCase.cs
@@ -175,7 +175,7 @@ namespace Lucene.Net.Index
                 // TODO: would be better if this were cross thread, so that we make sure one thread deleting anothers added docs works:
                 IList<string> toDeleteIDs = new List<string>();
                 IList<SubDocs> toDeleteSubDocs = new List<SubDocs>();
-                while (Environment.TickCount < stopTime && !outerInstance.m_failed)
+                while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime && !outerInstance.m_failed) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 {
                     try
                     {
@@ -454,7 +454,7 @@ namespace Lucene.Net.Index
                 {
                     Console.WriteLine(Thread.CurrentThread.Name + ": launch search thread");
                 }
-                while (Environment.TickCount < stopTimeMS)
+                while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTimeMS) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 {
                     try
                     {
@@ -505,7 +505,7 @@ namespace Lucene.Net.Index
                                     trigger = totTermCount / 30;
                                     shift = Random.Next(trigger);
                                 }
-                                while (Environment.TickCount < stopTimeMS)
+                                while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTimeMS) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                                 {
                                     if (!termsEnum.MoveNext())
                                     {
@@ -566,7 +566,7 @@ namespace Lucene.Net.Index
             m_delCount.Value = 0;
             m_packCount.Value = 0;
 
-            long t0 = Environment.TickCount;
+            long t0 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             Random random = new Random(Random.Next());
             LineFileDocs docs = new LineFileDocs(random, DefaultCodecSupportsDocValues);
@@ -627,13 +627,13 @@ namespace Lucene.Net.Index
             ISet<string> delPackIDs = new ConcurrentHashSet<string>();
             ConcurrentQueue<SubDocs> allSubDocs = new ConcurrentQueue<SubDocs>();
 
-            long stopTime = Environment.TickCount + (RUN_TIME_SEC * 1000);
+            long stopTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + (RUN_TIME_SEC * 1000); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             ThreadJob[] indexThreads = LaunchIndexingThreads(docs, NUM_INDEX_THREADS, stopTime, delIDs, delPackIDs, allSubDocs);
 
             if (Verbose)
             {
-                Console.WriteLine("TEST: DONE start " + NUM_INDEX_THREADS + " indexing threads [" + (Environment.TickCount - t0) + " ms]");
+                Console.WriteLine("TEST: DONE start " + NUM_INDEX_THREADS + " indexing threads [" + ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0) + " ms]"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
 
             // Let index build up a bit
@@ -643,7 +643,7 @@ namespace Lucene.Net.Index
 
             if (Verbose)
             {
-                Console.WriteLine("TEST: all searching done [" + (Environment.TickCount - t0) + " ms]");
+                Console.WriteLine("TEST: all searching done [" + ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0) + " ms]"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
 
             for (int thread = 0; thread < indexThreads.Length; thread++)
@@ -653,7 +653,7 @@ namespace Lucene.Net.Index
 
             if (Verbose)
             {
-                Console.WriteLine("TEST: done join indexing threads [" + (Environment.TickCount - t0) + " ms]; addCount=" + m_addCount + " delCount=" + m_delCount);
+                Console.WriteLine("TEST: done join indexing threads [" + ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0) + " ms]; addCount=" + m_addCount + " delCount=" + m_delCount); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
 
             IndexSearcher s = GetFinalSearcher();
@@ -792,7 +792,7 @@ namespace Lucene.Net.Index
 
             if (Verbose)
             {
-                Console.WriteLine("TEST: done [" + (Environment.TickCount - t0) + " ms]");
+                Console.WriteLine("TEST: done [" + ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0) + " ms]"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
         }
 
diff --git a/src/Lucene.Net.TestFramework/Search/QueryUtils.cs b/src/Lucene.Net.TestFramework/Search/QueryUtils.cs
index 5daf33f..128f5e1 100644
--- a/src/Lucene.Net.TestFramework/Search/QueryUtils.cs
+++ b/src/Lucene.Net.TestFramework/Search/QueryUtils.cs
@@ -585,7 +585,7 @@ namespace Lucene.Net.Search
                 float score = scorer.GetScore();
                 try
                 {
-                    long startMS = Environment.TickCount;
+                    long startMS = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     for (int i = lastDoc[0] + 1; i <= doc; i++)
                     {
                         Weight w = s.CreateNormalizedWeight(q);
@@ -598,7 +598,7 @@ namespace Lucene.Net.Search
 
                         // Hurry things along if they are going slow (eg
                         // if you got SimpleText codec this will kick in):
-                        if (i < doc && Environment.TickCount - startMS > 5)
+                        if (i < doc && (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - startMS > 5) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                         {
                             i = doc - 1;
                         }
diff --git a/src/Lucene.Net.TestFramework/Search/ShardSearchingTestBase.cs b/src/Lucene.Net.TestFramework/Search/ShardSearchingTestBase.cs
index 6f1651e..6e8b798 100644
--- a/src/Lucene.Net.TestFramework/Search/ShardSearchingTestBase.cs
+++ b/src/Lucene.Net.TestFramework/Search/ShardSearchingTestBase.cs
@@ -712,7 +712,7 @@ namespace Lucene.Net.Search
                 {
                     LineFileDocs docs = new LineFileDocs(Random, DefaultCodecSupportsDocValues);
                     int numDocs = 0;
-                    while (Time.NanoTime() < outerInstance.endTimeNanos)
+                    while (J2N.Time.NanoTime() < outerInstance.endTimeNanos)
                     {
                         int what = Random.Next(3);
                         NodeState node = outerInstance.m_nodes[Random.Next(outerInstance.m_nodes.Length)];
@@ -759,7 +759,7 @@ namespace Lucene.Net.Search
 
         protected virtual void Start(int numNodes, double runTimeSec, int maxSearcherAgeSeconds)
         {
-            endTimeNanos = Time.NanoTime() + (long)(runTimeSec * 1000000000);
+            endTimeNanos = J2N.Time.NanoTime() + (long)(runTimeSec * 1000000000);
             this.maxSearcherAgeSeconds = maxSearcherAgeSeconds;
 
             m_nodes = new NodeState[numNodes];
diff --git a/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs b/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs
index d2eb5e8..37590e2 100644
--- a/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs
+++ b/src/Lucene.Net.TestFramework/Util/ThrottledIndexOutput.cs
@@ -108,12 +108,12 @@ namespace Lucene.Net.Util
 
         public override void WriteBytes(byte[] b, int offset, int length)
         {
-            long before = Time.NanoTime();
+            long before = J2N.Time.NanoTime();
             // TODO: sometimes, write only half the bytes, then
             // sleep, then 2nd half, then sleep, so we sometimes
             // interrupt having only written not all bytes
             @delegate.WriteBytes(b, offset, length);
-            timeElapsed += Time.NanoTime() - before;
+            timeElapsed += J2N.Time.NanoTime() - before;
             pendingBytes += length;
             Sleep(GetDelay(false));
         }
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Miscellaneous/TestLucene47WordDelimiterFilter.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Miscellaneous/TestLucene47WordDelimiterFilter.cs
index 3277c3d..02eff71 100644
--- a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Miscellaneous/TestLucene47WordDelimiterFilter.cs
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Miscellaneous/TestLucene47WordDelimiterFilter.cs
@@ -1,4 +1,4 @@
-// Lucene version compatibility level 4.8.1
+// Lucene version compatibility level 4.8.1
 using Lucene.Net.Analysis.Core;
 using Lucene.Net.Analysis.Standard;
 using Lucene.Net.Analysis.TokenAttributes;
@@ -39,7 +39,7 @@ namespace Lucene.Net.Analysis.Miscellaneous
     // {
     //  String s = "now is the time-for all good men to come to-the aid of their country.";
     //  Token tok = new Token();
-    //  long start = System.currentTimeMillis();
+    //  long start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
     //  int ret = 0;
     //  for (int i = 0; i<1000000; i++) {
     //    StringReader r = new StringReader(s);
@@ -49,7 +49,7 @@ namespace Lucene.Net.Analysis.Miscellaneous
     //    while (ts.next(tok) != null) ret++;
     //  }
     // 
-    //  System.out.println("ret="+ret+" time="+(System.currentTimeMillis()-start));
+    //  System.out.println("ret="+ret+" time="+(J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond-start)); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
     // }
 
 
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Miscellaneous/TestWordDelimiterFilter.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Miscellaneous/TestWordDelimiterFilter.cs
index 2a7f4bd..60bb1a7 100644
--- a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Miscellaneous/TestWordDelimiterFilter.cs
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Miscellaneous/TestWordDelimiterFilter.cs
@@ -1,4 +1,4 @@
-// Lucene version compatibility level 4.8.1
+// Lucene version compatibility level 4.8.1
 using Lucene.Net.Analysis.Core;
 using Lucene.Net.Analysis.Standard;
 using Lucene.Net.Analysis.TokenAttributes;
@@ -36,7 +36,7 @@ namespace Lucene.Net.Analysis.Miscellaneous
         // public void TestPerformance() throws IOException {
         //  String s = "now is the time-for all good men to come to-the aid of their country.";
         //  Token tok = new Token();
-        //  long start = System.currentTimeMillis();
+        //  long start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
         //  int ret=0;
         //  for (int i=0; i<1000000; i++) {
         //    StringReader r = new StringReader(s);
@@ -46,7 +46,7 @@ namespace Lucene.Net.Analysis.Miscellaneous
         //    while (ts.next(tok) != null) ret++;
         //  }
         // 
-        //  System.out.println("ret="+ret+" time="+(System.currentTimeMillis()-start));
+        //  System.out.println("ret="+ret+" time="+(J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond-start)); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
         // }
 
         [Test]
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Pattern/TestPatternReplaceCharFilter.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Pattern/TestPatternReplaceCharFilter.cs
index c27df2e..aa3dc1c 100644
--- a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Pattern/TestPatternReplaceCharFilter.cs
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Pattern/TestPatternReplaceCharFilter.cs
@@ -1,4 +1,5 @@
-// Lucene version compatibility level 4.8.1
+// Lucene version compatibility level 4.8.1
+using J2N;
 using Lucene.Net.Util;
 using NUnit.Framework;
 using System;
@@ -221,29 +222,28 @@ namespace Lucene.Net.Analysis.Pattern
             return new Regex(p, RegexOptions.Compiled);
         }
 
-        // LUCENENET: This wasn't commented in the original source, but it had the Ignore attribute, so proceeding without it.
-        ///// <summary>
-        ///// A demonstration of how backtracking regular expressions can lead to relatively 
-        ///// easy DoS attacks.
-        ///// </summary>
-        ///// <seealso cref= "http://swtch.com/~rsc/regexp/regexp1.html" </seealso>
-        //[Test]
-        //[Ignore]
-        //public virtual void TestNastyPattern()
-        //{
-        //    Pattern p = Pattern.compile("(c.+)*xy");
-        //    string input = "[;<!--aecbbaa--><    febcfdc fbb = \"fbeeebff\" fc = dd   >\\';<eefceceaa e= babae\" eacbaff =\"fcfaccacd\" = bcced>>><  bccaafe edb = ecfccdff\"   <?</script><    edbd ebbcd=\"faacfcc\" aeca= bedbc ceeaac =adeafde aadccdaf = \"afcc ffda=aafbe &#x16921ed5\"1843785582']";
-        //    for (int i = 0; i < input.Length; i++)
-        //    {
-        //        Matcher matcher = p.matcher(input.Substring(0, i));
-        //        long t = DateTimeHelperClass.CurrentUnixTimeMillis();
-        //        if (matcher.find())
-        //        {
-        //            Console.WriteLine(matcher.group());
-        //        }
-        //        Console.WriteLine(i + " > " + (DateTimeHelperClass.CurrentUnixTimeMillis() - t) / 1000.0);
-        //    }
-        //}
+        /// <summary>
+        /// A demonstration of how backtracking regular expressions can lead to relatively 
+        /// easy DoS attacks.
+        /// </summary>
+        /// <seealso cref= "http://swtch.com/~rsc/regexp/regexp1.html" </seealso>
+        [Test]
+        [Ignore("Ignored in Lucene")]
+        public virtual void TestNastyPattern()
+        {
+            Regex p = new Regex("(c.+)*xy", RegexOptions.Compiled);
+            string input = "[;<!--aecbbaa--><    febcfdc fbb = \"fbeeebff\" fc = dd   >\\';<eefceceaa e= babae\" eacbaff =\"fcfaccacd\" = bcced>>><  bccaafe edb = ecfccdff\"   <?</script><    edbd ebbcd=\"faacfcc\" aeca= bedbc ceeaac =adeafde aadccdaf = \"afcc ffda=aafbe &#x16921ed5\"1843785582']";
+            for (int i = 0; i < input.Length; i++)
+            {
+                Match matcher = p.Match(input.Substring(0, i));
+                long t = Time.NanoTime() / Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
+                if (matcher.Success)
+                {
+                    Console.WriteLine(matcher.Groups[1]);
+                }
+                Console.WriteLine(i + " > " + (Time.NanoTime() / Time.MillisecondsPerNanosecond - t) / 1000.0); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
+            }
+        }
 
         /// <summary>
         /// blast some random strings through the analyzer </summary>
diff --git a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Sinks/TestTeeSinkTokenFilter.cs b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Sinks/TestTeeSinkTokenFilter.cs
index 89a6513..e9a1dcf 100644
--- a/src/Lucene.Net.Tests.Analysis.Common/Analysis/Sinks/TestTeeSinkTokenFilter.cs
+++ b/src/Lucene.Net.Tests.Analysis.Common/Analysis/Sinks/TestTeeSinkTokenFilter.cs
@@ -1,4 +1,5 @@
-// Lucene version compatibility level 4.8.1
+// Lucene version compatibility level 4.8.1
+using J2N;
 using Lucene.Net.Analysis.Core;
 using Lucene.Net.Analysis.Standard;
 using Lucene.Net.Analysis.TokenAttributes;
@@ -209,8 +210,7 @@ namespace Lucene.Net.Analysis.Sinks
                 for (int j = 0; j < modCounts.Length; j++)
                 {
                     int tfPos = 0;
-                    //long start = DateTimeHelperClass.CurrentUnixTimeMillis();
-                    long start = Environment.TickCount;
+                    long start = Time.NanoTime() / Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     for (int i = 0; i < 20; i++)
                     {
                         stream = new StandardFilter(TEST_VERSION_CURRENT, new StandardTokenizer(TEST_VERSION_CURRENT, new StringReader(buffer.ToString())));
@@ -226,13 +226,11 @@ namespace Lucene.Net.Analysis.Sinks
                             tfPos += posIncrAtt.PositionIncrement;
                         }
                     }
-                    //long finish = DateTimeHelperClass.CurrentUnixTimeMillis();
-                    long finish = Environment.TickCount;
+                    long finish = Time.NanoTime() / Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     Console.WriteLine("ModCount: " + modCounts[j] + " Two fields took " + (finish - start) + " ms");
                     int sinkPos = 0;
                     //simulate one field with one sink
-                    //start = DateTimeHelperClass.CurrentUnixTimeMillis();
-                    start = Environment.TickCount;
+                    start = Time.NanoTime() / Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     for (int i = 0; i < 20; i++)
                     {
                         teeStream = new TeeSinkTokenFilter(new StandardFilter(TEST_VERSION_CURRENT, new StandardTokenizer(TEST_VERSION_CURRENT, new StringReader(buffer.ToString()))));
@@ -249,8 +247,7 @@ namespace Lucene.Net.Analysis.Sinks
                             sinkPos += posIncrAtt.PositionIncrement;
                         }
                     }
-                    //finish = DateTimeHelperClass.CurrentUnixTimeMillis();
-                    finish = Environment.TickCount;
+                    finish = Time.NanoTime() / Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     Console.WriteLine("ModCount: " + modCounts[j] + " Tee fields took " + (finish - start) + " ms");
                     assertTrue(sinkPos + " does not equal: " + tfPos, sinkPos == tfPos);
 
diff --git a/src/Lucene.Net.Tests.Analysis.Kuromoji/TestJapaneseTokenizer.cs b/src/Lucene.Net.Tests.Analysis.Kuromoji/TestJapaneseTokenizer.cs
index 0e0cad9..48efd32 100644
--- a/src/Lucene.Net.Tests.Analysis.Kuromoji/TestJapaneseTokenizer.cs
+++ b/src/Lucene.Net.Tests.Analysis.Kuromoji/TestJapaneseTokenizer.cs
@@ -1,4 +1,5 @@
-using J2N.Text;
+using J2N;
+using J2N.Text;
 using Lucene.Net.Analysis.Ja.Dict;
 using Lucene.Net.Analysis.Ja.TokenAttributes;
 using Lucene.Net.Analysis.TokenAttributes;
@@ -718,7 +719,7 @@ namespace Lucene.Net.Analysis.Ja
           final FileInputStream fis = new FileInputStream("/q/lucene/jawiki-20120220-pages-articles.xml");
           final Reader r = new BufferedReader(new InputStreamReader(fis, StandardCharsets.UTF_8));
 
-          final long startTimeNS = System.nanoTime();
+          final long startTimeNS = Time.NanoTime();
           boolean done = false;
           long compoundCount = 0;
           long nonCompoundCount = 0;
@@ -741,7 +742,7 @@ namespace Lucene.Net.Analysis.Ja
                 nonCompoundCount++;
                 if (nonCompoundCount % 1000000 == 0) {
                   System.out.println(String.format("%.2f msec [pos=%d, %d, %d]",
-                                                   (System.nanoTime()-startTimeNS)/1000000.0,
+                                                   (Time.NanoTime()-startTimeNS)/1000000.0,
                                                    netOffset + offsetAtt.startOffset(),
                                                    nonCompoundCount,
                                                    compoundCount));
@@ -784,7 +785,7 @@ namespace Lucene.Net.Analysis.Ja
             }
             */
 
-            long totalStart = Environment.TickCount;
+            long totalStart = Time.NanoTime() / Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             for (int i = 0; i < numIterations; i++)
             {
                 TokenStream ts = analyzer.GetTokenStream("ignored", line);
@@ -802,10 +803,10 @@ namespace Lucene.Net.Analysis.Ja
             String[] sentences = Regex.Split(line, "、|。").TrimEnd();
             if (Verbose)
             {
-                Console.WriteLine("Total time : " + (Environment.TickCount - totalStart));
+                Console.WriteLine("Total time : " + ((Time.NanoTime() / Time.MillisecondsPerNanosecond) - totalStart)); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 Console.WriteLine("Test for Bocchan with pre-splitting sentences (" + sentences.Length + " sentences)");
             }
-            totalStart = Environment.TickCount;
+            totalStart = Time.NanoTime() / Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             for (int i = 0; i < numIterations; i++)
             {
                 foreach (String sentence in sentences)
@@ -825,7 +826,7 @@ namespace Lucene.Net.Analysis.Ja
             }
             if (Verbose)
             {
-                Console.WriteLine("Total time : " + (Environment.TickCount - totalStart));
+                Console.WriteLine("Total time : " + ((Time.NanoTime() / Time.MillisecondsPerNanosecond) - totalStart)); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
         }
 
diff --git a/src/Lucene.Net.Tests.Benchmark/ByTask/Feeds/DocMakerTest.cs b/src/Lucene.Net.Tests.Benchmark/ByTask/Feeds/DocMakerTest.cs
index b10b08a..d8acb4f 100644
--- a/src/Lucene.Net.Tests.Benchmark/ByTask/Feeds/DocMakerTest.cs
+++ b/src/Lucene.Net.Tests.Benchmark/ByTask/Feeds/DocMakerTest.cs
@@ -171,7 +171,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
             // leading to a file handle leak.
             FileInfo f = new FileInfo(Path.Combine(getWorkDir().FullName, "docMakerLeak.txt"));
             TextWriter ps = new StreamWriter(new FileStream(f.FullName, FileMode.Create, FileAccess.Write), Encoding.UTF8);
-            ps.WriteLine("one title\t" + J2N.Time.CurrentTimeMilliseconds() + "\tsome content");
+            ps.WriteLine("one title\t" + (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + "\tsome content"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             ps.Dispose();
 
             Dictionary<string, string> props = new Dictionary<string, string>();
diff --git a/src/Lucene.Net.Tests.Benchmark/ByTask/Tasks/CountingSearchTestTask.cs b/src/Lucene.Net.Tests.Benchmark/ByTask/Tasks/CountingSearchTestTask.cs
index 87d56ea..8322fdf 100644
--- a/src/Lucene.Net.Tests.Benchmark/ByTask/Tasks/CountingSearchTestTask.cs
+++ b/src/Lucene.Net.Tests.Benchmark/ByTask/Tasks/CountingSearchTestTask.cs
@@ -48,7 +48,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Tasks
             lock (syncLock)
             {
                 prevLastMillis = lastMillis;
-                lastMillis = J2N.Time.CurrentTimeMilliseconds();
+                lastMillis = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 if (0 == numSearches)
                 {
                     startMillis = prevLastMillis = lastMillis;
diff --git a/src/Lucene.Net.Tests.Classification/ClassificationTestBase.cs b/src/Lucene.Net.Tests.Classification/ClassificationTestBase.cs
index e9d821b..5d0a22f 100644
--- a/src/Lucene.Net.Tests.Classification/ClassificationTestBase.cs
+++ b/src/Lucene.Net.Tests.Classification/ClassificationTestBase.cs
@@ -213,15 +213,14 @@ namespace Lucene.Net.Classification
         protected void CheckPerformance(IClassifier<T> classifier, Analyzer analyzer, String classFieldName)
         {
             AtomicReader atomicReader = null;
-            var stopwatch = new Stopwatch();
-            stopwatch.Start();
+            long trainStart = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             try
             {
                 PopulatePerformanceIndex(analyzer);
                 atomicReader = SlowCompositeReaderWrapper.Wrap(indexWriter.GetReader());
                 classifier.Train(atomicReader, textFieldName, classFieldName, analyzer);
-                stopwatch.Stop();
-                long trainTime = stopwatch.ElapsedMilliseconds;
+                long trainEnd = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
+                long trainTime = trainEnd - trainStart;
                 Assert.IsTrue(trainTime < 120000, "training took more than 2 mins : " + trainTime / 1000 + "s");
             }
             finally
diff --git a/src/Lucene.Net.Tests.Suggest/Spell/TestSpellChecker.cs b/src/Lucene.Net.Tests.Suggest/Spell/TestSpellChecker.cs
index f74823c..47df487 100644
--- a/src/Lucene.Net.Tests.Suggest/Spell/TestSpellChecker.cs
+++ b/src/Lucene.Net.Tests.Suggest/Spell/TestSpellChecker.cs
@@ -357,9 +357,9 @@ namespace Lucene.Net.Search.Spell
 
         private void Addwords(IndexReader r, SpellChecker sc, string field)
         {
-            long time = Environment.TickCount;
+            long time = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             sc.IndexDictionary(new LuceneDictionary(r, field), NewIndexWriterConfig(TEST_VERSION_CURRENT, null), false);
-            time = Environment.TickCount - time;
+            time = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - time; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             //System.out.println("time to build " + field + ": " + time);
         }
 
diff --git a/src/Lucene.Net.Tests/Index/Test2BTerms.cs b/src/Lucene.Net.Tests/Index/Test2BTerms.cs
index 3a88aa9..d7ed797 100644
--- a/src/Lucene.Net.Tests/Index/Test2BTerms.cs
+++ b/src/Lucene.Net.Tests/Index/Test2BTerms.cs
@@ -217,9 +217,9 @@ namespace Lucene.Net.Index
 
                 for (int i = 0; i < numDocs; i++)
                 {
-                    long t0 = Environment.TickCount;
+                    long t0 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     w.AddDocument(doc);
-                    Console.WriteLine(i + " of " + numDocs + " " + (Environment.TickCount - t0) + " msec");
+                    Console.WriteLine(i + " of " + numDocs + " " + ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0) + " msec"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 }
                 savedTerms = ts.savedTerms;
 
@@ -283,14 +283,14 @@ namespace Lucene.Net.Index
             {
                 BytesRef term = terms[Random.Next(terms.Count)];
                 Console.WriteLine("TEST: search " + term);
-                long t0 = Environment.TickCount;
+                long t0 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 int count = s.Search(new TermQuery(new Term("field", term)), 1).TotalHits;
                 if (count <= 0)
                 {
                     Console.WriteLine("  FAILED: count=" + count);
                     failed = true;
                 }
-                long t1 = Environment.TickCount;
+                long t1 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 Console.WriteLine("  took " + (t1 - t0) + " millis");
 
                 TermsEnum.SeekStatus result = termsEnum.SeekCeil(term);
diff --git a/src/Lucene.Net.Tests/Index/TestAtomicUpdate.cs b/src/Lucene.Net.Tests/Index/TestAtomicUpdate.cs
index 22fec0c..c45c620 100644
--- a/src/Lucene.Net.Tests/Index/TestAtomicUpdate.cs
+++ b/src/Lucene.Net.Tests/Index/TestAtomicUpdate.cs
@@ -49,7 +49,7 @@ namespace Lucene.Net.Index
 
             public override void Run()
             {
-                long stopTime = Environment.TickCount + (long)RUN_TIME_MSEC;
+                long stopTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + (long)RUN_TIME_MSEC; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
                 count = 0;
 
@@ -63,7 +63,7 @@ namespace Lucene.Net.Index
                         }
                         DoWork();
                         count++;
-                    } while (Environment.TickCount < stopTime);
+                    } while ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) < stopTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 }
                 catch (Exception e) when (e.IsThrowable())
                 {
diff --git a/src/Lucene.Net.Tests/Index/TestDocValuesWithThreads.cs b/src/Lucene.Net.Tests/Index/TestDocValuesWithThreads.cs
index ac77ad1..262b64c 100644
--- a/src/Lucene.Net.Tests/Index/TestDocValuesWithThreads.cs
+++ b/src/Lucene.Net.Tests/Index/TestDocValuesWithThreads.cs
@@ -250,7 +250,7 @@ namespace Lucene.Net.Index
 
             AtomicReader sr = GetOnlySegmentReader(r);
 
-            long END_TIME = Environment.TickCount + (TestNightly ? 30 : 1);
+            long END_TIME = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + (TestNightly ? 30 : 1); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             int NUM_THREADS = TestUtil.NextInt32(LuceneTestCase.Random, 1, 10);
             ThreadJob[] threads = new ThreadJob[NUM_THREADS];
@@ -298,7 +298,7 @@ namespace Lucene.Net.Index
                 {
                     throw RuntimeException.Create(ioe);
                 }
-                while (Environment.TickCount < endTime)
+                while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < endTime) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 {
                     SortedDocValues source;
                     source = stringDVDirect;
diff --git a/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs b/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs
index 269ddc0..a592365 100644
--- a/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs
+++ b/src/Lucene.Net.Tests/Index/TestDocumentsWriterStallControl.cs
@@ -73,12 +73,12 @@ namespace Lucene.Net.Index
                 stallThreads[i] = new ThreadAnonymousClass(ctrl, stallProbability);
             }
             Start(stallThreads);
-            long time = Environment.TickCount;
+            long time = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             /*
              * use a 100 sec timeout to make sure we not hang forever. join will fail in
              * that case
              */
-            while ((Environment.TickCount - time) < 100 * 1000 && !Terminated(stallThreads))
+            while (((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - time) < 100 * 1000 && !Terminated(stallThreads)) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             {
                 ctrl.UpdateStalled(false);
                 if (Random.NextBoolean())
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterCommit.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterCommit.cs
index 76b9eed..96b4049 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterCommit.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterCommit.cs
@@ -343,7 +343,7 @@ namespace Lucene.Net.Index
             w.Commit();
             var failed = new AtomicBoolean();
             var threads = new ThreadJob[NUM_THREADS];
-            long endTime = Environment.TickCount + ((long)(RUN_SEC * 1000));
+            long endTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + ((long)(RUN_SEC * 1000)); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             for (int i = 0; i < NUM_THREADS; i++)
             {
                 int finalI = i;
@@ -411,7 +411,7 @@ namespace Lucene.Net.Index
                             r = r2;
                             Assert.AreEqual(1, r.DocFreq(new Term("f", s)), "term=f:" + s + "; r=" + r);
                         }
-                    } while (Environment.TickCount < endTime);
+                    } while ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) < endTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     r.Dispose();
                 }
                 catch (Exception t) when (t.IsThrowable())
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs
index c30cd04..544343a 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterExceptions.cs
@@ -163,8 +163,6 @@ namespace Lucene.Net.Index
 
         private class IndexerThread : ThreadJob
         {
-            private readonly DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-
             private readonly TestIndexWriterExceptions outerInstance;
 
             internal IndexWriter writer;
@@ -207,7 +205,7 @@ namespace Lucene.Net.Index
                 Field idField = NewField(r, "id", "", DocCopyIterator.custom2);
                 doc.Add(idField);
 
-                long stopTime = ((long)(DateTime.UtcNow - unixEpoch).TotalMilliseconds) + 500;
+                long stopTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + 500; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
                 do
                 {
@@ -274,7 +272,7 @@ namespace Lucene.Net.Index
                         failure = t;
                         break;
                     }
-                } while (((long)(DateTime.UtcNow - unixEpoch).TotalMilliseconds) < stopTime);
+                } while ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) < stopTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
         }
 
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
index b368980..da3a07f 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterReader.cs
@@ -881,7 +881,7 @@ namespace Lucene.Net.Index
 
             const float SECONDS = 0.5f;
 
-            long endTime = (long)(Environment.TickCount + 1000.0 * SECONDS);
+            long endTime = (long)((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + 1000.0 * SECONDS); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             ConcurrentQueue<Exception> excs = new ConcurrentQueue<Exception>();
 
             // Only one thread can addIndexes at a time, because
@@ -895,7 +895,7 @@ namespace Lucene.Net.Index
             }
 
             int lastCount = 0;
-            while (Environment.TickCount < endTime)
+            while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < endTime) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             {
                 DirectoryReader r2 = DirectoryReader.OpenIfChanged(r);
                 if (r2 != null)
@@ -968,7 +968,7 @@ namespace Lucene.Net.Index
                         excs.Enqueue(t);
                         throw RuntimeException.Create(t);
                     }
-                } while (Environment.TickCount < endTime);
+                } while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < endTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
         }
 
@@ -997,7 +997,7 @@ namespace Lucene.Net.Index
 
             const float SECONDS = 0.5f;
 
-            long endTime = (long)(Environment.TickCount + 1000.0 * SECONDS);
+            long endTime = (long)((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + 1000.0 * SECONDS); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             ConcurrentQueue<Exception> excs = new ConcurrentQueue<Exception>();
 
             var threads = new ThreadJob[numThreads];
@@ -1009,7 +1009,7 @@ namespace Lucene.Net.Index
             }
 
             int sum = 0;
-            while (Environment.TickCount < endTime)
+            while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < endTime) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             {
                 DirectoryReader r2 = DirectoryReader.OpenIfChanged(r);
                 if (r2 != null)
@@ -1085,7 +1085,7 @@ namespace Lucene.Net.Index
                         excs.Enqueue(t);
                         throw RuntimeException.Create(t);
                     }
-                } while (Environment.TickCount < endTime);
+                } while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < endTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
         }
 
diff --git a/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs b/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs
index 3601420..1dd4e13 100644
--- a/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs
+++ b/src/Lucene.Net.Tests/Index/TestIndexWriterWithThreads.cs
@@ -97,7 +97,8 @@ namespace Lucene.Net.Index
 
                 int idUpto = 0;
                 int fullCount = 0;
-                long stopTime = Environment.TickCount + timeToRunInMilliseconds; // LUCENENET specific: added the ability to change how much time to alot
+                // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
+                long stopTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + timeToRunInMilliseconds; // LUCENENET specific: added the ability to change how much time to alot
 
                 do
                 {
@@ -149,7 +150,7 @@ namespace Lucene.Net.Index
                         }
                         break;
                     }
-                } while (Environment.TickCount < stopTime);
+                } while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
         }
 
diff --git a/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs b/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
index 1b47436..183f87e 100644
--- a/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
+++ b/src/Lucene.Net.Tests/Index/TestNRTReaderWithThreads.cs
@@ -58,9 +58,9 @@ namespace Lucene.Net.Index
                 indexThreads[x].Name = "Thread " + x;
                 indexThreads[x].Start();
             }
-            long startTime = Environment.TickCount;
+            long startTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             long duration = 1000;
-            while ((Environment.TickCount - startTime) < duration)
+            while (((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - startTime) < duration) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             {
                 Thread.Sleep(100);
             }
diff --git a/src/Lucene.Net.Tests/Index/TestNRTThreads.cs b/src/Lucene.Net.Tests/Index/TestNRTThreads.cs
index abd75f3..6124374 100644
--- a/src/Lucene.Net.Tests/Index/TestNRTThreads.cs
+++ b/src/Lucene.Net.Tests/Index/TestNRTThreads.cs
@@ -52,7 +52,7 @@ namespace Lucene.Net.Index
 
             DirectoryReader r = DirectoryReader.Open(m_writer, true);
 
-            while (Environment.TickCount < stopTime && !m_failed)
+            while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime && !m_failed) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             {
                 if (Random.NextBoolean())
                 {
@@ -99,7 +99,7 @@ namespace Lucene.Net.Index
                 {
                     fixedSearcher = new IndexSearcher(r, es);
                     SmokeTestSearcher(fixedSearcher);
-                    RunSearchThreads(Environment.TickCount + 500);
+                    RunSearchThreads((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + 500); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 }
             }
             r.Dispose();
diff --git a/src/Lucene.Net.Tests/Index/TestNeverDelete.cs b/src/Lucene.Net.Tests/Index/TestNeverDelete.cs
index 9d61305..e92fc98 100644
--- a/src/Lucene.Net.Tests/Index/TestNeverDelete.cs
+++ b/src/Lucene.Net.Tests/Index/TestNeverDelete.cs
@@ -61,7 +61,7 @@ namespace Lucene.Net.Index
 
             w.Commit();
             ThreadJob[] indexThreads = new ThreadJob[Random.Next(4)];
-            long stopTime = Environment.TickCount + AtLeast(1000);
+            long stopTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + AtLeast(1000); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             for (int x = 0; x < indexThreads.Length; x++)
             {
                 indexThreads[x] = new ThreadAnonymousClass(w, stopTime, NewStringField, NewTextField);
@@ -72,7 +72,7 @@ namespace Lucene.Net.Index
             ISet<string> allFiles = new JCG.HashSet<string>();
 
             DirectoryReader r = DirectoryReader.Open(d);
-            while (Environment.TickCount < stopTime)
+            while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             {
                 IndexCommit ic = r.IndexCommit;
                 if (Verbose)
@@ -137,7 +137,7 @@ namespace Lucene.Net.Index
                 try
                 {
                     int docCount = 0;
-                    while (Environment.TickCount < stopTime)
+                    while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     {
                         Document doc = new Document();
                         doc.Add(newStringField("dc", "" + docCount, Field.Store.YES));
diff --git a/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs b/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs
index 7cec87b..d330a09 100644
--- a/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs
+++ b/src/Lucene.Net.Tests/Index/TestSnapshotDeletionPolicy.cs
@@ -125,7 +125,7 @@ namespace Lucene.Net.Index
         private void RunTest(Random random, Directory dir)
         {
             // Run for ~1 seconds
-            long stopTime = Environment.TickCount + 1000;
+            long stopTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + 1000; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             SnapshotDeletionPolicy dp = DeletionPolicy;
             IndexWriter writer = new IndexWriter(dir, (IndexWriterConfig)NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).SetIndexDeletionPolicy(dp).SetMaxBufferedDocs(2));
@@ -229,7 +229,7 @@ namespace Lucene.Net.Index
                     Thread.Sleep(1);
                     // LUCENENET NOTE: No need to catch and rethrow same excepton type ThreadInterruptedException
 
-                } while (Environment.TickCount < stopTime);
+                } while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
         }
 
diff --git a/src/Lucene.Net.Tests/Index/TestStressIndexing.cs b/src/Lucene.Net.Tests/Index/TestStressIndexing.cs
index ee3c8b2..9ddef83 100644
--- a/src/Lucene.Net.Tests/Index/TestStressIndexing.cs
+++ b/src/Lucene.Net.Tests/Index/TestStressIndexing.cs
@@ -50,7 +50,7 @@ namespace Lucene.Net.Index
 
             public override void Run()
             {
-                long stopTime = Environment.TickCount + RUN_TIME_MSEC;
+                long stopTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + RUN_TIME_MSEC; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
                 count = 0;
 
@@ -64,7 +64,7 @@ namespace Lucene.Net.Index
                         }
                         DoWork();
                         count++;
-                    } while (Environment.TickCount < stopTime);
+                    } while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 }
                 catch (Exception e) when (e.IsThrowable())
                 {
diff --git a/src/Lucene.Net.Tests/Index/TestTermdocPerf.cs b/src/Lucene.Net.Tests/Index/TestTermdocPerf.cs
index d73b8b6..e5d4115 100644
--- a/src/Lucene.Net.Tests/Index/TestTermdocPerf.cs
+++ b/src/Lucene.Net.Tests/Index/TestTermdocPerf.cs
@@ -127,9 +127,9 @@ namespace Lucene.Net.Index
         {
             Directory dir = NewDirectory();
 
-            long start = Environment.TickCount;
+            long start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             AddDocs(LuceneTestCase.Random, dir, ndocs, "foo", "val", maxTF, percentDocs);
-            long end = Environment.TickCount;
+            long end = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             if (Verbose)
             {
                 Console.WriteLine("milliseconds for creation of " + ndocs + " docs = " + (end - start));
@@ -139,7 +139,7 @@ namespace Lucene.Net.Index
 
             TermsEnum tenum = MultiFields.GetTerms(reader, "foo").GetEnumerator();
 
-            start = Environment.TickCount;
+            start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             int ret = 0;
             DocsEnum tdocs = null;
@@ -154,7 +154,7 @@ namespace Lucene.Net.Index
                 }
             }
 
-            end = Environment.TickCount;
+            end = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             if (Verbose)
             {
                 Console.WriteLine("milliseconds for " + iter + " TermDocs iteration: " + (end - start));
diff --git a/src/Lucene.Net.Tests/Index/TestTransactions.cs b/src/Lucene.Net.Tests/Index/TestTransactions.cs
index 8537f7f..cecfd33 100644
--- a/src/Lucene.Net.Tests/Index/TestTransactions.cs
+++ b/src/Lucene.Net.Tests/Index/TestTransactions.cs
@@ -77,7 +77,7 @@ namespace Lucene.Net.Index
 
             public override void Run()
             {
-                long stopTime = Environment.TickCount + (long)(RUN_TIME_MSEC);
+                long stopTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + (long)(RUN_TIME_MSEC);
 
                 try
                 {
@@ -88,7 +88,7 @@ namespace Lucene.Net.Index
                             break;
                         }
                         DoWork();
-                    } while (Environment.TickCount < stopTime);
+                    } while (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime);
                 }
                 catch (Exception e) when (e.IsThrowable())
                 {
diff --git a/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs b/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs
index 5bd9e46..e769ce7 100644
--- a/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs
+++ b/src/Lucene.Net.Tests/Search/TestControlledRealTimeReopenThread.cs
@@ -677,10 +677,10 @@ namespace Lucene.Net.Search
                 Document d = new Document();
                 d.Add(new TextField("count", i + "", Field.Store.NO));
                 d.Add(new TextField("content", content, Field.Store.YES));
-                long start = Environment.TickCount;
+                long start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 long l = tiw.AddDocument(d);
                 controlledRealTimeReopenThread.WaitForGeneration(l);
-                long wait = Environment.TickCount - start;
+                long wait = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - start; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 assertTrue("waited too long for generation " + wait, wait < (maxStaleSecs * 1000));
                 IndexSearcher searcher = sm.Acquire();
                 TopDocs td = searcher.Search(new TermQuery(new Term("count", i + "")), 10);
diff --git a/src/Lucene.Net.Tests/Search/TestDateFilter.cs b/src/Lucene.Net.Tests/Search/TestDateFilter.cs
index 09490e2..8745619 100644
--- a/src/Lucene.Net.Tests/Search/TestDateFilter.cs
+++ b/src/Lucene.Net.Tests/Search/TestDateFilter.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Attributes;
+using Lucene.Net.Attributes;
 using Lucene.Net.Documents;
 using NUnit.Framework;
 using System;
@@ -54,7 +54,7 @@ namespace Lucene.Net.Search
 #endif
                 Random, indexStore);
 
-            long now = DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond;
+            long now = J2N.Time.CurrentTimeMilliseconds();
 
             Document doc = new Document();
             // add time that is in the past
@@ -122,7 +122,7 @@ namespace Lucene.Net.Search
 #endif
                 Random, indexStore);
 
-            long now = DateTime.UtcNow.Ticks / TimeSpan.TicksPerMillisecond;
+            long now = J2N.Time.CurrentTimeMilliseconds();
 
             Document doc = new Document();
             // add time that is in the future
diff --git a/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs b/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
index ea4be55..04a2f23 100644
--- a/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
+++ b/src/Lucene.Net.Tests/Search/TestMultiThreadTermVectors.cs
@@ -202,16 +202,16 @@ namespace Lucene.Net.Search
             long start = 0L;
             for (int docId = 0; docId < numDocs; docId++)
             {
-                start = Environment.TickCount;
+                start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 Fields vectors = reader.GetTermVectors(docId);
-                timeElapsed += Environment.TickCount - start;
+                timeElapsed += (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - start; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
                 // verify vectors result
                 VerifyVectors(vectors, docId);
 
-                start = Environment.TickCount;
+                start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 Terms vector = reader.GetTermVectors(docId).GetTerms("field");
-                timeElapsed += Environment.TickCount - start;
+                timeElapsed += (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - start; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
                 VerifyVector(vector.GetEnumerator(), docId);
             }
diff --git a/src/Lucene.Net.Tests/Search/TestShardSearching.cs b/src/Lucene.Net.Tests/Search/TestShardSearching.cs
index 2dd0600..157fbd5 100644
--- a/src/Lucene.Net.Tests/Search/TestShardSearching.cs
+++ b/src/Lucene.Net.Tests/Search/TestShardSearching.cs
@@ -66,7 +66,7 @@ namespace Lucene.Net.Search
                 this.Sort = sort;
                 this.Query = query;
                 this.NumHitsPaged = numHitsPaged;
-                SearchTimeNanos = Time.NanoTime();
+                SearchTimeNanos = J2N.Time.NanoTime();
             }
         }
 
@@ -90,7 +90,7 @@ namespace Lucene.Net.Search
 
             List<PreviousSearchState> priorSearches = new List<PreviousSearchState>();
             List<BytesRef> terms = null;
-            while (Time.NanoTime() < endTimeNanos)
+            while (J2N.Time.NanoTime() < endTimeNanos)
             {
                 bool doFollowon = priorSearches.Count > 0 && Random.Next(7) == 1;
 
@@ -108,7 +108,7 @@ namespace Lucene.Net.Search
 
                     if (Verbose)
                     {
-                        Console.WriteLine("\nTEST: follow-on query age=" + ((Time.NanoTime() - prevSearchState.SearchTimeNanos) / 1000000000.0));
+                        Console.WriteLine("\nTEST: follow-on query age=" + ((J2N.Time.NanoTime() - prevSearchState.SearchTimeNanos) / 1000000000.0));
                     }
 
                     try
diff --git a/src/Lucene.Net.Tests/Util/Fst/TestFSTs.cs b/src/Lucene.Net.Tests/Util/Fst/TestFSTs.cs
index 8a1fc86..3038658 100644
--- a/src/Lucene.Net.Tests/Util/Fst/TestFSTs.cs
+++ b/src/Lucene.Net.Tests/Util/Fst/TestFSTs.cs
@@ -335,10 +335,10 @@ namespace Lucene.Net.Util.Fst
             DirectoryInfo tempDir = CreateTempDir("fstlines");
             Directory dir = NewFSDirectory(tempDir);
             IndexWriter writer = new IndexWriter(dir, conf);
-            long stopTime = Environment.TickCount + RUN_TIME_MSEC;
+            long stopTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + RUN_TIME_MSEC; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             Document doc;
             int docCount = 0;
-            while ((doc = docs.NextDoc()) != null && Environment.TickCount < stopTime)
+            while ((doc = docs.NextDoc()) != null && J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond < stopTime) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             {
                 writer.AddDocument(doc);
                 docCount++;
@@ -546,7 +546,7 @@ namespace Lucene.Net.Util.Fst
                 try
                 {
                     Int32sRef intsRef = new Int32sRef(10);
-                    long tStart = Environment.TickCount;
+                    long tStart = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     int ord = 0;
                     while (true)
                     {
@@ -561,7 +561,7 @@ namespace Lucene.Net.Util.Fst
                         ord++;
                         if (ord % 500000 == 0)
                         {
-                            Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:000000.000}s: {1:000000000}...", ((Environment.TickCount - tStart) / 1000.0), ord));
+                            Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:000000.000}s: {1:000000000}...", (((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - tStart) / 1000.0), ord)); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                         }
                         if (ord >= limit)
                         {
@@ -569,12 +569,12 @@ namespace Lucene.Net.Util.Fst
                         }
                     }
 
-                    long tMid = Environment.TickCount;
+                    long tMid = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     Console.WriteLine(((tMid - tStart) / 1000.0) + " sec to add all terms");
 
                     if (Debugging.AssertsEnabled) Debugging.Assert(builder.TermCount == ord);
                     FST<T> fst = builder.Finish();
-                    long tEnd = Environment.TickCount;
+                    long tEnd = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                     Console.WriteLine(((tEnd - tMid) / 1000.0) + " sec to finish/pack");
                     if (fst == null)
                     {
@@ -623,7 +623,7 @@ namespace Lucene.Net.Util.Fst
                             @is = new StreamReader(new FileStream(wordsFileIn, FileMode.Open), Encoding.UTF8);
 
                             ord = 0;
-                            tStart = Environment.TickCount;
+                            tStart = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                             while (true)
                             {
                                 string w = @is.ReadLine();
@@ -663,7 +663,7 @@ namespace Lucene.Net.Util.Fst
                                 ord++;
                                 if (ord % 500000 == 0)
                                 {
-                                    Console.WriteLine(((Environment.TickCount - tStart) / 1000.0) + "s: " + ord + "...");
+                                    Console.WriteLine((((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - tStart) / 1000.0) + "s: " + ord + "..."); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                                 }
                                 if (ord >= limit)
                                 {
@@ -671,7 +671,7 @@ namespace Lucene.Net.Util.Fst
                                 }
                             }
 
-                            double totSec = ((Environment.TickCount - tStart) / 1000.0);
+                            double totSec = (((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - tStart) / 1000.0); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                             Console.WriteLine("Verify " + (iter == 1 ? "(by output) " : "") + "took " + totSec + " sec + (" + (int)((totSec * 1000000000 / ord)) + " nsec per lookup)");
 
                             if (!verifyByOutput)
diff --git a/src/Lucene.Net.Tests/Util/TestDoubleBarrelLRUCache.cs b/src/Lucene.Net.Tests/Util/TestDoubleBarrelLRUCache.cs
index a0b1e4d..a819d4f 100644
--- a/src/Lucene.Net.Tests/Util/TestDoubleBarrelLRUCache.cs
+++ b/src/Lucene.Net.Tests/Util/TestDoubleBarrelLRUCache.cs
@@ -80,10 +80,10 @@ namespace Lucene.Net.Util
 
             private readonly CloneableObject[] objs;
             private readonly DoubleBarrelLRUCache<CloneableObject, object> c;
-            private readonly DateTime endTime;
+            private readonly long endTime;
             internal volatile bool failed;
 
-            public CacheThread(TestDoubleBarrelLRUCache outerInstance, DoubleBarrelLRUCache<CloneableObject, object> c, CloneableObject[] objs, DateTime endTime)
+            public CacheThread(TestDoubleBarrelLRUCache outerInstance, DoubleBarrelLRUCache<CloneableObject, object> c, CloneableObject[] objs, long endTime)
             {
                 this.outerInstance = outerInstance;
                 this.c = c;
@@ -116,7 +116,7 @@ namespace Lucene.Net.Util
                         }
                         if ((++count % 10000) == 0)
                         {
-                            if (DateTime.Now.CompareTo(endTime) > 0)
+                            if (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond > endTime) // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                             {
                                 break;
                             }
@@ -157,7 +157,7 @@ namespace Lucene.Net.Util
             }
 
             CacheThread[] threads = new CacheThread[NUM_THREADS];
-            DateTime endTime = DateTime.Now.AddSeconds(1);
+            long endTime = (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) + 1000L; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             for (int i = 0; i < NUM_THREADS; i++)
             {
                 threads[i] = new CacheThread(this, c, objs, endTime);
diff --git a/src/Lucene.Net/Index/BufferedUpdatesStream.cs b/src/Lucene.Net/Index/BufferedUpdatesStream.cs
index 4aac6d0..4043e4f 100644
--- a/src/Lucene.Net/Index/BufferedUpdatesStream.cs
+++ b/src/Lucene.Net/Index/BufferedUpdatesStream.cs
@@ -1,4 +1,4 @@
-using J2N.Text;
+using J2N.Text;
 using J2N.Threading.Atomic;
 using Lucene.Net.Diagnostics;
 using Lucene.Net.Support;
@@ -171,7 +171,7 @@ namespace Lucene.Net.Index
         {
             lock (this)
             {
-                long t0 = Environment.TickCount;
+                long t0 = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
                 if (infos.Count == 0)
                 {
@@ -365,7 +365,7 @@ namespace Lucene.Net.Index
                 if (Debugging.AssertsEnabled) Debugging.Assert(CheckDeleteStats());
                 if (infoStream.IsEnabled("BD"))
                 {
-                    infoStream.Message("BD", "applyDeletes took " + (Environment.TickCount - t0) + " msec");
+                    infoStream.Message("BD", "applyDeletes took " + ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - t0) + " msec"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 }
                 // assert infos != segmentInfos || !any() : "infos=" + infos + " segmentInfos=" + segmentInfos + " any=" + any;
 
diff --git a/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs b/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs
index 10dfdee..e873011 100644
--- a/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs
+++ b/src/Lucene.Net/Index/ConcurrentMergeScheduler.cs
@@ -429,7 +429,7 @@ namespace Lucene.Net.Index
                         // updateMergeThreads).  We stall this producer
                         // thread to prevent creation of new segments,
                         // until merging has caught up:
-                        startStallTime = Environment.TickCount;
+                        startStallTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                         if (IsVerbose)
                         {
                             Message("    too many merges; stalling...");
@@ -442,7 +442,7 @@ namespace Lucene.Net.Index
                     {
                         if (startStallTime != 0)
                         {
-                            Message("  stalled for " + (Environment.TickCount - startStallTime) + " msec");
+                            Message("  stalled for " + ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - startStallTime) + " msec"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                         }
                     }
 
diff --git a/src/Lucene.Net/Index/DocTermOrds.cs b/src/Lucene.Net/Index/DocTermOrds.cs
index 61b384f..8728462 100644
--- a/src/Lucene.Net/Index/DocTermOrds.cs
+++ b/src/Lucene.Net/Index/DocTermOrds.cs
@@ -334,7 +334,7 @@ namespace Lucene.Net.Index
                 throw IllegalStateException.Create("Type mismatch: " + m_field + " was indexed as " + info.DocValuesType);
             }
             //System.out.println("DTO uninvert field=" + field + " prefix=" + termPrefix);
-            long startTime = Environment.TickCount;
+            long startTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             m_prefix = termPrefix == null ? null : BytesRef.DeepCopyOf(termPrefix);
 
             int maxDoc = reader.MaxDoc;
@@ -555,7 +555,7 @@ namespace Lucene.Net.Index
 
             m_numTermsInField = termNum;
 
-            long midPoint = Environment.TickCount;
+            long midPoint = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             if (m_termInstances == 0)
             {
@@ -665,7 +665,7 @@ namespace Lucene.Net.Index
                 indexedTerms.CopyTo(m_indexedTermsArray, 0);
             }
 
-            long endTime = Environment.TickCount;
+            long endTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             m_total_time = (int)(endTime - startTime);
             m_phase1_time = (int)(midPoint - startTime);
diff --git a/src/Lucene.Net/Index/IndexFileDeleter.cs b/src/Lucene.Net/Index/IndexFileDeleter.cs
index b10bd83..107c250 100644
--- a/src/Lucene.Net/Index/IndexFileDeleter.cs
+++ b/src/Lucene.Net/Index/IndexFileDeleter.cs
@@ -501,7 +501,7 @@ namespace Lucene.Net.Index
             long t0 = 0;
             if (infoStream.IsEnabled("IFD"))
             {
-                t0 = Time.NanoTime();
+                t0 = J2N.Time.NanoTime();
                 infoStream.Message("IFD", "now checkpoint \"" + writer.SegString(writer.ToLiveInfos(segmentInfos).Segments) + "\" [" + segmentInfos.Count + " segments " + "; isCommit = " + isCommit + "]");
             }
 
@@ -534,7 +534,7 @@ namespace Lucene.Net.Index
             }
             if (infoStream.IsEnabled("IFD"))
             {
-                long t1 = Time.NanoTime();
+                long t1 = J2N.Time.NanoTime();
                 infoStream.Message("IFD", ((t1 - t0) / 1000000) + " msec to checkpoint");
             }
         }
diff --git a/src/Lucene.Net/Index/IndexWriter.cs b/src/Lucene.Net/Index/IndexWriter.cs
index 362a6b1..a9a822e 100644
--- a/src/Lucene.Net/Index/IndexWriter.cs
+++ b/src/Lucene.Net/Index/IndexWriter.cs
@@ -349,7 +349,7 @@ namespace Lucene.Net.Index
         {
             EnsureOpen();
 
-            long tStart = Environment.TickCount;
+            long tStart = Time.NanoTime() / Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             if (infoStream.IsEnabled("IW"))
             {
@@ -425,7 +425,7 @@ namespace Lucene.Net.Index
                 }
                 if (infoStream.IsEnabled("IW"))
                 {
-                    infoStream.Message("IW", "getReader took " + (Environment.TickCount - tStart) + " msec");
+                    infoStream.Message("IW", "getReader took " + ((Time.NanoTime() / Time.MillisecondsPerNanosecond) - tStart) + " msec"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 }
                 success2 = true;
             }
@@ -4502,7 +4502,7 @@ namespace Lucene.Net.Index
         {
             bool success = false;
 
-            long t0 = Environment.TickCount;
+            long t0 = Time.NanoTime() / Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             try
             {
@@ -4565,7 +4565,7 @@ namespace Lucene.Net.Index
             {
                 if (infoStream.IsEnabled("IW"))
                 {
-                    infoStream.Message("IW", "merge time " + (Environment.TickCount - t0) + " msec for " + merge.info.Info.DocCount + " docs");
+                    infoStream.Message("IW", "merge time " + ((Time.NanoTime() / Time.MillisecondsPerNanosecond) - t0) + " msec for " + merge.info.Info.DocCount + " docs"); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 }
             }
         }
diff --git a/src/Lucene.Net/Index/SegmentMerger.cs b/src/Lucene.Net/Index/SegmentMerger.cs
index 96a41a4..3004ee4 100644
--- a/src/Lucene.Net/Index/SegmentMerger.cs
+++ b/src/Lucene.Net/Index/SegmentMerger.cs
@@ -1,6 +1,6 @@
-using J2N.Collections.Generic.Extensions;
+using J2N;
+using J2N.Collections.Generic.Extensions;
 using Lucene.Net.Diagnostics;
-using Lucene.Net.Support;
 using System;
 using System.Collections.Generic;
 using System.IO;
diff --git a/src/Lucene.Net/Index/SimpleMergedSegmentWarmer.cs b/src/Lucene.Net/Index/SimpleMergedSegmentWarmer.cs
index 61a579a..feea6bb 100644
--- a/src/Lucene.Net/Index/SimpleMergedSegmentWarmer.cs
+++ b/src/Lucene.Net/Index/SimpleMergedSegmentWarmer.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Diagnostics;
+using Lucene.Net.Diagnostics;
 using System;
 
 namespace Lucene.Net.Index
@@ -41,7 +41,7 @@ namespace Lucene.Net.Index
 
         public override void Warm(AtomicReader reader)
         {
-            long startTime = Environment.TickCount;
+            long startTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             int indexedCount = 0;
             int docValuesCount = 0;
             int normsCount = 0;
@@ -92,7 +92,12 @@ namespace Lucene.Net.Index
 
             if (infoStream.IsEnabled("SMSW"))
             {
-                infoStream.Message("SMSW", "Finished warming segment: " + reader + ", indexed=" + indexedCount + ", docValues=" + docValuesCount + ", norms=" + normsCount + ", time=" + (Environment.TickCount - startTime));
+                infoStream.Message("SMSW",
+                    "Finished warming segment: " + reader +
+                    ", indexed=" + indexedCount +
+                    ", docValues=" + docValuesCount +
+                    ", norms=" + normsCount +
+                    ", time=" + ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - startTime)); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             }
         }
     }
diff --git a/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs b/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
index ec5c585..961ea84 100644
--- a/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
+++ b/src/Lucene.Net/Search/ControlledRealTimeReopenThread.cs
@@ -1,7 +1,6 @@
-using J2N.Threading;
-using Lucene.Net.Support;
+using J2N;
+using J2N.Threading;
 using System;
-using System.IO;
 using System.Threading;
 
 namespace Lucene.Net.Search
@@ -225,7 +224,7 @@ namespace Lucene.Net.Search
         {
             // TODO: maybe use private thread ticktock timer, in
             // case clock shift messes up nanoTime?
-            long lastReopenStartNS = DateTime.UtcNow.Ticks * 100;
+            long lastReopenStartNS = Time.NanoTime();
 
             //System.out.println("reopen: start");
             while (!finish)
@@ -241,7 +240,7 @@ namespace Lucene.Net.Search
                 if (sleepNS > 0)
                     try
                     {
-                        reopenCond.WaitOne(TimeSpan.FromMilliseconds(sleepNS / Time.MILLISECONDS_PER_NANOSECOND));//Convert NS to Ticks
+                        reopenCond.WaitOne(TimeSpan.FromMilliseconds(sleepNS / Time.MillisecondsPerNanosecond));//Convert NS to MS
                     }
                     catch (Exception ie) when (ie.IsInterruptedException())
                     {
diff --git a/src/Lucene.Net/Search/SearcherLifetimeManager.cs b/src/Lucene.Net/Search/SearcherLifetimeManager.cs
index cc4f02a..a62eb41 100644
--- a/src/Lucene.Net/Search/SearcherLifetimeManager.cs
+++ b/src/Lucene.Net/Search/SearcherLifetimeManager.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Support;
+using J2N;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
@@ -291,7 +291,7 @@ namespace Lucene.Net.Search
                     // recordTime, etc:
                     if (pruner.DoPrune(ageSec, tracker.Searcher))
                     {
-                        //System.out.println("PRUNE version=" + tracker.version + " age=" + ageSec + " ms=" + System.currentTimeMillis());
+                        //System.out.println("PRUNE version=" + tracker.version + " age=" + ageSec + " ms=" + Time.CurrentTimeMilliseconds());
                         Lazy<SearcherTracker> _;
                         _searchers.TryRemove(tracker.Version, out _);
                         tracker.Dispose();
diff --git a/src/Lucene.Net/Store/RateLimiter.cs b/src/Lucene.Net/Store/RateLimiter.cs
index 07e04ad..df7ccd0 100644
--- a/src/Lucene.Net/Store/RateLimiter.cs
+++ b/src/Lucene.Net/Store/RateLimiter.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Support;
+using J2N;
 using System;
 using System.Threading;
 
diff --git a/src/Lucene.Net/Support/Time.cs b/src/Lucene.Net/Support/Time.cs
deleted file mode 100644
index 91d5657..0000000
--- a/src/Lucene.Net/Support/Time.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System;
-
-namespace Lucene.Net.Support
-{
-    /*
-     * Licensed to the Apache Software Foundation (ASF) under one or more
-     * contributor license agreements.  See the NOTICE file distributed with
-     * this work for additional information regarding copyright ownership.
-     * The ASF licenses this file to You under the Apache License, Version 2.0
-     * (the "License"); you may not use this file except in compliance with
-     * the License.  You may obtain a copy of the License at
-     *
-     *     http://www.apache.org/licenses/LICENSE-2.0
-     *
-     * Unless required by applicable law or agreed to in writing, software
-     * distributed under the License is distributed on an "AS IS" BASIS,
-     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     * See the License for the specific language governing permissions and
-     * limitations under the License.
-     */
-
-    internal static class Time
-    {
-        public const long MILLISECONDS_PER_NANOSECOND = 1000000;
-        public const long TICKS_PER_NANOSECOND = 100;
-
-        public static long NanoTime()
-        {
-            return DateTime.Now.Ticks * TICKS_PER_NANOSECOND;
-            // LUCENENET TODO: Change to
-            // return (Stopwatch.GetTimestamp() / Stopwatch.Frequency) * 1000000000;
-            // for better accuracy that is not affected by the system clock
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Lucene.Net/Util/OfflineSorter.cs b/src/Lucene.Net/Util/OfflineSorter.cs
index 490bc62..3f09de0 100644
--- a/src/Lucene.Net/Util/OfflineSorter.cs
+++ b/src/Lucene.Net/Util/OfflineSorter.cs
@@ -242,7 +242,7 @@ namespace Lucene.Net.Util
         /// </summary>
         public SortInfo Sort(FileInfo input, FileInfo output)
         {
-            sortInfo = new SortInfo(this) { TotalTime = Environment.TickCount };
+            sortInfo = new SortInfo(this) { TotalTime = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond }; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             output.Delete();
 
@@ -330,7 +330,7 @@ namespace Lucene.Net.Util
                 }
             }
 
-            sortInfo.TotalTime = (Environment.TickCount - sortInfo.TotalTime);
+            sortInfo.TotalTime = ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - sortInfo.TotalTime); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             return sortInfo;
         }
 
@@ -362,8 +362,8 @@ namespace Lucene.Net.Util
             var data = this.buffer;
             FileInfo tempFile = FileSupport.CreateTempFile("sort", "partition", DefaultTempDir());
 
-            long start = Environment.TickCount;
-            sortInfo.SortTime += (Environment.TickCount - start);
+            long start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
+            sortInfo.SortTime += ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - start); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             using (var @out = new ByteSequencesWriter(tempFile))
             {
@@ -384,7 +384,7 @@ namespace Lucene.Net.Util
         /// Merge a list of sorted temporary files (partitions) into an output file. </summary>
         internal void MergePartitions(IList<FileInfo> merges, FileInfo outputFile)
         {
-            long start = Environment.TickCount;
+            long start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
 
             var @out = new ByteSequencesWriter(outputFile);
 
@@ -422,7 +422,7 @@ namespace Lucene.Net.Util
                     }
                 }
 
-                sortInfo.MergeTime += Environment.TickCount - start;
+                sortInfo.MergeTime += (J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - start; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
                 sortInfo.MergeRounds++;
             }
             finally
@@ -461,7 +461,7 @@ namespace Lucene.Net.Util
         /// Read in a single partition of data. </summary>
         internal int ReadPartition(ByteSequencesReader reader)
         {
-            long start = Environment.TickCount;
+            long start = J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond; // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             var scratch = new BytesRef();
             while ((scratch.Bytes = reader.Read()) != null)
             {
@@ -474,7 +474,7 @@ namespace Lucene.Net.Util
                     break;
                 }
             }
-            sortInfo.ReadTime += (Environment.TickCount - start);
+            sortInfo.ReadTime += ((J2N.Time.NanoTime() / J2N.Time.MillisecondsPerNanosecond) - start); // LUCENENET: Use NanoTime() rather than CurrentTimeMilliseconds() for more accurate/reliable results
             return buffer.Length;
         }