Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b2212f7

Browse files
Merge pull request #1151 from MenamAfzal/add/time-zone
Add/time zone
2 parents 97904f7 + 286c500 commit b2212f7

File tree

8 files changed

+173
-394
lines changed

8 files changed

+173
-394
lines changed

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

Lines changed: 89 additions & 245 deletions
Large diffs are not rendered by default.

‎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={'Etc/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={'Etc/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: 61 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import _ from "lodash";
22
import dayjs from "dayjs";
3-
import utc from 'dayjs/plugin/utc';
4-
import timezone from 'dayjs/plugin/timezone';
5-
import customParseFormat from 'dayjs/plugin/customParseFormat';
63
import { RecordConstructorToComp, RecordConstructorToView } from "lowcoder-core";
74
import {
85
BoolCodeControl,
@@ -58,9 +55,6 @@ import { EditorContext } from "comps/editorState";
5855
import { dropdownControl } from "comps/controls/dropdownControl";
5956
import { timeZoneOptions } from "./timeZone";
6057

61-
dayjs.extend(utc);
62-
dayjs.extend(timezone);
63-
dayjs.extend(customParseFormat);
6458

6559
const EventOptions = [changeEvent, focusEvent, blurEvent] as const;
6660

@@ -90,7 +84,7 @@ const commonChildren = {
9084
),
9185
inputFieldStyle: styleControl(DateTimeStyle, 'inputFieldStyle'),
9286
suffixIcon: withDefault(IconControl, "/icon:regular/clock"),
93-
timeZone: dropdownControl(timeZoneOptions, "Etc/UTC"),
87+
timeZone: dropdownControl(timeZoneOptions, Intl.DateTimeFormat().resolvedOptions().timeZone),
9488
viewRef: RefControl<CommonPickerMethods>,
9589
...validationChildren,
9690
};
@@ -130,7 +124,7 @@ function validate(
130124

131125
const childrenMap = {
132126
value: stringExposingStateControl("value"),
133-
userTimeZone: stringExposingStateControl("userTimeZone",'Etc/UTC'),
127+
userTimeZone: stringExposingStateControl("userTimeZone",Intl.DateTimeFormat().resolvedOptions().timeZone),
134128
...commonChildren,
135129
...formDataChildren,
136130
};
@@ -275,7 +269,7 @@ export const timeRangeControl = (function () {
275269
const childrenMap = {
276270
start: stringExposingStateControl("start"),
277271
end: stringExposingStateControl("end"),
278-
userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , 'Etc/UTC'),
272+
userRangeTimeZone: stringExposingStateControl("userRangeTimeZone" , Intl.DateTimeFormat().resolvedOptions().timeZone),
279273
...formDataChildren,
280274
...commonChildren,
281275
};
@@ -420,38 +414,39 @@ export const timeRangeControl = (function () {
420414
.build();
421415
})();
422416

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+
423425
export const TimePickerComp = withExposingConfigs(timePickerControl, [
424426
new NameConfig("value", trans("export.timePickerValueDesc")),
425427

426428
depsConfig({
427429
name: "formattedValue",
428430
desc: trans("export.timePickerFormattedValueDesc"),
429-
depKeys: ["value", "format", "timeZone", "userTimeZone"],
431+
depKeys: ["value", "format", "timeZone", "userTimeZone"],
430432
func: (input) => {
431-
let mom = null;
432-
433-
// Loop through TimeParser to find a valid format
434-
for (const format of TimeParser) {
435-
if (dayjs.utc(input.value, format).isValid()) {
436-
mom = dayjs.utc(input.value, format);
437-
break;
438-
}
439-
}
440-
441-
const tz = input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC';
442-
return mom?.isValid() ? mom.tz(tz).format(input.format) : '';
433+
const mom = Boolean(input.value) ? dayjs(input.value, TimeParser) : null;
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+
: "";
443441
},
444442
}),
445443

446444
depsConfig({
447445
name: "timeZone",
448446
desc: trans("export.timeZoneDesc"),
449447
depKeys: ["timeZone", "userTimeZone"],
450-
func: (input) => {
451-
return input.timeZone === 'UserChoice' ? input.userTimeZone : input.timeZone || 'UTC';
452-
},
448+
func: (input: { timeZone: any; userTimeZone: any; }) => getTimeZoneInfo(input.timeZone, input.userTimeZone)
453449
}),
454-
455450
depsConfig({
456451
name: "invalid",
457452
desc: trans("export.invalidDesc"),
@@ -460,158 +455,87 @@ export const TimePickerComp = withExposingConfigs(timePickerControl, [
460455
validate({
461456
...input,
462457
value: { value: input.value },
463-
}).validateStatus !== "success",
458+
}asany).validateStatus !== "success",
464459
}),
465-
466460
...CommonNameConfig,
467461
]);
468462

469-
470463
export let TimeRangeComp = withExposingConfigs(timeRangeControl, [
471-
// new NameConfig("start", trans("export.timeRangeStartDesc")),
472-
// new NameConfig("end", trans("export.timeRangeEndDesc")),
473-
depsConfig({
474-
name: "start",
475-
desc: trans("export.timeRangeStartDesc"),
476-
depKeys: ["start", "timeZone", "userRangeTimeZone"],
477-
func: (input) => {
478-
let start = null;
479-
480-
// Loop through TimeParser to find a valid format for start
481-
for (const format of TimeParser) {
482-
if (dayjs.utc(input.start, format).isValid()) {
483-
start = dayjs.utc(input.start, format);
484-
break;
485-
}
486-
}
487-
488-
if (start?.hour() === 0 && start?.minute() === 0 && start?.second() === 0) {
489-
start = start?.hour(12);
490-
}
491-
492-
// Apply timezone conversion if valid
493-
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC';
494-
return start?.isValid() ? start.tz(tz).format(input.format || "HH:mm:ss") : null;
495-
},
496-
}),
497-
498-
depsConfig({
499-
name: "end",
500-
desc: trans("export.timeRangeEndDesc"),
501-
depKeys: ["end", "timeZone", "userRangeTimeZone"],
502-
func: (input) => {
503-
let end = null;
504-
505-
// Loop through TimeParser to find a valid format for end
506-
for (const format of TimeParser) {
507-
if (dayjs.utc(input.end, format).isValid()) {
508-
end = dayjs.utc(input.end, format);
509-
break;
510-
}
511-
}
512-
513-
// Apply timezone conversion if valid
514-
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC';
515-
return end?.isValid() ? end.tz(tz).format(input.format || "HH:mm:ss") : null;
516-
},
517-
}),
518-
464+
new NameConfig("start", trans("export.timeRangeStartDesc")),
465+
new NameConfig("end", trans("export.timeRangeEndDesc")),
519466
depsConfig({
520467
name: "formattedValue",
521468
desc: trans("export.timeRangeFormattedValueDesc"),
522469
depKeys: ["start", "end", "format", "timeZone", "userRangeTimeZone"],
523470
func: (input) => {
524-
let start = null;
525-
let end = null;
526-
for (const format of TimeParser) {
527-
if (dayjs.utc(input.start, format).isValid()) {
528-
start = dayjs.utc(input.start, format);
529-
break;
530-
}
531-
}
532-
for (const format of TimeParser) {
533-
if (dayjs.utc(input.end, format).isValid()) {
534-
end = dayjs.utc(input.end, format);
535-
break;
536-
}
537-
}
538-
539-
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC';
540-
const formattedStart = start?.isValid() ? start.tz(tz).format(input.format) : '';
541-
const formattedEnd = end?.isValid() ? end.tz(tz).format(input.format) : '';
542-
543-
return [formattedStart, formattedEnd].filter(Boolean).join(" - ");
471+
const start = Boolean(input.start) ? dayjs(input.start, TimeParser) : null;
472+
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);
476+
return [
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) ,
483+
]
484+
.filter((item) => item)
485+
.join(" - ");
544486
},
545487
}),
546-
547488
depsConfig({
548489
name: "formattedStartValue",
549490
desc: trans("export.timeRangeFormattedStartValueDesc"),
550-
depKeys: ["start", "format", "timeZone", "userRangeTimeZone"],
491+
depKeys: ["start", "format", "timeZone", "userRangeTimeZone"],
551492
func: (input) => {
552-
let start = null;
553-
for (const format of TimeParser) {
554-
if (dayjs.utc(input.start, format).isValid()) {
555-
start = dayjs.utc(input.start, format);
556-
break;
557-
}
558-
}
559-
560-
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC';
561-
return start?.isValid() ? start.tz(tz).format(input.format) : '';
493+
const start = Boolean(input.start) ? dayjs(input.start, TimeParser) : null;
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);
562500
},
563501
}),
564-
565502
depsConfig({
566503
name: "formattedEndValue",
567504
desc: trans("export.timeRangeFormattedEndValueDesc"),
568505
depKeys: ["end", "format", "timeZone", "userRangeTimeZone"],
569506
func: (input) => {
570-
let end = null;
571-
for (const format of TimeParser) {
572-
if (dayjs.utc(input.end, format).isValid()) {
573-
end = dayjs.utc(input.end, format);
574-
break;
575-
}
576-
}
577-
578-
const tz = input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC';
579-
return end?.isValid() ? end.tz(tz).format(input.format) : '';
507+
const end = Boolean(input.end) ? dayjs(input.end, TimeParser) : null;
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);
580513
},
581514
}),
582-
583515
depsConfig({
584516
name: "timeZone",
585517
desc: trans("export.timeZoneDesc"),
586518
depKeys: ["timeZone", "userRangeTimeZone"],
587-
func: (input) => {
588-
return input.timeZone === 'UserChoice' ? input.userRangeTimeZone : input.timeZone || 'UTC';
589-
},
590-
}),
519+
func: (input:any) => getTimeZoneInfo(input.timeZone, input.userRangeTimeZone)
591520

521+
}),
592522
depsConfig({
593523
name: "invalid",
594524
desc: trans("export.invalidDesc"),
595525
depKeys: ["start", "end", "required", "minTime", "maxTime", "customRule"],
596-
func: (input) =>{
597-
conststartInvalid=validate({
526+
func: (input) =>
527+
validate({
598528
...input,
599529
value: { value: input.start },
600-
}).validateStatus !== "success";
601-
602-
const endInvalid = validate({
530+
}).validateStatus !== "success" ||
531+
validate({
603532
...input,
604533
value: { value: input.end },
605-
}).validateStatus !== "success";
606-
607-
return startInvalid || endInvalid;
608-
},
534+
}).validateStatus !== "success",
609535
}),
610-
611536
...CommonNameConfig,
612537
]);
613538

