0

I am completely new to programming/web development.

What I am trying to do: I am trying to write JavaScript that will take the date from a webpage or an online spreadsheet and change the color of the text or cell background. The color change will be based on if the date taken from the HTML element or online spreadsheet is within 14 or 30 days from today's date.

Here is a sample of html elements I would like to work on. I put the dates in various formats to try and work with them.

The Javascript I have written so far I am posting here because I can get the elements to change color but I don't think the change is actually based on the number of days and I am not able to compare a the number of days I want.

const now = new Date().toDateString();
const date1 = document.getElementById('test1').innerText;

for (let i = 0; i <= test.length; i++) {

  i += test[i];

  if (date1 <= now)
    console.log('safe');
  if (date1 >= now)
    document.getElementsByClassName('test')[0].style.color = 'purple';
};
<div class='test'>
  <p id="test1">February 22 2022</p>
  <br>
  <p id="test">17/2/2022</p>
  <br>
  <p id="test">17 3 2022</p>
  <br>
  <p id="test">17 4 2022</p>
  <br>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Satopu
  • 3
  • 3
  • 1
    Please [have a look at how to use markdown](https://stackoverflow.com/editing-help#comment-formatting) - Indent 4 spaces OR use the `[<>]` snippet editor I used to make a [mcve] – mplungjan Jan 22 '22 at 07:53
  • You can't have multiple elements with the same ID. An ID must be unique in the DOM (it's a unique IDentifier). Use a class instead – Jeremy Thille Jan 22 '22 at 07:56
  • First of all: Please remember that ID's should always be unique. You can't have more than 1 `id="test"` in a single document. Secondly, you're using different date / time zone formats. This will most likely cause issues. You'll probably have to [format the Javascript date](https://stackoverflow.com/questions/3552461/how-to-format-a-javascript-date) for every format you want to use. – icecub Jan 22 '22 at 07:59

3 Answers3

1
  1. IDs need to be unique. Use a class or in my case a selector from the container
  2. Your test is not an array, it is a string
  3. Which of the dates you have shown are valid? I assume in my code that any of dd/mm/yyyy, dd mm yyyy, Mmm(...) dd yyyy

const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
const now = new Date();
document.querySelectorAll('.test p').forEach(p => {
  const dString = p.textContent;
  let [date, month, year] = dString.split(/[ \/]/)

  const textMonth = months.indexOf(date.slice(0, 3))
  if (textMonth != -1) { // we found a month name
    date = month
    month = textMonth
  } else month -= 1;
  const d = new Date(year, month, date)
  console.log(d, d <= now)
  p.classList.toggle("safe", !isNaN(d) && d <= now)
  p.classList.toggle("unknown", isNaN(d))
  p.classList.toggle("unsafe", !isNaN(d) && d > now)
})
.safe {
  color: green;
}

.unsafe {
  color: purple;
}

.unknown {
  color: red;
}
<div class='test'>
  <p>February 22 2022</p>
  <br>
  <p>17/1/2022</p>
  <br>
  <p>17/2/2022</p>
  <br>
  <p>17 3 2022</p>
  <br>
  <p>17 4 2022</p>
  <br>
  <p>17 4 2025</p>
  <br>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 1
    Thank you for this, it showed me that what I was trying to do it much more complex than I thought and way beyond my skills right now. I will try to learn from the code you wrote. – Satopu Jan 22 '22 at 10:09
  • Consider `dString.split(/\D/)` instead of `dString.split(/[ \/]/)` to allow for any non–digit separator (space, dash, dot, slash, etc.). Also a link to [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) to explain the manual parse. :-) – RobG Jan 23 '22 at 01:07
0

Rather than converting them to strings to can use the date objects directly for comparison and the Date constructor can take a string as an input and make an object out of it.

Try something like this:

const now = new Date();
const dates = document.getElementsByTagName('p');

for (d of dates) {
  let dateString = d.innerText;
  let dateObj = new Date(dateString);

  if (dateObj < now)
    console.log(`${dateObj} is older`);
  else
    console.log(`${dateObj} is today or newer`);
};
<div class="test">
  <p>February 22 2022</p>
  <br>
  <p>2/22/2022</p>
  <br>
  <p>2021 2 17</p>
  <br>
</div>

Edit: Thanks for the idea abt snippets! Did not know much abt that feature. Also found out JS does not understand DD/MM/YYYY, where MM is 2 or 02 :(

Also updated the code a bit with other suggestions here and a hopefully more understandable example.

  • 1
    It would be really nice if you made a snippet so we can see your code in action. I predict it will crash immediately because `test` is not an array – Jeremy Thille Jan 22 '22 at 07:57
  • JS does not like dd/mm/yyyy at all. – mplungjan Jan 22 '22 at 10:39
  • Re `new Date(dateString)`, see [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) – RobG Jan 23 '22 at 01:09
-1

If you are using any single-page application then please install the moment.js library (npm I moment) or if you are using HTML javascript then please add moment.js CDN

The below code is just a sample of your logic problem only

<!DOCTYPE html>
<html>

<head>
    <title>Page Title</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>

<body>
    <div id="Reset">
        <button>Check date is under 30 days</button>
    </div>

    <script>
        $(document).ready(function () {
            $("#Reset").click(function () {
                /* $.get("https://jsonplaceholder.typicode.com/todos", function (data) {
                    console.log(data);
                    alert("Load was performed.");
                }) */
                let curretDate = new Date();
                let dateToCheck = new Date("01/12/2022");
                let date_of_30_subtract = moment(curretDate).subtract(30, 'days');
                
                console.log(moment(dateToCheck).isBetween(date_of_30_subtract,curretDate ))
            });
        });
    </script>
</body>

</html>

You can set before which date you have to check 14 or 30 days. Thant will subtract those days and get the date after subtraction.

ram verma
  • 26
  • 5
  • Thank you for this, it showed me that what I was trying to do it much more complex than I thought and way beyond my skills right now. I will absolutely work hard to understand everything in here. Thank you again. – Satopu Jan 22 '22 at 10:09
  • It's considered bad form to post an answer that depends on a library that isn't mentioned or tagged in the OP. Also, if using a date library, it should be used for parsing, which includes passing the format of the string to parse. – RobG Jan 23 '22 at 01:14