Reputation: 127
Its giving me like this instead of showing how many hours its showing "in hrs" but the real issue is even though the date is todays and time should show in minutes its giving me in hours..
I have to display time based on condition that if the order has been placed few minutes earlier it should show
"1 min"
, if few hours ago then "18 hr"
if it is not of the present date it should show date in the format "29/06/18"
. using moment.js
any help is appreciated.
This is my code:
export class Notifications extends PureComponent {
constructor(props) {
super(props);
this.state = {
notificationsData: null,
isLoading: true
};
}
componentDidMount() {
if (notifications) {
this.setState({
notificationsData: notifications.data,
isLoading: false
});
} else {
this.setState({ isLoading: false });
}
}
renderIconBadge(icon) {
return (
<View style={styles.iconBagdeContainer}>
<Icon name={icon} size={scale(16)} />
</View>
);
}
getDateFormatted(dateTime) {
var date = moment(dateTime, "DD/MM/YYYY HH:mm").isValid() ?
moment(dateTime, "DD/MM/YYYY HH:mm")
: moment(new Date(dateTime), "DD/MM/YYYY HH:mm");
var diff = date.fromNow();
if (diff.indexOf("minute") > -1) {
return diff.substring(0, 2).trim() + " mins";
} else if (diff.indexOf("hour") > -1) {
//If it's yesterday
if(date.day() != moment().day()){
return date.format("DD/MM/YYYY");
}
return diff.substring(0, 2).trim() + " hrs";
} else {
return date.format("DD/MM/YYYY");
}
}
renderNotificationCard = ({ item }) => {
return (
<Card style={styles.notificationCardContainer}>
<View
style={{
flexDirection: "row"
}}
>
{/* <View style={{ flexDirection: "row" }}> */}
{this.renderIconBadge(item.icon)}
<View
style={{
marginLeft: scale(12)
}}
>
<Text
style={styles.location}
numberOfLines={3}
ellipsizeMode="tail"
>
{item.location}
</Text>
<View style={{ flexDirection: "row" }}>
<ClickView onPress={() => {}}>
<Text style={styles.viewBooking}>
View Booking
</Text>
</ClickView>
<Text style={styles.dateFormat}>
{this.getDateFormatted(item.dateTime)}
</Text>
</View>
</View>
{/* </View> */}
</View>
</Card>
);
};
renderNotificationList() {
const { notificationsData } = this.state;
return (
<View style={{ marginTop: scale(10), marginBottom: scale(100) }}>
{notificationsData.notification.length !== 0 ? (
<FlatList
data={this.state.notificationsData.notification}
renderItem={this.renderNotificationCard}
/>
) : (
<View
style={{
marginTop: scale(100),
alignItems: "center"
}}
>
<Image source={Images.noTaskImg} />
<Text
style={{
marginTop: scale(20),
fontSize: scale(18),
fontWeight: "600",
color: Colors.body
}}
>
No Notifications found.
</Text>
</View>
)}
</View>
);
}
render() {
const { isLoading } = this.state;
return (
<ThemeView
theme="dark"
style={styles.mainContainer}
rightButton="close"
onRightButtonPress={() => {
this.props.navigation.goBack();
}}
>
{isLoading ? (
<ProgressBar />
) : (
<View>
<View
style={{ marginTop: scale(Metrics.headerHeight) }}
>
<Text style={styles.newTasks}>New Tasks</Text>
{this.renderNotificationList()}
</View>
</View>
)}
</ThemeView>
);
}
}
JSON data format is like this
{
id: "1",
icon: "water",
location:
"Your booking water",
dateTime: "2018-06-12T20:20:52.123Z"
}
Thanks in advance
Upvotes: 0
Views: 102
Reputation: 147453
You first need to test if the date is "today" and if not, return a date string in the required format. Otherwise, return the time ago in the required format.
Since you want something different to the default "from now" returned by moment.js and it's not difficult to write your own, you might as well do that. See below.
The above function expects to get a Date object, so if your source JSON is:
'{"id":"1","icon":"water","location":"Your booking water","dateTime":"2018-06-12T20:20:52.123Z"}'
then you need to get the dateTime property and turn it into a Date. Note that the supplied string will be parsed as UTC (given the Z timezone identifier) but the results of the function will be based on the host timezone offset.
function formatDate(date) {
var d = new Date();
var diff = d - date;
// If yesterday, return a formatted date
if (d.getDate() != date.getDate()) {
return moment(date).format('DD/MM/YYYY');
}
// If diff less than an hour ago, return minutes
if (diff < 3.6e6) {
return (diff/6e4 | 0) + ' min';
}
// Otherwise, return hours
return (diff/3.6e6 | 0) + ' hr';
}
// Some test dates
var a = new Date();
// 3 minutes ago
var b = new Date(a.setMinutes(a.getMinutes() - 3));
// 1 hour and 3 minutes ago
var c = new Date(a.setHours(a.getHours() - 1));
// 2 hour and 3 minutes ago
var d = new Date(a.setHours(a.getHours() - 1));
// 1 day, 2 hour and 3 minutes ago
a.setDate(a.getDate() - 1);
[b,c,d,a].forEach(function(d) {
console.log(`${moment(d).format('DD/MM/YY HH:mm')} => ${formatDate(d)}`);
});
// Using sample JSON:
var jsonTxt = '{"id":"1", "icon":"water", "location":"Your booking water", "dateTime":"2018-06-12T20:20:52.123Z"}';
var obj = JSON.parse(jsonTxt);
// Without moment.js
console.log(formatDate(new Date(obj.dateTime)));
// With moment.js
console.log(formatDate(moment(obj.dateTime).toDate()));
// Make dateTime 3 minutes ago
var s = b.toISOString(); // UTC 3 mins ago
obj.dateTime = s;
console.log(`${s} => ${formatDate(new Date(obj.dateTime))}`);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>
NB. The usual caveat applies to using the built-in parser: if you can guarantee that the string will strictly comply with the format in ECMA-262 with a timezone (e.g. "Z" or ±HH:mm) then it's fairly safe to use. Otherwise, use the moment parser.
Upvotes: 1
Reputation: 32145
Actually to check the difference you can use fromNow() and according to the result, you can return your custom string.
This is how should be your function:
var getDateFormatted = function(dateTime) {
var date = moment(dateTime, "DD/MM/YYYY HH:mm").isValid() ?
moment(dateTime, "DD/MM/YYYY HH:mm")
: moment(new Date(dateTime), "DD/MM/YYYY HH:mm");
var diff = date.fromNow();
if (diff.indexOf("minute") > -1) {
return diff.substring(0, 2).trim() + " mins";
} else if (diff.indexOf("hour") > -1) {
//If it's yesterday
if(date.day() != moment().day()){
return date.format("DD/MM/YYYY");
}
return diff.substring(0, 2).trim() + " hrs";
} else {
return date.format("DD/MM/YYYY");
}
}
var getDateFormatted = function(dateTime) {
var date = moment(dateTime, "DD/MM/YYYY HH:mm").isValid() ?
moment(dateTime, "DD/MM/YYYY HH:mm") :
moment(new Date(dateTime), "DD/MM/YYYY HH:mm");
var diff = date.fromNow();
if (diff.indexOf("minutes") > -1) {
return diff.substring(0, 2).trim() + " mins";
} else if (diff.indexOf("hour") > -1) {
if (date.day() != moment().day()) {
return date.format("DD/MM/YYYY");
}
return diff.substring(0, 2).trim() + " hrs";
} else {
return date.format("DD/MM/YYYY");
}
}
var data = {
id: "1",
icon: "water",
location: "Your booking water",
dateTime: "2018-06-12T20:20:52.123Z"
};
console.log(getDateFormatted("28/06/2018 23:00"));
console.log(getDateFormatted("29/06/2018 11:50"));
console.log(getDateFormatted("28/06/2018 01:00"));
console.log(getDateFormatted(data.dateTime));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>
Upvotes: 1
Reputation: 21766
Use fromNow() of momentjs. It will give you desired output.
var duration = moment("29/06/18", "DD/MM/YYYY").fromNow(); // in moment("pass your timestamp/valid date")
console.log(duration);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>
Upvotes: 0