time-convertor

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

commit e6fddb2a19d256be736af318a7afd5d629bf04e6
parent 6a40ea0bb4e507715a08fe8a1238866852b9f472
Author: Agastya Chandrakant <me@hanabi.in>
Date:   Mon, 18 May 2020 18:29:56 +0530

implement future + footer

Diffstat:
Msrc/comp/currentTime.js | 2+-
Msrc/comp/footer.js | 7+++++--
Msrc/comp/fromToTime.js | 2+-
Msrc/comp/future.js | 192++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/comp/help.js | 98++++++++++++++++++++++++++++++++++++++++---------------------------------------
5 files changed, 248 insertions(+), 53 deletions(-)

diff --git a/src/comp/currentTime.js b/src/comp/currentTime.js @@ -11,7 +11,7 @@ function CurrentTime() { TZ2 ); return ( - <div className="time-conversion"> + <div className="time-conversion container" style={{ minHeight: '75vh' }}> <div className="row mb-3" id="fromto"> <div className="col text-right" id="labels-from"> <h1>From</h1> diff --git a/src/comp/footer.js b/src/comp/footer.js @@ -3,9 +3,12 @@ import React from 'react'; function Footer() { const year = new Date().getFullYear(); return ( - <footer className="w-100" style={{ bottom: 0, left: 0, position: 'fixed' }}> + <footer className="w-100 mt-5" style={{ bottom: 0 }}> <hr style={{ marginTop: 0 }} /> - <div className="page-footer text-center" style={{ paddingBottom: '5px' }}> + <div + className="page-footer text-center ml-1 mr-1" + style={{ paddingBottom: '5px' }} + > Copyright &copy; {year}{' '} <a href="https://en.wikinews.org/wiki/User:Acagastya" diff --git a/src/comp/fromToTime.js b/src/comp/fromToTime.js @@ -15,7 +15,7 @@ function FromToTime() { TZ1 ); return ( - <div className="time-conversion"> + <div className="time-conversion container" style={{ minHeight: '75vh' }}> <div className="row mb-3" id="fromto"> <div className="col text-right" id="labels-from"> <h1>From</h1> diff --git a/src/comp/future.js b/src/comp/future.js @@ -1,7 +1,197 @@ import React from 'react'; +import moment from 'moment-timezone'; + +import AutoCompleteText from '../comp/autoCompleteText'; function Future() { - return 'Future'; + const now = moment(new Date()); + const today = now.format('YYYY-MM-DD'); + const guess = moment.tz.guess(); + const timeRightNow = now.format('HH:mm'); + const [date, setDate] = React.useState(today); + const [time, setTime] = React.useState(timeRightNow); + const [TZ1, setTZ1] = React.useState(guess); + const [TZ2, setTZ2] = React.useState('UTC'); + const [err, setErr] = React.useState(''); + const [convertedTime, setConvertedTime] = React.useState(undefined); + const [chosenTime, setChosenTime] = React.useState(undefined); + function handleDateChange(e) { + setDate(e.target.value); + setConvertedTime(undefined); + } + + function handleTimeChange(e) { + setTime(e.target.value); + setConvertedTime(undefined); + } + + function handleSubmit(e) { + e.preventDefault(); + // 0. Reset error + setErr(''); + setConvertedTime(undefined); + setChosenTime(undefined); + // 1. validate chosen date + const chosenDate = moment(date); + if (!chosenDate.isValid()) { + setErr('Chosen date is not valid.'); + console.warn(err); + return; + } + // 1.1 chosenDate is in the range + const epoch = moment('01-18-2038', 'MM-DD-YYYY'); + if (epoch.unix() - chosenDate.unix() < 0) { + setErr('Chosen date is outside the maximum permissible limit.'); + console.warn(err); + return; + } + // if (chosenDate.unix() - now.unix() < 0) { + // setErr('Chosen date is in the past.'); + // console.log(err); + // return; + // } + + // 2. validate chosen time + const dateStr = chosenDate.format('YYYY-MM-DD'); + const timeStr = time; + const completeTimeStr = `${dateStr} ${timeStr}`; + const completeTime = moment.tz(completeTimeStr, TZ1); + if (!completeTime.isValid) { + setErr('Error occurred while parsing time.'); + console.warn(err); + return; + } + // 3. validate chosen timezone + if (moment.tz.names().indexOf(TZ1) < 0) { + setErr('Selected timezone does not exist.'); + return; + } + // 4. validate set timezone + if (moment.tz.names().indexOf(TZ2) < 0) { + setErr('Destination timezone does not exist.'); + return; + } + // 5. convert time + setChosenTime(completeTime.tz(TZ1).format('HH:mm:ss MMM DD, YYYY')); + const convTime = completeTime.tz(TZ2).format('HH:mm:ss MMM DD, YYYY'); + setConvertedTime(convTime); + } + + return ( + <div className="container" style={{ minHeight: '75vh' }}> + <form onSubmit={handleSubmit}> + <div className="form-group"> + <label htmlFor="choose-date">Choose date</label> + <input + aria-describedby="choose-date" + className="form-control" + id="choose-date" + max={'2038-01-18'} + min={now} + name="choose-date" + onChange={handleDateChange} + placeholder="Enter date" + type="date" + value={date} + /> + </div> + <div className="form-group"> + <label htmlFor="choose-time">Choose time</label> + <input + aria-describedby="choose-time" + className="form-control" + id="choose-time" + name="choose-time" + onChange={handleTimeChange} + placeholder="Enter time" + type="time" + value={time} + /> + </div> + <div className="form-group"> + <label htmlFor="choose-from-timezone">Set timezone</label> + <AutoCompleteText + autofocus={false} + changeValue={setTZ1} + clearInput={setConvertedTime} + defaultValue={TZ1} + id="choose-from-timezone" + placeholder="Set timezone" + /> + </div> + <div className="form-group"> + <label htmlFor="convert-to-timezone">Convert to timezone</label> + <AutoCompleteText + autofocus={false} + changeValue={setTZ2} + clearInput={setConvertedTime} + defaultValue={TZ2} + id="convert-to-timezone" + placeholder="Convert to timezone" + /> + </div> + <button type="submit" className="btn btn-success"> + Convert + </button> + </form> + {!!err === true ? ( + <ErrorAlert msg={err} /> + ) : !!convertedTime === true ? ( + <FutureConversion + chosenTime={chosenTime} + convertedTime={convertedTime} + TZ1={TZ1} + TZ2={TZ2} + /> + ) : null} + </div> + ); +} + +function FutureConversion({ chosenTime, convertedTime, TZ1, TZ2 }) { + const mmChosenTime = moment(chosenTime, 'HH:mm:ss DD MMM, YYYY'); + const mmConvTime = moment(convertedTime, 'HH:mm:ss MMM DD, YYYY'); + const fromLbl = moment.tz.zone(TZ1).abbr(mmChosenTime); + const toLbl = moment.tz.zone(TZ2).abbr(mmConvTime); + return ( + <div className="mt-5"> + <div className="row"> + <div className="col"> + <h1>{TZ1.replace(/_/g, ' ')}</h1> + </div> + <div className="col"> + <h1>{TZ2.replace(/_/g, ' ')}</h1> + </div> + </div> + <div className="row"> + <div className="col"> + {chosenTime} ({fromLbl}) + </div> + <div className="col"> + {convertedTime} ({toLbl}) + </div> + </div> + </div> + ); +} + +function ErrorAlert({ msg }) { + return ( + <div + className="alert alert-warning alert-dismissible fade show" + role="alert" + > + {msg} + <button + type="button" + className="close" + data-dismiss="alert" + aria-label="Close" + > + <span aria-hidden="true">&times;</span> + </button> + </div> + ); } export default Future; diff --git a/src/comp/help.js b/src/comp/help.js @@ -6,54 +6,56 @@ function Help() { const tz = moment.tz.guess(); const tzAbbr = moment.tz.zone(tz).abbr(moment()); return ( - <ol> - <li> - Use the{' '} - <Link - to="/" - style={{ - background: 'lavender', - borderRadius: '5px', - padding: '2px 5px', - }} - > - homepage - </Link>{' '} - to convert your <span className="font-weight-bold">current time</span> ( - {tzAbbr}) to other timezone. - </li> - <li> - Use the{' '} - <Link - to="/future" - style={{ - background: 'lavender', - borderRadius: '5px', - padding: '2px 5px', - }} - > - /future - </Link>{' '} - to convert a <span className="font-weight-bold">future date</span>{' '} - between different timezones. - </li> - <li> - Use the{' '} - <Link - to="/from-to" - style={{ - background: 'lavender', - borderRadius: '5px', - padding: '2px 5px', - }} - > - /from-to - </Link>{' '} - to convert - <span className="font-weight-bold"> current time</span> between - different timezones. - </li> - </ol> + <div className="container" style={{ minHeight: '75vh' }}> + <ol> + <li> + Use the{' '} + <Link + to="/" + style={{ + background: 'lavender', + borderRadius: '5px', + padding: '2px 5px', + }} + > + homepage + </Link>{' '} + to convert your <span className="font-weight-bold">current time</span>{' '} + ({tzAbbr}) to other timezone. + </li> + <li> + Use the{' '} + <Link + to="/future" + style={{ + background: 'lavender', + borderRadius: '5px', + padding: '2px 5px', + }} + > + /future + </Link>{' '} + to convert a <span className="font-weight-bold">future date</span>{' '} + between different timezones. + </li> + <li> + Use the{' '} + <Link + to="/from-to" + style={{ + background: 'lavender', + borderRadius: '5px', + padding: '2px 5px', + }} + > + /from-to + </Link>{' '} + to convert + <span className="font-weight-bold"> current time</span> between + different timezones. + </li> + </ol> + </div> ); }