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

DaanHoogland pushed a commit to branch 4.22
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/4.22 by this push:
     new 042ec7e1655 UI: fix usage records end date with local timezone (#13769)
042ec7e1655 is described below

commit 042ec7e1655eb9d4620eca4277eb69245b07e07d
Author: Brad <[email protected]>
AuthorDate: Wed Sep 2 09:21:46 2026 +0100

    UI: fix usage records end date with local timezone (#13769)
---
 ui/src/views/infra/UsageRecords.vue            |  4 +-
 ui/tests/unit/views/infra/UsageRecords.spec.js | 81 ++++++++++++++++++++++++++
 2 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/ui/src/views/infra/UsageRecords.vue 
b/ui/src/views/infra/UsageRecords.vue
index f206c11b713..78b213cdd3a 100644
--- a/ui/src/views/infra/UsageRecords.vue
+++ b/ui/src/views/infra/UsageRecords.vue
@@ -595,10 +595,10 @@ export default {
         page: page || this.page,
         pagesize: pageSize || this.pageSize
       }
-      if (values.dateRange) {
+      if (Array.isArray(values.dateRange) && values.dateRange[0] && 
values.dateRange[1]) {
         if (this.$store.getters.usebrowsertimezone) {
           params.startdate = 
dayjs.utc(dayjs(values.dateRange[0]).startOf('day')).format('YYYY-MM-DD 
HH:mm:ss')
-          params.enddate = 
dayjs.utc(dayjs(values.dateRange[0]).endOf('day')).format('YYYY-MM-DD HH:mm:ss')
+          params.enddate = 
dayjs.utc(dayjs(values.dateRange[1]).endOf('day')).format('YYYY-MM-DD HH:mm:ss')
         } else {
           params.startdate = 
dayjs(values.dateRange[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss')
           params.enddate = 
dayjs(values.dateRange[1]).endOf('day').format('YYYY-MM-DD HH:mm:ss')
diff --git a/ui/tests/unit/views/infra/UsageRecords.spec.js 
b/ui/tests/unit/views/infra/UsageRecords.spec.js
new file mode 100644
index 00000000000..5e9b2b0bcf5
--- /dev/null
+++ b/ui/tests/unit/views/infra/UsageRecords.spec.js
@@ -0,0 +1,81 @@
+// 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.
+
+import dayjs from 'dayjs'
+import utc from 'dayjs/plugin/utc'
+import UsageRecords from '@/views/infra/UsageRecords'
+
+dayjs.extend(utc)
+
+const dateWithOffset = (date, offsetMinutes) => 
dayjs(date).utcOffset(offsetMinutes, true)
+
+const getParams = (dateRange, useBrowserTimezone) => {
+  return UsageRecords.methods.getParams.call({
+    form: { dateRange },
+    handleRemoveFields: values => values,
+    page: 1,
+    pageSize: 20,
+    $store: {
+      getters: { usebrowsertimezone: useBrowserTimezone }
+    }
+  })
+}
+
+describe('Views > infra > UsageRecords.vue', () => {
+  describe('getParams()', () => {
+    it('uses both selected dates when converting a local-timezone range to 
UTC', () => {
+      const params = getParams([
+        dateWithOffset('2026-07-26', 60),
+        dateWithOffset('2026-08-02', 60)
+      ], true)
+
+      expect(params.startdate).toBe('2026-07-25 23:00:00')
+      expect(params.enddate).toBe('2026-08-02 22:59:59')
+    })
+
+    it('uses the selected end date when the range crosses daylight-saving 
time', () => {
+      const params = getParams([
+        dateWithOffset('2026-03-28', 0),
+        dateWithOffset('2026-03-30', 60)
+      ], true)
+
+      expect(params.startdate).toBe('2026-03-28 00:00:00')
+      expect(params.enddate).toBe('2026-03-30 22:59:59')
+    })
+
+    it('preserves both selected dates when browser-timezone conversion is 
disabled', () => {
+      const params = getParams(['2026-07-26', '2026-08-02'], false)
+
+      expect(params.startdate).toBe('2026-07-26 00:00:00')
+      expect(params.enddate).toBe('2026-08-02 23:59:59')
+    })
+
+    it('omits date parameters when no range is selected', () => {
+      const params = getParams([], true)
+
+      expect(params).not.toHaveProperty('startdate')
+      expect(params).not.toHaveProperty('enddate')
+    })
+
+    it('omits date parameters when the selected range is incomplete', () => {
+      const params = getParams([dateWithOffset('2026-07-26', 60)], true)
+
+      expect(params).not.toHaveProperty('startdate')
+      expect(params).not.toHaveProperty('enddate')
+    })
+  })
+})

Reply via email to