0

How can i get 'day of year' and 'remaining days' according to chosen month and year? I've managed to get the days and check if it's leap or not but it's messy. How can this be improved and shortened? This is a table and has days 1-31 and month/year that can be changed. The for just increments the value.

var year = document.getElementById("Year").innerHTML;
var month = parseFloat(document.getElementById("Month").innerHTML);
var leap = (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0);
document.getElementById("leap").innerHTML = leap;


for (var i = 1; i <= $('#table thead th').length; ++i) {
  var day = parseFloat($('#table thead th:nth-child(' + i + ')').text());
  if (month == 1) {
    $('#table tbody tr:nth-child(1) td:nth-child(' + i + ')').text(i - 1);
  }
  if (month == 2) {
    $('#table tbody tr:nth-child(1) td:nth-child(' + i + ')').text(i + 30);
  }
  if (month == 3 && leap == true) {
    $('#table tbody tr:nth-child(1) td:nth-child(' + i + ')').text(i + 59);
  }
  if (month == 3 && leap == false) {
    $('#table tbody tr:nth-child(1) td:nth-child(' + i + ')').text(i + 58);
  }
  if (month == 4 && leap == true) {
    $('#table tbody tr:nth-child(1) td:nth-child(' + i + ')').text(i + 90);
  }
  if (month == 4 && leap == false) {
    $('#table tbody tr:nth-child(1) td:nth-child(' + i + ')').text(i + 89);
  }
  if (month == 5 && leap == true) {
    $('#table tbody tr:nth-child(1) td:nth-child(' + i + ')').text(i + 120);
  }
  if (month == 5 && leap == false) {
    $('#table tbody tr:nth-child(1) td:nth-child(' + i + ')').text(i + 119);
  }
}
$('.hide').text('');
table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
  border-bottom: 1px solid #ccc;
}

td,
th {
  border-bottom: 1px solid #ccc;
  text-align: center;
  padding: 8px;
}

thead {
  background-color: #dddddd;
}
<!DOCTYPE html>
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
</head>

<body>
  <span id="Month">5</span>
  <span id="Year">2020</span>
  <span id=leap></span>
  <table id="table">
    <thead>
      <tr>
        <th id="MonthName">Days</th>
        <th>1</th>
        <th>2</th>
        <th>3</th>
        <th>4</th>
        <th>5</th>
        <th>6</th>
        <th>7</th>
        <th>8</th>
        <th>9</th>
        <th>10</th>
        <th>11</th>
        <th>12</th>
        <th>13</th>
        <th>14</th>
        <th>15</th>
        <th>16</th>
        <th>17</th>
        <th>18</th>
        <th>19</th>
        <th>20</th>
        <th>21</th>
        <th>22</th>
        <th>23</th>
        <th>24</th>
        <th>25</th>
        <th>26</th>
        <th>27</th>
        <th>28</th>
        <th>29</th>
        <th>30</th>
        <th>31</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th style="font-size:12px;">Day Of Year</th>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <th style="font-size:12px;">Remaining Days</th>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </tbody>
  </table>
</body>

</html>
  • Does this answer your question? [Javascript calculate the day of the year (1 - 366)](https://stackoverflow.com/questions/8619879/javascript-calculate-the-day-of-the-year-1-366) – Matteo Meil Dec 18 '19 at 16:41

2 Answers2

2

In Javascript, and programming in general, dealing with date is one of the hardest things to do. How are you going to handle leap year, timezone, time changes, etc ? This is why it is always a good idea to use an external library. Now this might be an unpopular opinion but when it comes to dates, it's the right things to do.

Now with that in mind, I highly suggest using MomentJS. And in MomentJS, you can use the dayOfYear function to do just that.

// we create a now moment object, that defaults to today.
let today = moment();

console.log(today.dayOfYear());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

You can learn more why dealing with timezone is a pain, in this Tom scott's video

Nicolas
  • 8,077
  • 4
  • 21
  • 51
0

In both cases the simplest thing to do is work out a date fixed at the start of the year, and then simply divide into the the number of milliseconds after subtracting.

Below are 2 simple functions that use this technique.

ps. Both function assume the current day is not included, but you can alter to suite your needs.

const aDay = 1000 * 60 * 60 * 24;

function startOfYear(dt) {
  const n = new Date(dt);
  n.setDate(1);
  n.setMonth(0);
  n.setHours(0);
  n.setMinutes(0);
  n.setSeconds(0);
  n.setMilliseconds(0);
  return n;
}

function dayOfYear(dt) {
  const st = startOfYear(dt);
  return Math.trunc(
    (dt.getTime() - st.getTime()) 
    / aDay) + 1;
}

function daysLeft(dt) {
  const ed = startOfYear(dt);
  ed.setFullYear(ed.getFullYear() + 1);
  return Math.trunc(
    (ed.getTime() - dt.getTime())
    / aDay);
}


var dt = new Date();
console.log(`Day of the year = ${dayOfYear(dt)}`);
console.log(`Days left of the year = ${daysLeft(dt)}`);
Keith
  • 22,005
  • 2
  • 27
  • 44