DateDiff issue on today's date

I have code…

  DisplayDate = CDate(DisplayDate)
  TodaysDate = Date
  console.log("DisplayDate:" & DisplayDate & " TodaysDate:" & TodaysDate)
  DaysDiff = DateDiff("d",TodaysDate,DisplayDate) 
  console.log("DisplayDate2:" & DisplayDate & " DaysDiff:" & DaysDiff)

showing this in the console…

DisplayDate:9/30/2019 TodaysDate:9/29/2019
DisplayDate2:9/30/2019 DaysDiff:0

It’ll say datediff 09/29/2019 and 10/01/2019 is 1, 2 for the 2nd, and so on.
But prior to 09/29/2019 it calculates correctly.

What’s going on here?

The example you give, with DisplayDate being “9/29/2019”, works properly.

Can you give a date which gives the incorrect result?

Eh? Datediff from 29 to 30th should be 0? Shouldn’t the 29th to the 29th be 0? Because that is the answer I get for the 29th and 30th. I edited my question to be a little clearer.

Here’s what I see:

DisplayDate:9/30/2019 TodaysDate:9/29/2019
code.js:6 DisplayDate2:9/30/2019 DaysDiff:1

This is the code I am running:

DisplayDate = "9/30/2019"
DisplayDate = CDate(DisplayDate)
  TodaysDate = Date
  console.log("DisplayDate:" & DisplayDate & " TodaysDate:" & TodaysDate)
  DaysDiff = DateDiff("d",TodaysDate,DisplayDate) 
  console.log("DisplayDate2:" & DisplayDate & " DaysDiff:" & DaysDiff)

So I’m getting the correct result. One possibility could be time zones. Could DisplayDate be other than midnite? That could affect the calculation.

PS. Time zones can be a real pain to deal with.

Could well be. That is when daylight savings started for us.

If I have a date eg CDate(“09/29/2019”) it will display in console as “09/29/2019” but if I add a day to it it then displays “09/30/2019 12:00:00 AM”

That make a difference? I am gmt +12

Sounds like it’s a time zone problem.

There are a couple choices:

  1. Make sure all dates have a time of midnight.

  2. Use a library like moment.js to normalize all dates.

The BASIC functions for date and time handling are built on top of their JavaScript equivalents. If you google JavaScript date and time functions, you’ll find a lot of information.

That makes sense. Thanks

Is there a simple way of setting a date to midnight? Everything I come up with in my brain seems to be more complicated than it seemingly should be.

I wrote apps which need and do exact calculations of dates with adding and subtracting days and months. Never cared about setting to midnight.

There are several libraries which provide exact date calculations. It seems important to have a library which provides locales as well.

Currently I prefer to use moment.js. My extraheaders property e.g. would contain:

<script type="text/javascript" src="ted/moment-with-locales.min.js"></script>
<link rel="stylesheet" href="ted/tempusdominus-bootstrap-4.min.css" type="text/css" />
<script type="text/javascript" src="ted/tempusdominus-bootstrap-4.min.js"></script>
<link rel="stylesheet" href="css/all.css" type="text/css" />
<script type="text/javascript" src="js/all.js"></script>"

moment-with-locales.min.js enables to set the locale e.g. to “de_DE” which is done in datepicker settings.

tempusdominus provides a nice datepicker which works together with bootstrap 4.

Adding days and getting the precise new date would work like this:

datum2 = moment(datum1, "DD.MM.YYYY").add(vTageZahl, 'days').toDate();

For a functioning example (for my special purpose) see: FristPick

For commercial projects, we create a code module call util to handle all the date conversions using moment.js, then call those functions.

More on moment.js here:
https://momentjs.com/docs/

