abhijith
abhijith

Reputation: 127

show difference in 2 times

enter image description here 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

Answers (3)

RobG
RobG

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.

Edit

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

cнŝdk
cнŝdk

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

Vikasdeep Singh
Vikasdeep Singh

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

Related Questions