This is an automated email from the ASF dual-hosted git repository.
mcasters pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new c2dcbf7553 Fix#6754 incorrect date truncation logic in JavaScript
transform truncDate (#6759)
c2dcbf7553 is described below
commit c2dcbf755372310605de350b2dfe222a0aeed9f6
Author: lance <[email protected]>
AuthorDate: Thu Mar 12 03:13:28 2026 +0800
Fix#6754 incorrect date truncation logic in JavaScript transform truncDate
(#6759)
* Fix incorrect date truncation logic in JavaScript transform truncDate
Signed-off-by: lance <[email protected]>
* add javascript truncDate unit test
Signed-off-by: lance <[email protected]>
* add javascript truncDate unit test
Signed-off-by: lance <[email protected]>
---------
Signed-off-by: lance <[email protected]>
---
.../0066-script-javascript-truncDate.hpl | 192 +++++++++++++++++++++
.../golden-script-javascript-truncDate.csv | 2 +
.../golden-script-javascript-truncDate.json | 56 ++++++
.../0066-script-javascript-truncDate UNIT.json | 53 ++++++
.../javascript/ScriptValuesAddedFunctions.java | 15 +-
.../javascript/src/src/assembly/assembly.xml | 61 -------
.../src/src/main/resources/dependencies.xml | 23 ---
.../javascript/src/src/main/resources/version.xml | 20 ---
.../javascript/ScriptValuesAddedFunctionsTest.java | 24 ++-
9 files changed, 327 insertions(+), 119 deletions(-)
diff --git a/integration-tests/transforms/0066-script-javascript-truncDate.hpl
b/integration-tests/transforms/0066-script-javascript-truncDate.hpl
new file mode 100644
index 0000000000..86697c33cb
--- /dev/null
+++ b/integration-tests/transforms/0066-script-javascript-truncDate.hpl
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+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.
+
+-->
+<?xml version="1.0" encoding="UTF-8"?>
+<pipeline>
+ <info>
+ <name>0066-script-javascript-truncDate</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <pipeline_version/>
+ <pipeline_type>Normal</pipeline_type>
+ <parameters>
+ </parameters>
+ <capture_transform_performance>N</capture_transform_performance>
+
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+ <created_user>-</created_user>
+ <created_date>2026/03/11 21:34:59.574</created_date>
+ <modified_user>-</modified_user>
+ <modified_date>2026/03/11 21:34:59.574</modified_date>
+ </info>
+ <notepads>
+ </notepads>
+ <order>
+ <hop>
+ <from>Data grid</from>
+ <to>JavaScript</to>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>JavaScript</from>
+ <to>Dummy (do nothing)</to>
+ <enabled>Y</enabled>
+ </hop>
+ </order>
+ <transform>
+ <name>JavaScript</name>
+ <type>ScriptValueMod</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <optimizationLevel>9</optimizationLevel>
+ <jsScripts>
+ <jsScript>
+ <jsScript_type>0</jsScript_type>
+ <jsScript_name>Script 1</jsScript_name>
+ <jsScript_script>//Script here
+//Script here
+var dateTime = new Date(2026, 1, 12, 14, 30, 21);
+var date0 = truncDate(dateTime, 0);
+var date1 = truncDate(dateTime, 1);
+var date2 = truncDate(dateTime, 2);
+var date3 = truncDate(dateTime, 3);
+var date4 = truncDate(dateTime, 4);
+var date5 = truncDate(dateTime, 5);
+</jsScript_script>
+ </jsScript>
+ </jsScripts>
+ <fields>
+ <field>
+ <name>date0</name>
+ <rename>date0</rename>
+ <type>Date</type>
+ <length>-1</length>
+ <precision>-1</precision>
+ <replace>N</replace>
+ </field>
+ <field>
+ <name>date1</name>
+ <rename>date1</rename>
+ <type>Date</type>
+ <length>-1</length>
+ <precision>-1</precision>
+ <replace>N</replace>
+ </field>
+ <field>
+ <name>date2</name>
+ <rename>date2</rename>
+ <type>Date</type>
+ <length>-1</length>
+ <precision>-1</precision>
+ <replace>N</replace>
+ </field>
+ <field>
+ <name>date3</name>
+ <rename>date3</rename>
+ <type>Date</type>
+ <length>-1</length>
+ <precision>-1</precision>
+ <replace>N</replace>
+ </field>
+ <field>
+ <name>date4</name>
+ <rename>date4</rename>
+ <type>Date</type>
+ <length>-1</length>
+ <precision>-1</precision>
+ <replace>N</replace>
+ </field>
+ <field>
+ <name>date5</name>
+ <rename>date5</rename>
+ <type>Date</type>
+ <length>-1</length>
+ <precision>-1</precision>
+ <replace>N</replace>
+ </field>
+ </fields>
+ <attributes/>
+ <GUI>
+ <xloc>224</xloc>
+ <yloc>176</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>Data grid</name>
+ <type>DataGrid</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <data>
+ <line>
+ <item>1</item>
+ </line>
+ </data>
+ <fields>
+ <field>
+ <length>-1</length>
+ <precision>-1</precision>
+ <currency/>
+ <set_empty_string>N</set_empty_string>
+ <name>id</name>
+ <format/>
+ <group/>
+ <decimal/>
+ <type>Number</type>
+ </field>
+ </fields>
+ <attributes/>
+ <GUI>
+ <xloc>80</xloc>
+ <yloc>176</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>Dummy (do nothing)</name>
+ <type>Dummy</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <attributes/>
+ <GUI>
+ <xloc>384</xloc>
+ <yloc>176</yloc>
+ </GUI>
+ </transform>
+ <transform_error_handling>
+ </transform_error_handling>
+ <attributes/>
+</pipeline>
diff --git
a/integration-tests/transforms/datasets/golden-script-javascript-truncDate.csv
b/integration-tests/transforms/datasets/golden-script-javascript-truncDate.csv
new file mode 100644
index 0000000000..4acf7862e1
--- /dev/null
+++
b/integration-tests/transforms/datasets/golden-script-javascript-truncDate.csv
@@ -0,0 +1,2 @@
+date0,date1,date2,date3,date4,date5
+2026/02/12 14:30:21.000,2026/02/12 14:30:00.000,2026/02/12
14:00:00.000,2026/02/12 00:00:00.000,2026/02/01 00:00:00.000,2026/01/01
00:00:00.000
diff --git
a/integration-tests/transforms/metadata/dataset/golden-script-javascript-truncDate.json
b/integration-tests/transforms/metadata/dataset/golden-script-javascript-truncDate.json
new file mode 100644
index 0000000000..eee47e6749
--- /dev/null
+++
b/integration-tests/transforms/metadata/dataset/golden-script-javascript-truncDate.json
@@ -0,0 +1,56 @@
+{
+ "base_filename": "golden-script-javascript-truncDate.csv",
+ "name": "golden-script-javascript-truncDate",
+ "description": "",
+ "dataset_fields": [
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 3,
+ "field_precision": -1,
+ "field_name": "date0",
+ "field_format": "yyyy/MM/dd HH:mm:ss.SSS"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 3,
+ "field_precision": -1,
+ "field_name": "date1",
+ "field_format": "yyyy/MM/dd HH:mm:ss.SSS"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 3,
+ "field_precision": -1,
+ "field_name": "date2",
+ "field_format": "yyyy/MM/dd HH:mm:ss.SSS"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 3,
+ "field_precision": -1,
+ "field_name": "date3",
+ "field_format": "yyyy/MM/dd HH:mm:ss.SSS"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 3,
+ "field_precision": -1,
+ "field_name": "date4",
+ "field_format": "yyyy/MM/dd HH:mm:ss.SSS"
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 3,
+ "field_precision": -1,
+ "field_name": "date5",
+ "field_format": "yyyy/MM/dd HH:mm:ss.SSS"
+ }
+ ],
+ "folder_name": ""
+}
\ No newline at end of file
diff --git
a/integration-tests/transforms/metadata/unit-test/0066-script-javascript-truncDate
UNIT.json
b/integration-tests/transforms/metadata/unit-test/0066-script-javascript-truncDate
UNIT.json
new file mode 100644
index 0000000000..be443149ed
--- /dev/null
+++
b/integration-tests/transforms/metadata/unit-test/0066-script-javascript-truncDate
UNIT.json
@@ -0,0 +1,53 @@
+{
+ "database_replacements": [],
+ "autoOpening": true,
+ "description": "",
+ "persist_filename": "",
+ "test_type": "UNIT_TEST",
+ "variableValues": [],
+ "basePath": "${HOP_UNIT_TESTS_FOLDER}",
+ "golden_data_sets": [
+ {
+ "field_mappings": [
+ {
+ "transform_field": "date0",
+ "data_set_field": "date0"
+ },
+ {
+ "transform_field": "date1",
+ "data_set_field": "date1"
+ },
+ {
+ "transform_field": "date2",
+ "data_set_field": "date2"
+ },
+ {
+ "transform_field": "date3",
+ "data_set_field": "date3"
+ },
+ {
+ "transform_field": "date4",
+ "data_set_field": "date4"
+ },
+ {
+ "transform_field": "date5",
+ "data_set_field": "date5"
+ }
+ ],
+ "field_order": [
+ "date0",
+ "date1",
+ "date2",
+ "date3",
+ "date4",
+ "date5"
+ ],
+ "data_set_name": "golden-script-javascript-truncDate",
+ "transform_name": "Dummy (do nothing)"
+ }
+ ],
+ "input_data_sets": [],
+ "name": "0066-script-javascript-truncDate UNIT",
+ "trans_test_tweaks": [],
+ "pipeline_filename": "./0066-script-javascript-truncDate.hpl"
+}
\ No newline at end of file
diff --git
a/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesAddedFunctions.java
b/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesAddedFunctions.java
index 0f7a197fce..75d3c6e65f 100644
---
a/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesAddedFunctions.java
+++
b/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesAddedFunctions.java
@@ -2628,24 +2628,19 @@ public class ScriptValuesAddedFunctions extends
ScriptableObject {
// MONTHS
case 5:
cal.set(Calendar.MONTH, 0);
- break;
- // DAYS
+ // DAYS fall through
case 4:
cal.set(Calendar.DAY_OF_MONTH, 1);
- break;
- // HOURS
+ // HOURS fall through
case 3:
cal.set(Calendar.HOUR_OF_DAY, 0);
- break;
- // MINUTES
+ // MINUTES fall through
case 2:
cal.set(Calendar.MINUTE, 0);
- break;
- // SECONDS
+ // SECONDS fall through
case 1:
cal.set(Calendar.SECOND, 0);
- // MILI-SECONDS
- break;
+ // MILI-SECONDS fall through
case 0:
cal.set(Calendar.MILLISECOND, 0);
break;
diff --git a/plugins/transforms/javascript/src/src/assembly/assembly.xml
b/plugins/transforms/javascript/src/src/assembly/assembly.xml
deleted file mode 100644
index 2c5b8d5f4b..0000000000
--- a/plugins/transforms/javascript/src/src/assembly/assembly.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<!--
- ~ 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.
- ~
- -->
-
-<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0
http://maven.apache.org/xsd/assembly-2.2.0.xsd">
- <id>hop-transform-javascript</id>
- <formats>
- <format>zip</format>
- </formats>
- <baseDirectory>transforms/javascript</baseDirectory>
- <files>
- <file>
- <source>${project.basedir}/src/main/resources/version.xml</source>
- <outputDirectory>.</outputDirectory>
- <filtered>true</filtered>
- </file>
- <file>
-
<source>${project.basedir}/src/main/resources/dependencies.xml</source>
- <outputDirectory>.</outputDirectory>
- <filtered>true</filtered>
- </file>
- </files>
- <fileSets>
- <fileSet>
- <outputDirectory>lib</outputDirectory>
- <excludes>
- <exclude>**/*</exclude>
- </excludes>
- </fileSet>
- </fileSets>
- <dependencySets>
- <dependencySet>
-
- <includes>
- <include>org.apache.hop:hop-transform-javascript:jar</include>
- </includes>
- </dependencySet>
- <dependencySet>
-
- <includes>
- <include>org.apache.hop:hop-transform-javascript:jar</include>
- </includes>
- </dependencySet>
- </dependencySets>
-</assembly>
\ No newline at end of file
diff --git
a/plugins/transforms/javascript/src/src/main/resources/dependencies.xml
b/plugins/transforms/javascript/src/src/main/resources/dependencies.xml
deleted file mode 100644
index 10c1a13731..0000000000
--- a/plugins/transforms/javascript/src/src/main/resources/dependencies.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
- ~ 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.
- ~
- -->
-
-<dependencies>
- <folder>../fieldsplitter</folder>
- <folder>../rowgenerator</folder>
- <folder>../loadfileinput</folder>
-</dependencies>
\ No newline at end of file
diff --git a/plugins/transforms/javascript/src/src/main/resources/version.xml
b/plugins/transforms/javascript/src/src/main/resources/version.xml
deleted file mode 100644
index 6be576acae..0000000000
--- a/plugins/transforms/javascript/src/src/main/resources/version.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- ~
- -->
-
-<version>${project.version}</version>
\ No newline at end of file
diff --git
a/plugins/transforms/javascript/src/test/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesAddedFunctionsTest.java
b/plugins/transforms/javascript/src/test/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesAddedFunctionsTest.java
index 0511bdaee0..774f91ac63 100644
---
a/plugins/transforms/javascript/src/test/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesAddedFunctionsTest.java
+++
b/plugins/transforms/javascript/src/test/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesAddedFunctionsTest.java
@@ -20,39 +20,53 @@ package org.apache.hop.pipeline.transforms.javascript;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
+import org.apache.commons.lang3.time.DateFormatUtils;
import org.junit.jupiter.api.Test;
class ScriptValuesAddedFunctionsTest {
+ private static final String FORMATTER = "yyyy-MM-dd HH:mm:ss";
@Test
void testTruncDate() {
- Date dateBase = new Date(118, Calendar.FEBRUARY, 15, 11, 11, 11); //
2018-02-15 11:11:11
- Calendar c = Calendar.getInstance();
- c.set(2011, Calendar.NOVEMBER, 11, 11, 11, 11); // 2011-11-11 11:11:11
- c.set(Calendar.MILLISECOND, 11);
+ LocalDateTime time = LocalDateTime.of(2025, 2, 15, 11, 11, 11, 123);
+ Date dateBase = Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
- Date rtn = null;
+ Date rtn;
Calendar c2 = Calendar.getInstance();
rtn = ScriptValuesAddedFunctions.truncDate(dateBase, 5);
c2.setTime(rtn);
assertEquals(Calendar.JANUARY, c2.get(Calendar.MONTH));
+ assertEquals("2025-01-01 00:00:00", DateFormatUtils.format(rtn,
FORMATTER));
+
rtn = ScriptValuesAddedFunctions.truncDate(dateBase, 4);
c2.setTime(rtn);
assertEquals(1, c2.get(Calendar.DAY_OF_MONTH));
+ assertEquals("2025-02-01 00:00:00", DateFormatUtils.format(rtn,
FORMATTER));
+
rtn = ScriptValuesAddedFunctions.truncDate(dateBase, 3);
c2.setTime(rtn);
assertEquals(0, c2.get(Calendar.HOUR_OF_DAY));
+ assertEquals("2025-02-15 00:00:00", DateFormatUtils.format(rtn,
FORMATTER));
+
rtn = ScriptValuesAddedFunctions.truncDate(dateBase, 2);
c2.setTime(rtn);
assertEquals(0, c2.get(Calendar.MINUTE));
+ assertEquals("2025-02-15 11:00:00", DateFormatUtils.format(rtn,
FORMATTER));
+
rtn = ScriptValuesAddedFunctions.truncDate(dateBase, 1);
c2.setTime(rtn);
assertEquals(0, c2.get(Calendar.SECOND));
+ assertEquals("2025-02-15 11:11:00", DateFormatUtils.format(rtn,
FORMATTER));
+
rtn = ScriptValuesAddedFunctions.truncDate(dateBase, 0);
c2.setTime(rtn);
assertEquals(0, c2.get(Calendar.MILLISECOND));
+ assertEquals("2025-02-15 11:11:11", DateFormatUtils.format(rtn,
FORMATTER));
+
try {
ScriptValuesAddedFunctions.truncDate(rtn, 6); // Should throw exception
fail("Expected exception - passed in level > 5 to truncDate");