4

I have a date that I receive from a mySQL database via an API. This date comes in as the expected mySQL format: yyyy-MM-dd. I then reformat this to MM-dd-yyyy with the following JS:

const date = data.dateOfService;
const [year, month, day] = date.split('-');
const dateObj = {month, day, year};
value = (dateObj.month + '-' + dateObj.day + '-' + dateObj.year);

Where value is the field in form.io that the calculation/script is taking place. At any rate, the issue is that I actually need to display the previous day of the original MySQL date.

yyyy-MM-dd -1 => MM-dd-yyyy

Does anyone know how this can be approached? I am stumped.

Abhishek Bhagate
  • 5,583
  • 3
  • 15
  • 32
tmman
  • 69
  • 1
  • 9

5 Answers5

2

Use your year, month, and day variables to create a date object. Subtract one from that date object and wrap that in another date object. Then use the functions on the date object to extract your desired string.

For the code below, it helps to know that in javascript January = 0.

const date = '2020-01-01';
const [year, month, day] = date.split('-');

let dt = new Date(new Date(year, month - 1, day) - 1);

console.log(`${dt.getMonth()+1}-${dt.getDate()}-${dt.getFullYear()}`);

I picked January 1st on purpose. You can see that it properly rolls back to December 31st of the previous year.


If you need to pad the month and date with leading zeroes for single digits, then you can use padStart(). It's not as pretty, but does the trick:

(dt.getMonth()+1).toString().padStart(2,0) + '-' + 
dt.getDate().toString().padStart(2,0) + '-' + 
dt.getFullYear();
pwilcox
  • 5,542
  • 1
  • 19
  • 31
  • This gets me VERY close. Any easy way to append a zero on single digit days and months? That way it's 08-09-2020 instead of 8-9-2020. – tmman Aug 14 '20 at 18:44
  • 1
    I added sample code using `padStart()`. For the sake of brevity, I didn't make it into a snippet, but I tested it and it seems to successfully pad today's date. – pwilcox Aug 14 '20 at 18:52
1

If you are getting the value correctly into the date variable, you can use the code below to get the result as expected -

const date = '2020-01-01';
const prevDate = new Date(date);
prevDate.setDate(prevDate.getDate() - 1);

const value = ((prevDate.getMonth() + 1) + '-' + prevDate.getDate() + '-' + prevDate.getFullYear());
// A better/efficient way to assign would be as follow using template literals -
// const value = `${prevDate.getMonth() + 1}-${prevDate.getDate()}-${prevDate.getFullYear()}`

console.log(value);

Using the above approach will work for all corner cases like when the date you have initially is the start of any month or when the year is a leap year. Since we are using inbuilt JS date methods, that will all be handled by Javascript.

Abhishek Bhagate
  • 5,583
  • 3
  • 15
  • 32
  • 3
    I think the problem here is it does not account for an instance where the date is January 1st, 2020. Subtracting 1 from the day here would not appropriately change the other object parts. – tmman Aug 14 '20 at 18:13
  • @tmman Check the edit... I have changed the approach used and this should work fine – Abhishek Bhagate Aug 14 '20 at 18:30
  • Your edited code results in two days previous, not one. `const prevDate = new Date(date)` already results in the day before. I can't explain why, but it does. I certainly think it's safer to not make a new Date object from a string. – pwilcox Aug 14 '20 at 18:38
  • @pwilcox No. The result I get always gives the correct previous day's date. You can check with few dates and tell me if there are any bugs – Abhishek Bhagate Aug 14 '20 at 18:40
  • 1
    I am unfortunately getting -2 days as well. – tmman Aug 14 '20 at 18:42
  • As of this writing, running your code snippet results in '12-30-2019' with an input date of '2020-01-01'. That's two days before. – pwilcox Aug 14 '20 at 18:42
  • @pwilcox Where are you running the code...In the answer, you can see when you run the code snippet its showing 12-31-2019 – Abhishek Bhagate Aug 14 '20 at 18:44
  • Very weird! Glendale, AZ, USA. Chrome 84.0.4147.105. How about yourself? – pwilcox Aug 14 '20 at 18:54
  • Formatting of the 2-digits from month and days is not implemented (e.g. '2020-01-06' results in "1-5-2020" instead of "01-05-2020". Look at my solution. – Sascha Aug 14 '20 at 18:54
  • @pwilcox I checked on JSfiddle as well...I get same correct output – Abhishek Bhagate Aug 14 '20 at 19:00
  • JSFiddle check over here as well. Results in "12-30-2019". But I'm guessing JSFiddle output depends on browser implementation. – pwilcox Aug 14 '20 at 19:03
  • @Abhishek. It think I figured it out. See [this](https://stackoverflow.com/questions/7556591/is-the-javascript-date-object-always-one-day-off). It's because when you do a date from a string like that, it fills in the time (or at least the hour) portion with the current time of your system. Wrap that up in a date and it can do some rounding which will be different based on zimezones. When you put in numbers in the date constructor, it sets time components to 0. The latter is safer. – pwilcox Aug 14 '20 at 19:09
  • Sorry, I don't think I had the reasoning quite right in the previous comment. But go to the referenced link and you'll learn more. – pwilcox Aug 14 '20 at 19:17
1

First splitting to get the year, month and day. Create with day-1 (for yesterday) and 12 hours (for security for changingday winter/summertime) a new date (note: months -1 because JS months 0-11).

Create for output string with getDate, getMonth (+1 because of JS 0-11) and getFullYear. For formatting hours and minutes as 2-digit add before the string '0' and then take the last 2 chars.

You can try it, there are even no problems with year or monthchange.

function convertToYesterday(date) {
    let [year, month, day] = date.split('-');
    let yesterday = new Date(year, month-1, day-1, 12);
    return ('0'+(yesterday .getMonth()+1)).slice(-2) + '-' + ('0'+yesterday .getDate()).slice(-2) + '-' + yesterday .getFullYear();
}

console.log(convertToYesterday('2020-01-01'));
console.log(convertToYesterday('2020-03-01'));
console.log(convertToYesterday('2020-08-14'));
Sascha
  • 4,576
  • 3
  • 13
  • 34
0

I wouldn't use split I would use the built in date function to do the conversion then just use the built in date functions to get the month/day/year also.

function addN(n){return n<10? '0'+n:''+n;}

const yesterday = new Date("2020-10-5");
yesterday.setDate(yesterday.getDate() - 1);
_date = addN(yesterday.getMonth()+1) + "-" + addN(yesterday.getDate()) + "-" + yesterday.getFullYear()
console.log(_date)
imvain2
  • 15,480
  • 1
  • 16
  • 21
0
 var my_date_format = function (input) {
   var d = new Date(Date.parse(input.replace(/-/g, "/")));
    var month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 
     'Oct', 'Nov', Dec'];
     var date = (d.getDay() - 1).toString() + " " + 
     month[d.getMonth().toString()] + ", " + 
     d.getFullYear().toString();
     return (date);
  };

Now you just need to call this function and pass the date comming from databse.

Mudit Gulgulia
  • 1,131
  • 7
  • 21