Reputation: 10240
I have a live clock working pretty good except in the morning hours, it displays 1:2:3
when it should display 01:02:03
How can I modify this to work in a ReactJS component? I'm very new at React and the ways to implement a javascript function are not quite the same so I can't really use any of the regular JS answer I find. Here is the code in my class:
class SidebarContent extends React.Component {
constructor(props) {
super(props);
this.state = {
date: new Date()
};
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({date: new Date()});
}
getHours() {
return this.state.date.getHours();
}
getMinutes() {
return this.state.date.getMinutes();
}
getSeconds() {
return this.state.date.getSeconds();
}
componentDidMount() {
this.timerID = setInterval(() => this.tick(), 1000);
}
render() {
return (
<ul className="nav" ref={(c) => {this.nav = c; }}>
<li className="today">
<Row className="clock" center="xs">
<Row center="xs">
<span className="hours">{this.getHours()}</span>
<span>:</span>
<span className="min">{this.getMinutes()}</span>
<span className="sec">{this.getSeconds()}</span>
</Row>
</Row>
<Row className="date" center="xs">
<p className="today-is">{this.state.date.toDateString()}</p>
</Row>
</li>
</ul>
);
}
}
Thanks in advance
Upvotes: 1
Views: 10748
Reputation: 130102
Padding time is essentially this:
if (seconds < 10) {
return '0' + seconds;
} else {
return '' + seconds;
}
or
const pad = (seconds < 10) ? '0' : '';
return pad + seconds;
In total:
getFormattedTime() {
const {date} = this.state;
const timeComponents = [date.getHours(), date.getMinutes(), date.getSeconds()];
return timeComponents
.map(component => {
const pad = (component < 10) ? '0' : '';
return pad + component;
})
.join(':');
}
Upvotes: 3
Reputation: 21124
This is how I did it in my count down timer app some time back. Here given the time in seconds it returns you a JSON object which represents hours, minutes and seconds in two digit format.
secondsToTime(secs) {
let hours = `${constants.ZERO}${Math.floor(secs / (60 * 60))}`.slice(-2);
let divisorForMinutes = secs % (60 * 60);
let minutes = `${constants.ZERO}${Math.floor(divisorForMinutes / 60)}`.slice(-2);
let divisorForSeconds = divisorForMinutes % 60;
let seconds = `${constants.ZERO}${Math.ceil(divisorForSeconds)}`.slice(-2);
let obj = {
"h": hours,
"m": minutes,
"s": seconds
};
return obj;
}
You may access the values like this.
var remainingTime = this.secondsToTime(timeInSeconds);
remainingTime["h"] // gives you hours
remainingTime["m"] // gives you minutes
remainingTime["s"] // gives you seconds
This approach is far more better than calling 3 functions to get the hours, minutes and seconds separately which is a bit awkward for me. Hope this helps. Happy Coding !
Upvotes: -1
Reputation: 12746
If you wish you can you momentjs and forget about formatting stuff. momentjs will take care of that. You'll only need to specify the format. I believe It will look a lot cleaner than padding stuff.
class SidebarContent extends React.Component {
constructor(props) {
super(props);
this.state = {
date: moment()
};
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({date: moment()});
}
getTime() {
return this.state.date.format('HH:mm:ss')
}
componentDidMount() {
this.timerID = setInterval(() => this.tick(), 1000);
}
render() {
return (
<ul className="nav" ref={(c) => {this.nav = c; }}>
<li className="today">
<div className="clock" center="xs">
<div center="xs">
<span className="hours">{this.getTime()}</span>
</div>
</div>
<div className="date" center="xs">
<p className="today-is">
{this.state.date.format('ddd MMM DD YYYY')}</p>
</div>
</li>
</ul>
);
}
}
Here is the Fiddle for the same. JSFiddle
Upvotes: 2
Reputation: 2295
You can use the function padStart from lodash. You can install the entire lodash library or the standalone package lodash.padstart.
To display the leading 0
, you can do this:
// here you will import the function from the lodash package
// import padStart from 'lodash.padstart';
// OR
// import padStart from 'lodash/padstart';
const padStart = _.padStart;
class SidebarContent extends React.Component {
constructor(props) {
super(props);
this.state = {
date: new Date()
};
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
getHours() {
return padStart(this.state.date.getHours(), 2, '0');
}
getMinutes() {
return padStart(this.state.date.getMinutes(), 2, '0');
}
getSeconds() {
return padStart(this.state.date.getSeconds(), 2, '0');
}
componentDidMount() {
this.timerID = setInterval(() => this.tick(), 1000);
}
render() {
return ( <
ul className = "nav"
ref = {
(c) => {
this.nav = c;
}
} >
<
li className = "today" >
<
div className = "clock"
center = "xs" >
<
div center = "xs" >
<
span className = "hours" > {
this.getHours()
} < /span> <
span >: < /span> <
span className = "min" > {
this.getMinutes()
} < /span> <
span >: < /span> <
span className = "sec" > {
this.getSeconds()
} < /span> <
/div> <
/div> <
div className = "date"
center = "xs" >
<
p className = "today-is" > {
this.state.date.toDateString()
} < /p> <
/div> <
/li> <
/ul>
);
}
}
ReactDOM.render( < SidebarContent / > , document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
<div id="app" />
Upvotes: 1
Reputation: 594
React is plain javascript. You absolutely can use any plain javascript in there. Your issue has nothing to do with react and everything to do with javascript. Date()
's methods return a single digit. You're going to need to somehow pad the output. See How to output integers with leading zeros in JavaScript
Upvotes: -2