In my database I have a data set with date (startdatetime) and zone (timezone). Zone is posted into the DB from a different application that uses C# DateObject.
Ex. (UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague OR another example (UTC-10:00) Hawaii
I need to create a component that can convert date (startdatetime) and zone (timezone) to the users choosing, so I created a dropdown that uses time zones from moment-timezone library. UNFORTUNATELY it doesn't convert (or accurately if it does) the C# DateObject format since it's not in the same format as moment-timezone.
So I either have to create a dictionary where for example it converts '(UTC-08:00) Pacific Time (US & Canada)' to 'America/Los_Angeles|PST PDT|80 70|0101|1Lzm0 1zb0 Op0' or create my own custom dynamic timezone converter. Which I have tried but I keep getting incorrect time.
I could be missing something in moment-timezone docs (since I am new to the library) but as of now this is my existing code (before I was informed that the timezone will be on C# Date Object format and not on moment-timezone format).
import React, {useState, useEffect} from 'react';
import CloseIcon from '@material-ui/icons/Close';
import { makeStyles } from '@material-ui/core/styles';
import { useSelector, useDispatch } from "react-redux";
import {setRunListData, getRunDataAllGroupedAsync, setIsAllRunListDataShown, setTimeZone} from "../actions/index";
import * as Utils from '../../utils/utils';
import { Select, MenuItem, FormControl } from '@mui/material';
import moment from 'moment-timezone';
import {
Typography,
IconButton,
Button,
Dialog,
DialogTitle,
DialogActions
} from '@material-ui/core';
const TimeZone = (props) => {
const { handleClose, isOpen } = props;
const runlist = useSelector(state => state.runlist);
const jwt = useSelector(state => state.jwt);
const is_all_run_list_data_shown = useSelector(state => state.is_all_run_list_data_shown);
const dispatch = useDispatch();
const [selectedTimeZone, setSelectedTimeZone] = React.useState(localStorage.getItem('time_zone') || 'PST8PDT');
const [originalRunlist, setOriginalRunlist] = useState(runlist);
const zones = Utils.zones;
useEffect(() => {
setOriginalRunlist(is_all_run_list_data_shown);
}, [is_all_run_list_data_shown])
const useStyles = makeStyles((theme) => ({
dialogWrapper: {
padding: theme.spacing(2),
position: 'absolute',
top: theme.spacing(2),
},
dialogTitle: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
},
closeIcon: {
marginLeft: 'auto',
},
storagesContainer: {
display: 'flex',
justifyContent: 'space-evenly',
gap: 5,
margin: '20px 0px',
},
alertContainer: {
display: 'flex',
alignItems: 'center',
marginLeft: '20px 0px',
overflow: 'hidden',
},
inputContainer: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-evenly',
margin: '15px 0px',
//overflow: 'hidden',
},
outlineInput: {
height: 20,
width: 50,
marginLeft: 10,
marginRight: 10,
},
buttonContainer: {
display: 'flex',
justifyContent: 'space-evenly',
overflow: 'hidden',
},
defaultButton: {
margin: theme.spacing(1),
background: 'linear-gradient(113.96deg, #E9F5F5 100%, #D9E7F4 100%)',
border: '0.5px solid #CCCCCC',
boxSizing: 'border-box',
borderRadius: '4px',
color: '#189AB4',
width: 150,
'&:disabled': {
background: '#f0f0f0', // Change this to the desired disabled background color
color: '#666666', // Change this to the desired disabled text color
},
},
button: {
margin: theme.spacing(1),
background: '-webkit-gradient(linear, left top, right bottom, from(#0075a9), to(#003049))',
border: '0.5px solid #CCCCCC',
boxSizing: 'border-box',
borderRadius: '4px',
color: 'white',
width: 150,
'&:disabled': {
background: '#f0f0f0', // Change this to the desired disabled background color
color: '#666666', // Change this to the desired disabled text color
},
},
formControl: {
"& .MuiInputBase-root": {
borderWidth: "1px",
borderStyle: "solid",
minWidth: "120px",
width: "280px",
justifyContent: "center",
cursor: "pointer" // Set cursor to pointer
},
"& .MuiSelect-select.MuiSelect-select": {
paddingRight: "15px"
},
marginLeft: "auto" // Move the FormControl to the right
},
}));
const classes = useStyles();
const handleChange = (event) => {
setSelectedTimeZone(event.target.value);
};
const handleDefaultRunlistDate = () => {
setSelectedTimeZone('PST8PDT');
dispatch(setTimeZone('PST8PDT'));
originalRunlist ? dispatch(getRunDataAllGroupedAsync(undefined, jwt)) : dispatch(getRunDataAllGroupedAsync(100, jwt));
}
function toTimeZone(time, zone) {
try {
var format = 'MM/DD/YYYY HH:mm:ss';
return moment(time, format).tz(zone).format(format);
} catch (error) {
console.log(error)
}
}
const handleUpdateRunlistDate = () => {
let copyRunList = structuredClone(runlist);
const updatedRunlist = copyRunList.map(entry => {
if(entry.timezone){
const startDatetime = toTimeZone(entry.startdatetime, selectedTimeZone);
entry.startdatetime = startDatetime;
entry.timezone = selectedTimeZone;
}
return entry;
});
dispatch(setTimeZone(selectedTimeZone));
dispatch(setRunListData(updatedRunlist));
}
return (
<>
<Dialog disableEnforceFocus onClose={handleClose} aria-labelledby="customized-dialog-title" open={isOpen} fullWidth maxWidth={'sm'} classes={{paper: classes.dialogWrapper}}>
<DialogTitle>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Typography variant="h6">Time Zone Settings</Typography>
<IconButton onClick={handleClose}>
<CloseIcon />
</IconButton>
</div>
</DialogTitle>
<div className={classes.inputContainer}>
<Typography>Time Zone Name:</Typography>
<FormControl className={classes.formControl}>
<Select
labelId="zone-label"
id="zone-select"
value={selectedTimeZone}
onChange={handleChange}
>
{zones.map((zone, index) => (
<MenuItem key={index} value={zone.split('|')[0]}>
{zone.split('|')[0]}
</MenuItem>
))}
</Select>
</FormControl>
</div>
<div className={classes.buttonContainer}>
<DialogActions>
<Button autoFocus color="primary" className={classes.defaultButton} onClick={handleDefaultRunlistDate}>
Default
</Button>
<Button autoFocus color="primary" className={classes.button} onClick={handleUpdateRunlistDate}>
Apply
</Button>
</DialogActions>
</div>
</Dialog>
</>
);
}
export default TimeZone;
Any tips?