0

I'm currently populating a table with data from a soap web service, the date comes as a string (example 44250). I created a function to format it into a yyyy/mm/dd format.

Outside the loop I have this function:

Date.prototype.addDays = function (days) {
          var date = new Date(this.valueOf());
          date.setDate(date.getDate() + days);
          return date;
        };

Inside the loop I have:

else if (detailsItem == details[i].children[1].innerHTML) {
          const dbDays = days[i].innerHTML;
          const daysInt = parseInt(dbDays, 0);
          const newDate = firstDate.addDays(daysInt);
          // Format the date to a readable value
          const partsDate = {
            date: newDate.getDate(),
            month: newDate.getMonth() + 1,
            year: newDate.getYear() + 1900,
          };
          finalDate = `${partsDate.date}/${partsDate.month}/${partsDate.year}`;
          const td = document.createElement("td");
          td.textContent = finalDate;
          tr.appendChild(td);
          }

the else if is just checking when to add the date to the table while populating it.

I now need to send a request to the service using the date again but in the previous format, but the date has to be in the same row as the button click, the service only accepts the string format of the date, I'm currently stuck and unsure on how to format it back.

This is the button click function which has to then format the date back to a format such as 44250.

btn.onclick = function () {
                // Loops through the table to find the slot and date when clicking the button on the same row
                var tableRow = document.getElementById("booking-table"),
                  rIndex;
                for (var i = 0; i < tableRow.rows.length; i++) {
                  tableRow.rows[i].onclick = function () {
                    rIndex = this.rowIndex;
                    bookingDay = this.cells[1].innerHTML;
                    bookingSlot = this.cells[2].innerHTML;
                    console.log(bookingSlot, bookingDay);
                  };
                }

Any help on how to accomplish this would be appreciated.

2
  • It would probably be a good idea to separate the data and presentation layers. When parsing data from the web service, store the date in its original format and only use the transformed readable format for presentation. Commented Feb 23, 2021 at 13:35
  • This is definitely a good point, will look into doing that, thank you very much for the tip! Commented Feb 23, 2021 at 17:11

2 Answers 2

1

The value "44250" looks like the number of days since 31 Dec 1899 (the epoch), which means a value of "1" converts to 1 Jan 1900. If that's correct, you can create a Date from it using:

let dbDays = '44250';
let date = new Date(1900, 0, dbDays); // 24 Feb 2021

In this algorithm, 1 is 1 Jan 1900 and 0 is 31 Dec 1899.

You can convert it back to an epoch offset using the reverse algorithm:

let dbDays = Math.round((date.getTime() - new Date(1899, 11, 31) / 8.64e7);

Which gets the difference in ms since the date and the epoch, then divides by ms in one day and rounds it to account for possible daylight saving effects where days aren't exactly 24 hours long. This method only works for whole days, it doesn't work for partial days.

The algorithm might be out by a day if 1 Jan 1900 should be 0 rather than 1, just adjust the base dates used in the functions.

Simple functions to go from dbDate to Date instance and back are:

// Convert epoch days to Date
function toDate(dbDays) {
  return new Date(1900, 0, +dbDays);
}

// Convert Date to epoch days
function toDBDays(date) {
  return Math.round((date - new Date(1899,11,31)) / 8.64e7);
}

// Format date as dd/mm/yyyy
function formatDate(d) {
  let z = n => ('0'+n).slice(-2);
  return z(d.getDate()) + '/' + z(d.getMonth()+1) + '/' + d.getFullYear();
}

// Parse date in d/m/y format, any non-digit separator
function parseDate(s) {
  let [d,m,y] = s.split(/\D/);
  return new Date(y, m - 1, d)
}

// Example
let dbDays = '44250';
let d1 = toDate(dbDays);  // 24 Feb 2021
let ts = formatDate(d1);  // 24/02/2021

let d2 = parseDate(ts);   // date object

console.log(dbDays + ' to Date: ' + ts);
console.log(ts + ' to dbDays: ' + toDBDays(d2));

PS Given the epoch won't change, instead of creating a date for 31 Dec 1899 and getting its time value, the constant -2209111200000 can be used.

Notes on your code:

const daysInt = parseInt(dbDays, 0);

The second argument to parseInt is a radix or base to use for conversion to number. The value 0 is replaced with 10 (the default radix), so the above is equivalent to:

const daysInt = parseInt(dbDays, 10);

Then there is:

const partsDate = {
  date: newDate.getDate(),
  month: newDate.getMonth() + 1,
  year: newDate.getYear() + 1900,
};

The getYear method returns a 2 digit year, it's not recommended and is supported mostly for historic reasons, use getFullYear instead.

Using an object for temporary storage is not really optimal, just use variables:

let date = newDate.getDate(),
    month = newDate.getMonth() + 1,
    year = newDate.getFullYear();

Note that this doesn't pad single digit days or months with leading zeros so will produce timestamps like 1/1/2021 instead of 01/01/2021.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much for this detailed explanation and for putting in the time to go over so many things, I appreciate all the help!
-1

You can use momentjs to convert the date easier: https://momentjs.com/ , about the use of the date after you pass that value to the html, can you store that value on some global variable,sesion or localstorage? and then use it later? to call again the soap service? i'm asumming your working on a web page, cause your using html :)

2 Comments

This isn't an answer, it might be a useful comment.
you are right im new here sorry about that, just learning how to use this aweosome site! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.