Here’s a snippet of our util functions:

    // Date conversion functions

    DDMMYYtoDDMMYYYY(d) {
      return (d === '') ? null : moment(d, 'DD/MM/YY').format('DD/MM/YYYY');
    },

    DDMMYYYYtoYYYYMMDD(d) {
      return (d === '') ? null : moment.utc(moment(d, 'DD/MM/YYYY')).format('YYYY/MM/DD');
    },

    YMM00toDDMMYY(d) {
      return (d === '') ? null : moment(d, 'YYMM').endOf('month').format('DD/MM/YY');
    },

    dateToDDMMYYYY(d) {
      return (d === null) ? '' : moment.utc(d).format('DD/MM/YYYY');
    },

    dateToDDMMYY(d) {
      return (d === null) ? '' : moment.utc(d).format('DD/MM/YY');
    },

    dateToDDMM(d) {
      return (d === null) ? '' : moment.utc(d).format('DD/MM');
    },

    dateToYYMMDD(d) {
      return (d === null) ? '' : moment.utc(d).format('YYMMDD');
    },

    dateToLocalDateTime(d) {
      return (d === null) ? '' : moment(d).format('DD/MM/YYYY hh:mm a');
    },

    dateTimeStamp(d) {
      return (d === null) ? '' : moment(d).valueOf();
    },

    DDMMYYToDate(d) {
      return (d === '') ? null : moment.utc(d, 'DD/MM/YY').toDate();
    },

    DDMMYYYYToDate(d) {
      return (d === '') ? null : moment.utc(d, 'DD/MM/YYYY').toDate();
    },

    startOfMonth(d) {
      return moment(d, 'YYMM').toDate();
    },

    endOfMonth(d) {
      return moment(d, 'YYMM').endOf('month').toDate();
    },

    monthShortName(d) {
      return moment(d).format('MMM');
    },

    dateJStoDB(d) {
      // converts a DD/MM/YY string to an ISOString suitable for SQLite.
      if (d === null) return null;
      if (!d.toISOString) {
        return (d === '') ? null : util.DDMMYYToDate(d).toISOString();
      }
      return d.toISOString();
    },

    dateDBtoJS(d) {
      return (d === null) ? null : moment.utc(d).toDate();
    },

    dateNowUTC() {
      return moment.utc({ hour: 0 });
    },

    dateNow() {
      return util.dateNowUTC().toDate();
    },

    dateNowDDMMYY() {
      return util.dateNowUTC().format('DD/MM/YY');
    },

    dateNowDDMMYYYY() {
      return util.dateNowUTC().format('DD/MM/YYYY');
    },

    dateNowYYYYww() {
      return util.dateNowUTC().format('YYYYww');
    },

    dateNowDateTime() {
      return util.dateNowUTC().format('DD/MM/YYYY hh:mm a');
    },

    DDMMYYYYToDateNoUTC(d) {
      // used in datepicker.js. Pickadate wants non UTC date.
      return (d === '') ? null : moment(d, 'DD/MM/YYYY').toDate();
    },

    dateAgo(d) {
      // returns days ago from current date
      return moment.utc().startOf('day').diff(d, 'days');
    },

    dateInFuture(d) {
      // checks if DDMMYY is in future
      if (d === '') return null;
      return (moment.utc().diff(util.DDMMYYToDate(d)) < 0);
    },

    dateAddDays(d, days) {
      if (d === '') return null;
      return moment.utc(d).add(days, 'days').toDate();
      // Should be the same as DateAdd("d",d1) in BASIC - if not,  please correct
    },

    dateAddToDDMMYY(days) {
      const today = util.dateNow();
      return util.dateToDDMMYY(util.dateAddDays(today, days));
    },

    dateAddMonths(d, months) {
      if (d === '') return null;
      return moment.utc(d).add(months, 'months').toDate();
      // Should be the same as DateAdd("m",d1) in BASIC - if not,  please correct
    },

    dateDifferenceDays(d1, d2) {
      return moment.utc(d2).startOf('day').diff(moment.utc(d1).startOf('day'), 'days');
    },

    dateStartOfYear() {
      return moment.utc().startOf('year');
    },

    dateSetValues(el, d) {
      // set the value in DDMMYY format, and data-value for pickadate.
      // eslint-disable-next-line no-param-reassign
      el.value = d;
      if (!d) {
        el.setAttribute('data-value', '');
      } else {
        el.setAttribute('data-value', util.DDMMYYtoDDMMYYYY(el.value));
      }
    },

    dayOfWeek() {
      return util.dateNowUTC().isoWeekday(); // 1 - Monday ... 7 - Sunday
    },

Just to confirm we are talking about the same thing. If I run this code I get “True - DateDiff is equal” in the console. Nobody else get that?

  If DateDiff("d","09/29/2019","09/29/2019") = DateDiff("d","09/29/2019","09/30/2019") Then
    console.log("True - DateDiff is equal")
  Else
    console.log("False - DateDiff is different")
  End If

FYI DateDiff(“d”,CDate(“09/29/2019”),CDate(“09/29/2019”)) gives the same result

I’ve worked out the issue is daylight saving (for us was changing to daylight saving 2am 29th Sept)

So the datediff of “09/29/2019” & “09/30/2019” is…
days = 0 (obviously not rounded up)
hours = 23 (-1hr)
minutes = 1380 (-60 min)

Anybody else identify and deal with this?

cdate seems to be BASIC / Visual Basic
DateDiff: AppStudio Reference says: DateDiff

This function is for BASIC compatibility. It is not available in pure JavaScript projects.

Since AppStudio no longer supports code coming von BASIC, even when translated to JavaScript, I rewrote all my JavaScript apps where deprecated functions like cdate and DateDiff occured, using moment.js.
Maybe this is the reason why no other user reports problems like this.

This isn’t true - AppStudio absolutely does still support code written in BASIC.

If you are using only JavaScript in your project, you need to include the BASIC library if you want to call BASIC functions in your code. Here’s how:

It’d be a rare thing to pickup I imagine. Even if a developer was calculating datediff across daylight savings start, the result appears accurate. Only discovered it myself as my app was “scrolling” through a few days coincidentally over daylight savings start.

George, might be worth a note in your docs for future users? Or modify Datediff function to allow for this?

Fyi for those interested, I have my own function for days difference now to fix the issue…

Function DaysDateDiff(interval, Date1, Date2)
DaysDateDiff = Round(DateDiff(“h”, Date1, Date2)/24)
End Function

@Leader: This is an information I would have preferred to get sooner. We had exchanged messages about this, because my working code after an AppStudio update sudddenly stopped working after changing insignificant JavaScript code. It was a lot of trouble and spent time to achieve this. Mabe I misunderstood or I intended to get rid of BASIC anyway. It is pure JS now and as far as I currently am aware, it seems not necessary any more to include a BASIC library.
Sorry for my fake news.
PS: Why is cdate missing in help/reference? Why does the reference file just say that DateDiff is deprecated in pure JS code? Should not the reference become updated?
Update: I think I once tried the library but was not happy with the results.