time-convertor

Convert time across timezones
git clone http://git.hanabi.in/repos/time-convertor.git
Log | Files | Refs | README | LICENSE

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">&times;</span>
    192       </button>
    193     </div>
    194   );
    195 }
    196 
    197 export default Future;