I'm new at thunkable and I'm having trouble calculating weeks between two dates!

Any quick and easy ideas to make that calculation?

Classic has the Clock component, the clock component has (among several more) the following functions:

  • make instant (from)
  • duration (start, end)
  • duration to weeks (duration)

So, you use ‘make instant’ using the first date (specified as MM/dd/YYYY; I know, it is not elegant that the most logical YYYY-MM-dd is not available; at least it was not the last time I needed to use it) and then using the second date.
Then. you use the ‘duration’ by feeding both those instant as start and end. Now, you have a duration (it is expressed in millisecond), you could divide this by 60480000 to get a week, or rely on the more obvious ‘duration to weeks’ function.

That’s it.

1 Like

I’m using a two date picker to get the start date and end date, would it work the same? The date format is not really elegant!

Yes, date pickers would work the same.
You would use DatePickerStart.Instant and DatePickerEnd.Instant returned properties as input to a Clock.duration.
The lack of elegance of the date format is irrelevant since you never need to see it, but you can always format it to display as DatePickerStart.Text by building the caption using the day of the month, month code and year component extracted from the date picker, using the “DatePicker.After Date Set” event to launch the caption revision process.

Right!! I did something with the date picker to show the date in a textbox !! It’s functional !! But I’m trying part of the weeks count and I can not !! Here’s what I did with the data picker, I do not know if it’s the right logic to then use the clock !! Can you give me an idea on a button to make the count? Not of importance to the names, it is in Portuguese, because I am Brazilian !!date%20picker

Actually, you do not need the TextBox1 and TextBox2, the date with the format you want can be displayed on the date picker face itself.

And as far as the calculation is needed, all you need is a button that uses the ‘instant’ value set by the date picker.

image

Now, I do not know how you want to deal with the fractional weeks. The ‘duration to weeks’ function will return 0 until 7 days have gone by. If you would prefer to have 40 days to round up to 6 weeks, then perhaps the “Clock1.Duration To Days” could be used, when you divide the result by 7 to get a week and fraction (i.e. 40 days would read 5.714) or you use the math round function so that this 5.714 would round up to 6.
But right now, the duration to weeks would return 5 weeks when the time is 40 days, it is only complete weeks.

Yes, I know I do not need the textbox1 and textbox2, but I put a figure inside the textbox, so it was a bit strange, I preferred to put a textbox, I think there will be no problems !! In relation to the fractional sows, I did the test with the code that you sent me, it was all right, but I have whole weeks, and I also tested the frantioned question, which would be 30 days equals 4.28571, that was true too, but my treatment would need to be 30 days in weeks and days, 30 days equal to 4 weeks and 2 days !! Follow the code I made and everything went well here. If you find something that might make it different in this part, tell me !! And if you help me in that part “30 days equal to 4 weeks and 2 days”.

For the weeks + days, you would rely on two functions from the Math category, the floor and the modulo.

Once you have the number of days, you divide by 7 and take “floor”, which will remove all decimals.
For the days, you use the ‘remainder of division’ function modulo.

In this example, “total_days” would be set to the value you got from the .Duration_To_Days call, say for the sake or argument it happens to be 41

image

Then 41/7 is 5.857, and the floor function trims that to 5, that is the value of “full_weeks”.

Then the modulo function divides 41 by 7, finds that it is five with 6 remaining, so it returns 6.

So the answer is 5 full weeks and 6 days.

If the number of days was 42, then the modulo function would return 0.

I followed his last guidelines, but the result did not occur as expected !! Ex: 30 days = 4 weeks and 2 days, it’s happening 30 days = 4 weeks and 4 days, what’s wrong with my code? I’m not using global variables, is this the problem? Thanks in advance for your collaboration and learning !! Follow the code below for analysis !!

The problem is that you are overwriting the value of Lb_mostra_idada_gestacional with the floor and divide value, and then using that overwritten value for the modulo calculation. At that point, the result it contains is already changed, so the modulo is not dealing with the number of days, but the number of weeks.

Just to be perfectly clear on what is happening, in the first statement, you make the calculation that returns 30 days.
Since 30 days is not -1, you proceed.
Then you calculate 30/7, and get 4.2857. You take floor, and therefore get 4.0
Then you put that 4.0 value in the memory spot that contained the 30.
Then, you take modulo of 4.0 (!!!) by 7.

