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')
+ })
+ })
+})