future.js (5805B)
1 import React from 'react'; 2 import moment from 'moment-timezone'; 3 4 import AutoCompleteText from '../comp/autoCompleteText'; 5 6 function Future() { 7 const now = moment(new Date()); 8 const today = now.format('YYYY-MM-DD'); 9 const guess = moment.tz.guess(); 10 const timeRightNow = now.format('HH:mm'); 11 const [date, setDate] = React.useState(today); 12 const [time, setTime] = React.useState(timeRightNow); 13 const [TZ1, setTZ1] = React.useState(guess); 14 const [TZ2, setTZ2] = React.useState('UTC'); 15 const [err, setErr] = React.useState(''); 16 const [convertedTime, setConvertedTime] = React.useState(undefined); 17 const [chosenTime, setChosenTime] = React.useState(undefined); 18 function handleDateChange(e) { 19 setDate(e.target.value); 20 setConvertedTime(undefined); 21 } 22 23 function handleTimeChange(e) { 24 setTime(e.target.value); 25 setConvertedTime(undefined); 26 } 27 28 function handleSubmit(e) { 29 e.preventDefault(); 30 // 0. Reset error 31 setErr(''); 32 setConvertedTime(undefined); 33 setChosenTime(undefined); 34 // 1. validate chosen date 35 const chosenDate = moment(date); 36 if (!chosenDate.isValid()) { 37 setErr('Chosen date is not valid.'); 38 console.warn(err); 39 return; 40 } 41 // 1.1 chosenDate is in the range 42 const epoch = moment('01-18-2038', 'MM-DD-YYYY'); 43 if (epoch.unix() - chosenDate.unix() < 0) { 44 setErr('Chosen date is outside the maximum permissible limit.'); 45 console.warn(err); 46 return; 47 } 48 // if (chosenDate.unix() - now.unix() < 0) { 49 // setErr('Chosen date is in the past.'); 50 // console.log(err); 51 // return; 52 // } 53 54 // 2. validate chosen time 55 const dateStr = chosenDate.format('YYYY-MM-DD'); 56 const timeStr = time; 57 const completeTimeStr = `${dateStr} ${timeStr}`; 58 const completeTime = moment.tz(completeTimeStr, TZ1); 59 if (!completeTime.isValid) { 60 setErr('Error occurred while parsing time.'); 61 console.warn(err); 62 return; 63 } 64 // 3. validate chosen timezone 65 if (moment.tz.names().indexOf(TZ1) < 0) { 66 setErr('Selected timezone does not exist.'); 67 return; 68 } 69 // 4. validate set timezone 70 if (moment.tz.names().indexOf(TZ2) < 0) { 71 setErr('Destination timezone does not exist.'); 72 return; 73 } 74 // 5. convert time 75 setChosenTime(completeTime.tz(TZ1).format('HH:mm:ss MMM DD, YYYY')); 76 const convTime = completeTime.tz(TZ2).format('HH:mm:ss MMM DD, YYYY'); 77 setConvertedTime(convTime); 78 } 79 80 return ( 81 <div className="container" style={{ minHeight: '75vh' }}> 82 <form onSubmit={handleSubmit}> 83 <div className="form-group"> 84 <label htmlFor="choose-date">Choose date</label> 85 <input 86 aria-describedby="choose-date" 87 className="form-control" 88 id="choose-date" 89 max={'2038-01-18'} 90 min={now} 91 name="choose-date" 92 onChange={handleDateChange} 93 placeholder="Enter date" 94 type="date" 95 value={date} 96 /> 97 </div> 98 <div className="form-group"> 99 <label htmlFor="choose-time">Choose time</label> 100 <input 101 aria-describedby="choose-time" 102 className="form-control" 103 id="choose-time" 104 name="choose-time" 105 onChange={handleTimeChange} 106 placeholder="Enter time" 107 type="time" 108 value={time} 109 /> 110 </div> 111 <div className="form-group"> 112 <label htmlFor="choose-from-timezone">Set timezone</label> 113 <AutoCompleteText 114 autofocus={false} 115 changeValue={setTZ1} 116 clearInput={setConvertedTime} 117 defaultValue={TZ1} 118 id="choose-from-timezone" 119 placeholder="Set timezone" 120 /> 121 </div> 122 <div className="form-group"> 123 <label htmlFor="convert-to-timezone">Convert to timezone</label> 124 <AutoCompleteText 125 autofocus={false} 126 changeValue={setTZ2} 127 clearInput={setConvertedTime} 128 defaultValue={TZ2} 129 id="convert-to-timezone" 130 placeholder="Convert to timezone" 131 /> 132 </div> 133 <button type="submit" className="btn btn-success"> 134 Convert 135 </button> 136 </form> 137 {!!err === true ? ( 138 <ErrorAlert msg={err} /> 139 ) : !!convertedTime === true ? ( 140 <FutureConversion 141 chosenTime={chosenTime} 142 convertedTime={convertedTime} 143 TZ1={TZ1} 144 TZ2={TZ2} 145 /> 146 ) : null} 147 </div> 148 ); 149 } 150 151 function FutureConversion({ chosenTime, convertedTime, TZ1, TZ2 }) { 152 const mmChosenTime = moment(chosenTime, 'HH:mm:ss DD MMM, YYYY'); 153 const mmConvTime = moment(convertedTime, 'HH:mm:ss MMM DD, YYYY'); 154 const fromLbl = moment.tz.zone(TZ1).abbr(mmChosenTime); 155 const toLbl = moment.tz.zone(TZ2).abbr(mmConvTime); 156 return ( 157 <div className="mt-5"> 158 <div className="row"> 159 <div className="col"> 160 <h1>{TZ1.replace(/_/g, ' ')}</h1> 161 </div> 162 <div className="col"> 163 <h1>{TZ2.replace(/_/g, ' ')}</h1> 164 </div> 165 </div> 166 <div className="row"> 167 <div className="col"> 168 {chosenTime} ({fromLbl}) 169 </div> 170 <div className="col"> 171 {convertedTime} ({toLbl}) 172 </div> 173 </div> 174 </div> 175 ); 176 } 177 178 function ErrorAlert({ msg }) { 179 return ( 180 <div 181 className="alert alert-warning alert-dismissible fade show" 182 role="alert" 183 > 184 {msg} 185 <button 186 type="button" 187 className="close" 188 data-dismiss="alert" 189 aria-label="Close" 190 > 191 <span aria-hidden="true">×</span> 192 </button> 193 </div> 194 ); 195 } 196 197 export default Future;