Skip to content

Commit 6de6379

Browse files
committed
formatted values with respect to selective timeZone
1 parent 056337c commit 6de6379

File tree

7 files changed

+140
-77
lines changed

7 files changed

+140
-77
lines changed

client/packages/lowcoder/src/comps/comps/dateComp/dateComp.tsx

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import _, { noop } from "lodash";
22
import dayjs from "dayjs";
3-
import utc from 'dayjs/plugin/utc';
43
import { RecordConstructorToComp, RecordConstructorToView } from "lowcoder-core";
54
import {
65
BoolCodeControl,
@@ -53,8 +52,6 @@ import { dropdownControl } from "comps/controls/dropdownControl";
5352
import { timeZoneOptions } from "./timeZone";
5453

5554

56-
dayjs.extend(utc);
57-
5855

5956
const EventOptions = [changeEvent, focusEvent, blurEvent] as const;
6057

@@ -87,7 +84,7 @@ const commonChildren = {
8784
...validationChildren,
8885
viewRef: RefControl<CommonPickerMethods>,
8986
inputFieldStyle: styleControl(DateTimeStyle, 'inputFieldStyle'),
90-
timeZone: dropdownControl(timeZoneOptions, "Etc/UTC"),
87+
timeZone: dropdownControl(timeZoneOptions, Intl.DateTimeFormat().resolvedOptions().timeZone),
9188
};
9289
type CommonChildrenType = RecordConstructorToComp<typeof commonChildren>;
9390

@@ -145,7 +142,7 @@ function validate(
145142

146143
const childrenMap = {
147144
value: stringExposingStateControl("value"),
148-
userTimeZone: stringExposingStateControl("userTimeZone", 'Etc/UTC'),
145+
userTimeZone: stringExposingStateControl("userTimeZone", Intl.DateTimeFormat().resolvedOptions().timeZone),
149146
...commonChildren,
150147
...formDataChildren,
151148
};
@@ -306,7 +303,7 @@ export const dateRangeControl = (function () {
306303
const childrenMap = {
307304
start: stringExposingStateControl("start"),
308305
end: stringExposingStateControl("end"),
309-
userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , 'Etc/UTC'),
306+
userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , Intl.DateTimeFormat().resolvedOptions().timeZone),
310307
...formDataChildren,
311308
...commonChildren,
312309
};
@@ -465,6 +462,14 @@ export const dateRangeControl = (function () {
465462
.build();
466463
})();
467464

465+
const getTimeZoneInfo = (timeZone: any, othereTimeZone: any) => {
466+
const tz = timeZone === 'UserChoice' ? othereTimeZone : timeZone ;
467+
return {
468+
TimeZone: tz,
469+
Offset: dayjs().tz(tz).format('Z') // Get the UTC offset for the selected timezone
470+
};
471+
};
472+
468473
export const DatePickerComp = withExposingConfigs(datePickerControl, [
469474
depsConfig({
470475
name: "value",
@@ -478,10 +483,16 @@ export const DatePickerComp = withExposingConfigs(datePickerControl, [
478483
depsConfig({
479484
name: "formattedValue",
480485
desc: trans("export.datePickerFormattedValueDesc"),
481-
depKeys: ["value", "format"],
486+
depKeys: ["value", "format", "timeZone", "userTimeZone"],
482487
func: (input) => {
483488
const mom = Boolean(input.value) ? dayjs(input.value, DateParser) : null;
484-
return mom?.isValid() ? mom.format(input.format) : "";
489+
const tz = input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone; // Get the selected timezone
490+
const timeInTz = mom?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time)
491+
return mom?.isValid()
492+
? (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z'
493+
? timeInTz?.format(input?.format) // Return formattedDateWithoffset if format includes 'Z' or is not available
494+
: mom.format(input.format) // Otherwise, return mom.format(input.format)
495+
: "";
485496
},
486497
}),
487498
depsConfig({
@@ -507,11 +518,8 @@ export const DatePickerComp = withExposingConfigs(datePickerControl, [
507518
name: "timeZone",
508519
desc: trans("export.timeZoneDesc"),
509520
depKeys: ["timeZone", "userTimeZone"],
510-
func: (input) => {
511-
console.log("input.timeZone", input.timeZone)
512-
return input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC';
521+
func: (input: { timeZone: any; userTimeZone: any; }) => getTimeZoneInfo(input.timeZone, input.userTimeZone)
513522

514-
},
515523
}),
516524
...CommonNameConfig,
517525
]);
@@ -556,36 +564,58 @@ export let DateRangeComp = withExposingConfigs(dateRangeControl, [
556564
depsConfig({
557565
name: "formattedValue",
558566
desc: trans("export.dateRangeFormattedValueDesc"),
559-
depKeys: ["start", "end", "format"],
567+
depKeys: ["start", "end", "format" , "timeZone", "userRangeTimeZone"],
560568
func: (input) => {
561569
const start = Boolean(input.start) ? dayjs(input.start, DateParser): null;
562570
const end = Boolean(input.end) ? dayjs(input.end, DateParser): null;
571+
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone; // Get the selected timezone
572+
const startTimeInTz = start?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time)
573+
const endTimeInTz = end?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time)
574+
563575
return [
564-
start?.isValid() && start.format(input.format),
565-
end?.isValid() && end.format(input.format),
576+
start?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z'
577+
? startTimeInTz?.format(input?.format) // Return formattedDateWithoffset if format includes 'Z' or is not available
578+
: start?.format(input.format),
579+
end?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z'
580+
? endTimeInTz?.format(input?.format) // Return formattedDateWithoffset if format includes 'Z' or is not available
581+
: end?.format(input.format) ,
566582
]
567583
.filter((item) => item)
568584
.join(" - ");
569585
},
570586
}),
571587
depsConfig({
572-
name: "formattedStartValue",
573-
desc: trans("export.dateRangeFormattedStartValueDesc"),
574-
depKeys: ["start", "format"],
575-
func: (input) => {
576-
const start = Boolean(input.start) ? dayjs(input.start, DateParser): null;
577-
return start?.isValid() && start.format(input.format);
578-
},
579-
}),
588+
name: "formattedStartValue",
589+
desc: trans("export.dateRangeFormattedStartValueDesc"),
590+
depKeys: ["start", "format", "timeZone", "userRangeTimeZone"],
591+
func: (input) => {
592+
const start = Boolean(input.start) ? dayjs(input.start, DateParser): null;
593+
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone;
594+
const startTimeInTz = start?.clone().tz(tz, true);
595+
return start?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z'))
596+
? startTimeInTz?.format(input?.format)
597+
: start?.format(input.format);
598+
},
599+
}),
580600
depsConfig({
581601
name: "formattedEndValue",
582602
desc: trans("export.dateRangeFormattedEndValueDesc"),
583-
depKeys: ["end", "format"],
603+
depKeys: ["end", "format" , "timeZone", "userRangeTimeZone"],
584604
func: (input) => {
585605
const end = Boolean(input.end) ? dayjs(input.end, DateParser): null;
586-
return end?.isValid() && end.format(input.format);
606+
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone;
607+
const endTimeInTz = end?.clone().tz(tz, true);
608+
return end?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z'))
609+
? endTimeInTz?.format(input?.format)
610+
: end?.format(input.format);
587611
},
588612
}),
613+
depsConfig({
614+
name: "timeZone",
615+
desc: trans("export.timeZoneDesc"),
616+
depKeys: ["timeZone", "userRangeTimeZone"],
617+
func: (input:any) => getTimeZoneInfo(input.timeZone, input.userRangeTimeZone)
618+
}),
589619
depsConfig({
590620
name: "invalid",
591621
desc: trans("export.invalidDesc"),

client/packages/lowcoder/src/comps/comps/dateComp/dateRangeUIView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export const DateRangeUIView = (props: DateRangeUIViewProps) => {
8282
<StyledAntdSelect
8383
options={timeZoneOptions.filter(option => option.value !== 'UserChoice')}
8484
placeholder="Select Time Zone"
85-
defaultValue={'(UTC 00:00) UTC'}
85+
defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone}
8686
onChange={props?.onClickDateRangeTimeZone}
8787
/>
8888
</StyledDiv>

client/packages/lowcoder/src/comps/comps/dateComp/dateUIView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export const DateUIView = (props: DataUIViewProps) => {
7070
<StyledAntdSelect
7171
options={timeZoneOptions.filter(option => option.value !== 'UserChoice')}
7272
placeholder="Select Time Zone"
73-
defaultValue={'(UTC 00:00) UTC'}
73+
defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone}
7474
onChange={props.onClickDateTimeZone}
7575
/>
7676
</StyledDiv>

client/packages/lowcoder/src/comps/comps/dateComp/timeComp.tsx

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import _ from "lodash";
22
import dayjs from "dayjs";
3-
import utc from 'dayjs/plugin/utc';
43
import { RecordConstructorToComp, RecordConstructorToView } from "lowcoder-core";
54
import {
65
BoolCodeControl,
@@ -56,7 +55,6 @@ import { EditorContext } from "comps/editorState";
5655
import { dropdownControl } from "comps/controls/dropdownControl";
5756
import { timeZoneOptions } from "./timeZone";
5857

59-
dayjs.extend(utc);
6058

6159
const EventOptions = [changeEvent, focusEvent, blurEvent] as const;
6260

@@ -86,7 +84,7 @@ const commonChildren = {
8684
),
8785
inputFieldStyle: styleControl(DateTimeStyle, 'inputFieldStyle'),
8886
suffixIcon: withDefault(IconControl, "/icon:regular/clock"),
89-
timeZone: dropdownControl(timeZoneOptions, "Etc/UTC"),
87+
timeZone: dropdownControl(timeZoneOptions, Intl.DateTimeFormat().resolvedOptions().timeZone),
9088
viewRef: RefControl<CommonPickerMethods>,
9189
...validationChildren,
9290
};
@@ -126,7 +124,7 @@ function validate(
126124

127125
const childrenMap = {
128126
value: stringExposingStateControl("value"),
129-
userTimeZone: stringExposingStateControl("userTimeZone" , 'Etc/UTC'),
127+
userTimeZone: stringExposingStateControl("userTimeZone", Intl.DateTimeFormat().resolvedOptions().timeZone),
130128
...commonChildren,
131129
...formDataChildren,
132130
};
@@ -271,7 +269,7 @@ export const timeRangeControl = (function () {
271269
const childrenMap = {
272270
start: stringExposingStateControl("start"),
273271
end: stringExposingStateControl("end"),
274-
userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , 'Etc/UTC'),
272+
userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , Intl.DateTimeFormat().resolvedOptions().timeZone),
275273
...formDataChildren,
276274
...commonChildren,
277275
};
@@ -416,26 +414,38 @@ export const timeRangeControl = (function () {
416414
.build();
417415
})();
418416

417+
const getTimeZoneInfo = (timeZone: any, othereTimeZone: any) => {
418+
const tz = timeZone === 'UserChoice' ? othereTimeZone : timeZone ;
419+
return {
420+
TimeZone: tz,
421+
Offset: dayjs().tz(tz).format('Z') // Get the UTC offset for the selected timezone
422+
};
423+
};
424+
419425
export const TimePickerComp = withExposingConfigs(timePickerControl, [
420426
new NameConfig("value", trans("export.timePickerValueDesc")),
421427

422428
depsConfig({
423429
name: "formattedValue",
424430
desc: trans("export.timePickerFormattedValueDesc"),
425-
depKeys: ["value", "format"],
431+
depKeys: ["value", "format", "timeZone", "userTimeZone"],
426432
func: (input) => {
427433
const mom = Boolean(input.value) ? dayjs(input.value, TimeParser) : null;
428-
return mom?.isValid() ? mom.format(input.format) : '';
434+
const tz = input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone; // Get the selected timezone
435+
const timeInTz = mom?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time)
436+
const formattedTimeWithoffset = timeInTz?.format(input?.format);
437+
return mom?.isValid() ? (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z'
438+
? formattedTimeWithoffset // Return formattedDateWithoffset if format includes 'Z' or is not available
439+
: mom.format(input.format) // Otherwise, return mom.format(input.format)
440+
: "";
429441
},
430442
}),
431443

432444
depsConfig({
433445
name: "timeZone",
434446
desc: trans("export.timeZoneDesc"),
435447
depKeys: ["timeZone", "userTimeZone"],
436-
func: (input) => {
437-
return input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC';
438-
},
448+
func: (input: { timeZone: any; userTimeZone: any; }) => getTimeZoneInfo(input.timeZone, input.userTimeZone)
439449
}),
440450
depsConfig({
441451
name: "invalid",
@@ -456,13 +466,20 @@ export let TimeRangeComp = withExposingConfigs(timeRangeControl, [
456466
depsConfig({
457467
name: "formattedValue",
458468
desc: trans("export.timeRangeFormattedValueDesc"),
459-
depKeys: ["start", "end", "format"],
469+
depKeys: ["start", "end", "format", "timeZone", "userRangeTimeZone"],
460470
func: (input) => {
461471
const start = Boolean(input.start) ? dayjs(input.start, TimeParser) : null;
462472
const end = Boolean(input.end) ? dayjs(input.end, TimeParser) : null;
473+
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone; // Get the selected timezone
474+
const startTimeInTz = start?.clone().tz(tz, true); // Apply the selected timezone without altering the time itself (do not convert the time)
475+
const endTimeInTz = end?.clone().tz(tz, true);
463476
return [
464-
start?.isValid() && start.format(input.format),
465-
end?.isValid() && end.format(input.format),
477+
start?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z')) // Check if format is not available or contains 'Z'
478+
? startTimeInTz?.format(input?.format) // Return formattedTimeWithoffset if format includes 'Z' or is not available
479+
: start?.format(input.format),
480+
end?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z'))
481+
? endTimeInTz?.format(input?.format)
482+
: end?.format(input.format) ,
466483
]
467484
.filter((item) => item)
468485
.join(" - ");
@@ -471,21 +488,37 @@ export let TimeRangeComp = withExposingConfigs(timeRangeControl, [
471488
depsConfig({
472489
name: "formattedStartValue",
473490
desc: trans("export.timeRangeFormattedStartValueDesc"),
474-
depKeys: ["start", "format"],
491+
depKeys: ["start", "format" , "timeZone", "userRangeTimeZone"],
475492
func: (input) => {
476493
const start = Boolean(input.start) ? dayjs(input.start, TimeParser) : null;
477-
return start?.isValid() && start.format(input.format);
494+
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone;
495+
const startTimeInTz = start?.clone().tz(tz, true);
496+
const formattedDate = startTimeInTz?.format(input?.format);
497+
return start?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z'))
498+
? formattedDate
499+
: start?.format(input.format);
478500
},
479501
}),
480502
depsConfig({
481503
name: "formattedEndValue",
482504
desc: trans("export.timeRangeFormattedEndValueDesc"),
483-
depKeys: ["end", "format"],
505+
depKeys: ["end", "format", "timeZone", "userRangeTimeZone"],
484506
func: (input) => {
485507
const end = Boolean(input.end) ? dayjs(input.end, TimeParser) : null;
486-
return end?.isValid() && end.format(input.format);
508+
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone;
509+
const endTimeInTz = end?.clone().tz(tz, true);
510+
return end?.isValid() && (!input.format || input.format.includes('Z') || input.format.includes('z'))
511+
? endTimeInTz?.format(input?.format)
512+
: end?.format(input.format);
487513
},
488514
}),
515+
depsConfig({
516+
name: "timeZone",
517+
desc: trans("export.timeZoneDesc"),
518+
depKeys: ["timeZone", "userRangeTimeZone"],
519+
func: (input:any) => getTimeZoneInfo(input.timeZone, input.userRangeTimeZone)
520+
521+
}),
489522
depsConfig({
490523
name: "invalid",
491524
desc: trans("export.invalidDesc"),

client/packages/lowcoder/src/comps/comps/dateComp/timeRangeUIView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export const TimeRangeUIView = (props: TimeRangeUIViewProps) => {
7171
<StyledAntdSelect
7272
placeholder="Select Time Zone"
7373
options={timeZoneOptions.filter(option => option.value !== 'UserChoice')} // Filter out 'userChoice'
74-
defaultValue={'(UTC 00:00) UTC'}
74+
defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone}
7575
onChange={props.handleTimeRangeZoneChange}
7676
/>
7777
)

client/packages/lowcoder/src/comps/comps/dateComp/timeUIView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const TimeUIView = (props: TimeUIViewProps) => {
5454
placeholder="Select Time Zone"
5555
options={timeZoneOptions.filter(option => option.value !== 'UserChoice')} // Filter out 'userChoice'
5656
onChange={props?.handleTimeZoneChange}
57-
defaultValue={'(UTC 00:00) UTC'}
57+
defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone}
5858
/>
5959
)
6060
)}

0 commit comments

Comments
 (0)