Time difference between an ISO 8601 date and now

I have a comment section on my website and each message have its created_at date time. After fetching it from the MariaDB database, I get a string like "2021-06-15T12:45:28.000Z" (ISO 8601). Then, I convert it to a "x minutes ago" text instead of the full date.

But then, I'm having some trouble when the date is parsed.

const epochs = [
    ["année", 31536000],
    ["mois", 2592000],
    ["jour", 86400],
    ["heure", 3600],
    ["minute", 60],
    ["seconde", 1]
];

function getInterval(timeAgo) {
    for (let [ name, seconds ] of epochs) {
        const interval = Math.floor(timeAgo / seconds);

        if (interval >= 1) {
            return { interval: interval, epoch: name };
        }
    }
}

function dateToString(d) {
    const date = new Date(d);

    console.log("Created at:", date);
    console.log("Now:", new Date());

    const timeAgo = Math.floor((new Date() - date) / 1000);
    console.log("Time ago:", timeAgo);
    const { interval, epoch } = getInterval(timeAgo);
    const plural = (interval === 1 || epoch.slice(-1) === "s") ? "" : "s";

    console.log("----------------------------");
    return `Il y a ${interval} ${epoch}${plural}`;
}

dateToString("2021-06-15 12:45:28"); // Works fine
dateToString("2021-06-15T12:45:28.000Z"); // The "timeAgo" is negative

Subtracting the ISO date gives a negative number. I'm pretty sure this is a timezone problem because the minimal value of the substraction is almost -7200 which is two hour and I'm in a UTC+2 timezone.

Have you any idea how can I fix this?

Thanks

Upvotes: 2

Views: 280

Answers (1)

mplungjan
mplungjan

Reputation: 177786

Try adding or subtracting the timezoneOffset of the local computer from the UTC you get when you pass Z

I fixed your plural too

const epochs = {
  "années": 31536000,
  "mois": 2592000,
  "jours": 86400,
  "heures": 3600,
  "minutes": 60,
  "secondes": 1
};

const singular = {
  "années": "ans",
  "mois": "mois",
  "jours": "jour",
  "heures": "heure",
  "minutes": "minute",
  "secondes": "seconde"
};

const getInterval = timeAgo => {
  const epoch = Object.entries(epochs).filter(([key, val]) => timeAgo >= val).shift();
  const obj = {
    epoch: epoch[0],
    interval: parseInt(timeAgo / epoch[1])
  }
  if (obj.interval === 1) obj.epoch = singular[obj.epoch]
  return obj
};

const aMinute = 60 * 1000

function dateToString(d) {
  const date = new Date(d);
  if (d.includes("Z")) {
    let tzo = date.getTimezoneOffset();
    tzo = (tzo > 0 ? tzo * -1 : tzo);
    tzo *= aMinute
    date.setTime(date.getTime() + tzo)
  }
  console.log("Created at:", date.toLocaleString());
  console.log("Now:", new Date());

  const timeAgo = Math.floor((new Date() - date) / 1000);
  console.log("Time ago:", timeAgo);
  console.log(getInterval(timeAgo))

  const { epoch, interval } = getInterval(timeAgo);
  console.log(epoch)


  console.log("----------------------------");
  return `Il y a ${interval} ${epoch}`;
}
console.log(
  dateToString("2021-06-15 12:45:28"), "\n",
  dateToString("2021-06-15T12:45:28.000Z"), "\n",
  dateToString("2019-06-15T12:45:28.000Z"), "\n"
)

Upvotes: 1

Related Questions