fix: the jql time zone issue (#4932)

diff --git a/backend/plugins/jira/tasks/issue_collector.go b/backend/plugins/jira/tasks/issue_collector.go
index 0e60cc5..6b36f87 100644
--- a/backend/plugins/jira/tasks/issue_collector.go
+++ b/backend/plugins/jira/tasks/issue_collector.go
@@ -23,6 +23,7 @@
 	"io"
 	"net/http"
 	"net/url"
+	"time"
 
 	"github.com/apache/incubator-devlake/core/errors"
 	"github.com/apache/incubator-devlake/core/plugin"
@@ -66,18 +67,8 @@
 	// build jql
 	// IMPORTANT: we have to keep paginated data in a consistence order to avoid data-missing, if we sort issues by
 	//  `updated`, issue will be jumping between pages if it got updated during the collection process
-	jql := "created is not null ORDER BY created ASC"
-
-	// timer filter
-	if data.TimeAfter != nil {
-		jql = fmt.Sprintf("updated >= '%v' AND %v", data.TimeAfter.Format("2006/01/02 15:04"), jql)
-	}
-
-	// diff sync
 	incremental := collectorWithState.IsIncremental()
-	if incremental {
-		jql = fmt.Sprintf("updated >= '%v' AND %v", collectorWithState.LatestState.LatestSuccessStart.Format("2006/01/02 15:04"), jql)
-	}
+	jql := buildJQL(data.TimeAfter, collectorWithState.LatestState.LatestSuccessStart, incremental)
 
 	err = collectorWithState.InitCollector(api.ApiCollectorArgs{
 		ApiClient:   data.ApiClient,
@@ -144,3 +135,24 @@
 
 	return collectorWithState.Execute()
 }
+
+// buildJQL build jql based on timeAfter and incremental mode
+func buildJQL(timeAfter, latestSuccessStart *time.Time, isIncremental bool) string {
+	jql := "ORDER BY created ASC"
+	var moment time.Time
+	if timeAfter != nil {
+		moment = *timeAfter
+	}
+	// if isIncremental is true, we should not collect data before latestSuccessStart
+	if isIncremental {
+		// subtract 24 hours to avoid missing data due to time zone difference
+		latest := latestSuccessStart.Add(-24 * time.Hour)
+		if latest.After(moment) {
+			moment = latest
+		}
+	}
+	if !moment.IsZero() {
+		jql = fmt.Sprintf("updated >= '%s' %s", moment.In(time.UTC).Format("2006/01/02 15:04"), jql)
+	}
+	return jql
+}
diff --git a/backend/plugins/jira/tasks/issue_collector_test.go b/backend/plugins/jira/tasks/issue_collector_test.go
new file mode 100644
index 0000000..3dba84e
--- /dev/null
+++ b/backend/plugins/jira/tasks/issue_collector_test.go
@@ -0,0 +1,93 @@
+/*
+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.
+*/
+
+package tasks
+
+import (
+	"testing"
+	"time"
+)
+
+func Test_buildJQL(t *testing.T) {
+	base := time.Date(2021, 2, 3, 4, 5, 6, 7, time.UTC)
+	timeAfter := base
+	add48 := base.Add(48 * time.Hour)
+	minus48 := base.Add(-48 * time.Hour)
+	type args struct {
+		timeAfter          *time.Time
+		latestSuccessStart *time.Time
+		isIncremental      bool
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "test incremental",
+			args: args{
+				timeAfter:          nil,
+				latestSuccessStart: nil,
+				isIncremental:      false,
+			},
+			want: "ORDER BY created ASC"},
+		{
+			name: "test incremental",
+			args: args{
+				timeAfter:          nil,
+				latestSuccessStart: &add48,
+				isIncremental:      true,
+			},
+			want: "updated >= '2021/02/04 04:05' ORDER BY created ASC",
+		},
+		{
+			name: "test incremental",
+			args: args{
+				timeAfter:          &base,
+				latestSuccessStart: nil,
+				isIncremental:      false,
+			},
+			want: "updated >= '2021/02/03 04:05' ORDER BY created ASC",
+		},
+		{
+			name: "test incremental",
+			args: args{
+				timeAfter:          &timeAfter,
+				latestSuccessStart: &add48,
+				isIncremental:      true,
+			},
+			want: "updated >= '2021/02/04 04:05' ORDER BY created ASC",
+		},
+		{
+			name: "test incremental",
+			args: args{
+				timeAfter:          &timeAfter,
+				latestSuccessStart: &minus48,
+				isIncremental:      true,
+			},
+			want: "updated >= '2021/02/03 04:05' ORDER BY created ASC",
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := buildJQL(tt.args.timeAfter, tt.args.latestSuccessStart, tt.args.isIncremental); got != tt.want {
+				t.Errorf("buildJQL() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}