Search code examples
javascriptreactjstypescriptrecharts

How to convert Unix time format to hh:mm coming from an API


I'm quite new with React and using API's. I'm trying to make a graph with Recharts and I'm kinda stuck with something. The time data that I get from the API shows as Unix time format as shown here: https://i.sstatic.net/EZH3T.png This is how I fetch the API data:

 const [devices, setDevices] = useState([] as IDeviceData[]);

 useEffect(() => {
        fetch("http://api...")
            .then(response => {
                if (response.ok) {
                    return response.json()
                } else if (response.status === 404) {
                    return Promise.reject('Error 404')
                } else {
                    return Promise.reject('There was an error: ' + response.status)
                }
            })
            .then(data => setDevices(data))
            .catch(error => navigate(
                `/sensors/${imei}/404-not-found/`,
                {
                    state: {
                        description: `No sensor found with: "${imei}"`
                    }
                },
            ));
    }, [imei, navigate, category]);

And this is how I show it in my graph:

                <ResponsiveContainer width="100%" height="100%">
                    <LineChart data={devices} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>
                        <Line type="monotone" dataKey={category} dot={{strokeWidth: '4'}} stroke="#0EA5E9" />
                        <CartesianGrid stroke="#ccc" strokeDasharray="5 5" />
                        <XAxis dataKey={"timestamp"}/>
                        <YAxis />
                        <Tooltip />
                    </LineChart>
                </ResponsiveContainer>

I have tried to make a timestamp converter function like this:

export function convertTimestampToDate(timestamp: string): string {
  return new Intl.DateTimeFormat('nl', {
    year: 'numeric',
    day: '2-digit',
    month: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  }).format(parseInt(timestamp));
}

I don't quite know how to use the API data that I've put inside devices within the XAxis component.


Solution

  • It's possible to do that, here is how:

    • in XAxis there is a prop tickFormatter which can help you format the XAxis label

    • you should format the timestamp in the Tooltip too using labelFormatter

    then you have to pass convertTimestampToDate to those props

    note that in convertTimestampToDate you have to convert the timestamp to a date using new Date() because Intl.DateTimeFormat().format() accepts a date as a parameter

    export function convertTimestampToDate(timestamp: string): string {
      return new Intl.DateTimeFormat('nl', {
        year: 'numeric',
        day: '2-digit',
        month: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
      }).format(new Date(timestamp));
    }
    
    <ResponsiveContainer width='100%' height='100%'>
        <LineChart data={devices} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>
            <Line
                type='monotone'
                dataKey={category}
                dot={{ strokeWidth: '4' }}
                stroke='#0EA5E9'
            />
            <CartesianGrid stroke='#ccc' strokeDasharray='5 5' />
            <XAxis dataKey='timestamp' tickFormatter={convertTimestampToDate} />
            <YAxis />
            <Tooltip labelFormatter={convertTimestampToDate} />
        </LineChart>
    </ResponsiveContainer>
    

    check the codesandbox example

    Edit simple-line-chart (forked)