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

imbajin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hugegraph-toolchain.git


The following commit(s) were added to refs/heads/master by this push:
     new bf8a46a0 fix(loader): enhance DateUtil with concurrent date parsing 
(#734)
bf8a46a0 is described below

commit bf8a46a064c65943b7b7e5ca4752148ff6a5b7e7
Author: Jason <[email protected]>
AuthorDate: Wed May 6 19:51:57 2026 +0800

    fix(loader): enhance DateUtil with concurrent date parsing (#734)
    
    
    
    ---------
    
    Signed-off-by: Jason <[email protected]>
---
 .../org/apache/hugegraph/loader/util/DateUtil.java | 19 ++++----
 .../hugegraph/loader/test/unit/DateUtilTest.java   | 54 ++++++++++++++++++++++
 2 files changed, 63 insertions(+), 10 deletions(-)

diff --git 
a/hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DateUtil.java 
b/hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DateUtil.java
index 670c70a0..caeada15 100644
--- 
a/hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DateUtil.java
+++ 
b/hugegraph-loader/src/main/java/org/apache/hugegraph/loader/util/DateUtil.java
@@ -18,16 +18,16 @@
 package org.apache.hugegraph.loader.util;
 
 import java.util.Date;
-import java.util.Map;
+import java.util.HashMap;
 import java.util.TimeZone;
-import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.hugegraph.date.SafeDateFormat;
 import org.apache.hugegraph.loader.constant.Constants;
 
 public final class DateUtil {
 
-    private static final Map<String, SafeDateFormat> DATE_FORMATS = new 
ConcurrentHashMap<>();
+    private static final ThreadLocal<HashMap<String, SafeDateFormat>> 
DATE_FORMATS =
+            ThreadLocal.withInitial(HashMap::new);
 
     public static Date parse(String source, String df) {
         return parse(source, df, Constants.TIME_ZONE);
@@ -35,19 +35,16 @@ public final class DateUtil {
 
     public static Date parse(String source, String df, String timeZone) {
         SafeDateFormat dateFormat = getDateFormat(df);
-        // parse date with specified timezone
         dateFormat.setTimeZone(timeZone);
         return dateFormat.parse(source);
     }
 
     private static SafeDateFormat getDateFormat(String df) {
-        SafeDateFormat dateFormat = DATE_FORMATS.get(df);
+        HashMap<String, SafeDateFormat> formats = DATE_FORMATS.get();
+        SafeDateFormat dateFormat = formats.get(df);
         if (dateFormat == null) {
             dateFormat = new SafeDateFormat(df);
-            SafeDateFormat previous = DATE_FORMATS.putIfAbsent(df, dateFormat);
-            if (previous != null) {
-                dateFormat = previous;
-            }
+            formats.put(df, dateFormat);
         }
         return dateFormat;
     }
@@ -58,7 +55,9 @@ public final class DateUtil {
     }
 
     public static String now(String df) {
-        return getDateFormat(df).format(new Date());
+        SafeDateFormat dateFormat = getDateFormat(df);
+        dateFormat.setTimeZone(Constants.TIME_ZONE);
+        return dateFormat.format(new Date());
     }
 
     public static boolean checkTimeZone(String timeZone) {
diff --git 
a/hugegraph-loader/src/test/java/org/apache/hugegraph/loader/test/unit/DateUtilTest.java
 
b/hugegraph-loader/src/test/java/org/apache/hugegraph/loader/test/unit/DateUtilTest.java
index 6370c897..08d2ab2a 100644
--- 
a/hugegraph-loader/src/test/java/org/apache/hugegraph/loader/test/unit/DateUtilTest.java
+++ 
b/hugegraph-loader/src/test/java/org/apache/hugegraph/loader/test/unit/DateUtilTest.java
@@ -17,6 +17,12 @@
 
 package org.apache.hugegraph.loader.test.unit;
 
+import java.util.Date;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.apache.hugegraph.loader.util.DateUtil;
 import org.junit.Test;
 
@@ -24,6 +30,13 @@ import org.apache.hugegraph.testutil.Assert;
 
 public class DateUtilTest {
 
+    @Test
+    public void testNowUsesDefaultTimeZone() {
+        String pattern = "Z";
+        DateUtil.parse("+0000", pattern, "GMT");
+        Assert.assertEquals("+0800", DateUtil.now(pattern));
+    }
+
     @Test
     public void testCheckTimeZone() {
         Assert.assertTrue(DateUtil.checkTimeZone("JST"));
@@ -70,4 +83,45 @@ public class DateUtilTest {
         // minutes 00-59 only
         Assert.assertFalse(DateUtil.checkTimeZone("GMT+13:60"));
     }
+
+    @Test
+    public void testConcurrentParseDateWithDifferentTimeZones() throws 
InterruptedException {
+        int threads = 10;
+        int iterations = 100;
+        ExecutorService executor = Executors.newFixedThreadPool(threads);
+        CountDownLatch latch = new CountDownLatch(threads);
+        AtomicInteger errors = new AtomicInteger(0);
+
+        String dateStr = "2024-01-15 12:00:00";
+        String pattern = "yyyy-MM-dd HH:mm:ss";
+        long expectedEpochGMT8 = DateUtil.parse(dateStr, pattern, 
"GMT+8").getTime();
+        long expectedEpochGMT0 = DateUtil.parse(dateStr, pattern, 
"GMT+0").getTime();
+        long expectedDiff = 8 * 60 * 60 * 1000;
+
+        for (int i = 0; i < threads; i++) {
+            final int threadId = i;
+            executor.submit(() -> {
+                try {
+                    String timeZone = threadId % 2 == 0 ? "GMT+8" : "GMT+0";
+                    long expectedEpoch = threadId % 2 == 0 ? expectedEpochGMT8 
: expectedEpochGMT0;
+                    for (int j = 0; j < iterations; j++) {
+                        Date result = DateUtil.parse(dateStr, pattern, 
timeZone);
+                        if (result == null || result.getTime() != 
expectedEpoch) {
+                            errors.incrementAndGet();
+                        }
+                    }
+                } catch (Exception e) {
+                    errors.incrementAndGet();
+                } finally {
+                    latch.countDown();
+                }
+            });
+        }
+
+        latch.await();
+        executor.shutdown();
+
+        Assert.assertEquals(0, errors.get());
+        Assert.assertEquals(expectedDiff, expectedEpochGMT0 - 
expectedEpochGMT8);
+    }
 }

Reply via email to