It should have been 30 modulo 7; but at this point, the value 30 is erased.

The real odd thing is that it would have worked if you had calculated the modulo first, before the floor function, because at that point you would NOT be overwriting the “Lb_mostra_idada_gestaciona” value yet. And there is danger in that, because it would have worked, and then one day, years from now, you modify the order for some reason, and it would stop working for a reason that is not that obvious.

If you made the clock duration result saved into a local variable “número_de_dias” and use this value for your test (by the way, do not compare it with exactly -1, it would be better if you used as “> 0” instead, in case someone inverted the start and end dates. You may get -38 days, and that is not -1, so the calculations would take place with crazy results) and as input for the two math functions (the floor divide, and the modulo one) you would have the right result.

It is a good practice to name your variables as a function of what they mean. Calling a variable “number of weeks” and feeding it a number of days would immediately signal that something is not coherent.

That is what I did with the example I provided. You can use label or text box at the very end, to display result, but using them for intermediate results is not a good idea; and the reason for that it involves a rather calculation intensive process. Putting the value in a text means converting the number into a series of character, using a formatting process, picking font size and so on, then using another process to convert those into pixels, and requesting the screen manager to update the display.
Meanwhile, updating a variable is only that: changing a value in a memory space.

I’ve been modifying a few things, and some tips that you provided, including calculating the module first, worked out and I was a bit worried about the intensive calculation process, what I could do to minimize this problem, not to lose values, or much use of memory, in that code.

Best use of memory and processing is to rely on the minimal object that will get the job done.
For computation, that would be a simple variable.
For text output (no input required) that would be a label (as opposed to a text box, as the text box has a bunch of events the system need to monitor–click in, click out, bring the keyboard, etc).
But, even if your program is not optimal, that is not an issue at this point. My application has over 7000 blocks, 5 screens, and about a dozen files as assets. You need not worry about efficiency that much now, but you should be aware of it, as if one day you develop a 7000 blocks app, any lack of efficiency would be felt.

Got it!! But now another problem has arisen, the days when they pass 31 or 28 (February), I would like to add in the next month!

That means another layer of complexity, because you now have to factor in the number of days in the month.

You already have an accurate days and weeks handling now, because days and weeks are fixed values.
To handle months, I do not see much beyond having a look-up table with the number of days each month has, with the added complexity of factoring in the leap day every 4 years, except when the year is a century that is not divisible by 400 (if you want to be formal about it. If you do not care about the intricacies of the leap year at century level and go with 29 days February every 4 years, you are still good until February 28, 2100 as there will not be a February 29 that year).

However, you have the benefit of the date handling in the clock in Classic, so can extract the month from any date associated with an instant, and can make an instant form any date entered.

At this point, you need to put down the equation as it need to be. What it is you want out? What is it that you already know?
Once you put down this as a set of rules, you just go ahead and code it.

From your question, I am not sure what you mean by “adding in the next month”.
Add what?

I forgot to explain this part of the add to next month !! I am calculating the probable date of birth, so there is a formula for this that adds values to the day, month, year, this part is working, but I came across this February problem, for example, that can happen, more days, eg February 28 days in that year, but I did a test and the probable date of birth gave 35 days of February, which does not exist, that difference of 35 to 28, which would be 7 days, should be added to the next month !! March 7 !!

The way to tackle this is by doing a validation of the due date, and that does indeed require a look-up table of each month – list number_of_days with values 31, 28*, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31. The * for the second entry means that you are to increase temporarily to 29 if this is a leap year.

Then suppose that the projected date is the 38th of June; you check 38 against the entry for June (30), and since it is more than the number of days, you subtract that 30 from 38, and add 1 to the month. So now you are looking at the 8th of the 7th month.
In effect, you could very well have a very silly date of 115th of February (for instance), where you test and reduce until (a while loop is indicated) until the number of the date is less than the number of days in the month.
115 February is the same as the 87th of March (if this is not a leap year, we subtracted 28)
87th of March is the same as 56th of April (minus 31)
56th of April is the same as 26th of May (remove 30)

Since 26 is less than the number of days in May, we stop here. That is the date: May 26.

If the calculation takes you across the 12th month, then you increment the year by one, and start anew with month 1 (i.e. you take it that January 1st is the same as December 32nd).

Simple enough?