614-
615539
TimeRangeComp = withMethodExposing(TimeRangeComp, [
616540
...dateRefMethods,
617541
{
@@ -653,4 +577,4 @@ TimeRangeComp = withMethodExposing(TimeRangeComp, [
653577
comp.children.end.getView().onChange(data.end);
654578
},
655579
},
656-
]);
580+
]);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const RangePickerStyled = styled((props: any) => <RangePicker {...props} />)<{ $
2121
`;
2222

2323
const StyledAntdSelect = styled(AntdSelect)`
24-
width: 100%;
24+
width: 300px;
2525
margin: 10px 0px;
2626
.ant-select-selector {
2727
font-size: 14px;
@@ -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={'Etc/UTC'}
74+
defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone}
7575
onChange={props.handleTimeRangeZoneChange}
7676
/>
7777
)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const TimeMobileUIView = React.lazy(() =>
2121
);
2222

2323
const StyledAntdSelect = styled(AntdSelect)`
24-
width: 100%;
24+
width: 300px;
2525
margin: 10px 0;
2626
.ant-select-selector {
2727
font-size: 14px;
@@ -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={'Etc/UTC'}
57+
defaultValue={Intl.DateTimeFormat().resolvedOptions().timeZone}
5858
/>
5959
)
6060
)}
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { trans } from "i18n";
22

33
export const timeZoneOptions = [
4-
{ label: trans("timeZone.UTC-12:00"), value: "Etc/GMT+12" },
5-
{ label: trans("timeZone.UTC-11:00"), value: "Etc/GMT+11" },
4+
{ label: trans("timeZone.UserChoice"), value: "UserChoice" },
5+
{ label: trans("timeZone.UTC-12:00"), value: "Pacific/Baker" },
6+
{ label: trans("timeZone.UTC-11:00"), value: "Pacific/Niue" },
67
{ label: trans("timeZone.UTC-10:00"), value: "Pacific/Honolulu" },
78
{ label: trans("timeZone.UTC-09:00"), value: "America/Anchorage" },
89
{ label: trans("timeZone.UTC-08:00"), value: "America/Tijuana" },
@@ -11,7 +12,7 @@ export const timeZoneOptions = [
1112
{ label: trans("timeZone.UTC-05:00"), value: "America/New_York" },
1213
{ label: trans("timeZone.UTC-04:00"), value: "America/Halifax" },
1314
{ label: trans("timeZone.UTC-03:00"), value: "America/Argentina/Buenos_Aires" },
14-
{ label: trans("timeZone.UTC-02:00"), value: "Etc/GMT+2" },
15+
{ label: trans("timeZone.UTC-02:00"), value: "Atlantic/South_Georgia" },
1516
{ label: trans("timeZone.UTC-01:00"), value: "Atlantic/Cape_Verde" },
1617
{ label: trans("timeZone.UTC+00:00"), value: "Etc/UTC" },
1718
{ label: trans("timeZone.UTC+01:00"), value: "Europe/Berlin" },
@@ -20,10 +21,15 @@ export const timeZoneOptions = [
2021
{ label: trans("timeZone.UTC+04:00"), value: "Asia/Dubai" },
2122
{ label: trans("timeZone.UTC+05:00"), value: "Asia/Karachi" },
2223
{ label: trans("timeZone.UTC+05:30"), value: "Asia/Kolkata" },
24+
{ label: trans("timeZone.UTC+05:45"), value: "Asia/Kathmandu" },
2325
{ label: trans("timeZone.UTC+06:00"), value: "Asia/Dhaka" },
26+
{ label: trans("timeZone.UTC+06:30"), value: "Asia/Rangoon" },
2427
{ label: trans("timeZone.UTC+07:00"), value: "Asia/Bangkok" },
2528
{ label: trans("timeZone.UTC+08:00"), value: "Asia/Shanghai" },
2629
{ label: trans("timeZone.UTC+09:00"), value: "Asia/Tokyo" },
30+
{ label: trans("timeZone.UTC+09:30"), value: "Australia/Darwin" },
2731
{ label: trans("timeZone.UTC+10:00"), value: "Australia/Sydney" },
28-
{ label: trans("timeZone.UserChoice"), value: "UserChoice" },
32+
{ label: trans("timeZone.UTC+11:00"), value: "Pacific/Guadalcanal" },
33+
{ label: trans("timeZone.UTC+12:00"), value: "Pacific/Auckland" },
34+
{ label: trans("timeZone.UTC+13:00"), value: "Pacific/Tongatapu" },
2935
];

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /