The PHP script captures the values and calculates the future value. working backwards from the last month to the first, how could I compute the investment for the previous month and display the months number and the value all the way back to the first investment (Unknown). I've already figured out that I'll have to uses a formula like this "months value = (months value)/(1 + rate)" but after that I hit a road block. basically I'm trying how to figure how much do you invest today to have a balance value of $XXX after xx years at a x% interest rate?
<?php
// get the data from the form
$investment = $_POST['investment'];
$interest_rate = $_POST['interest_rate'];
$years = $_POST['years'];
// calculate the future value
$future_value = $investment;
for ($i = 1; $i <= $years; $i++) {
$future_value = ($future_value + ($future_value * $interest_rate *.01));
}
// apply currency and percent formatting
$investment_f = '$'.number_format($investment, 2);
$yearly_rate_f = $interest_rate.'%';
$future_value_f = '$'.number_format($future_value, 2);
?>
Your formula is basically this:
Start with X
For each of the Y years, increase X by Z%
This is a simple function: result = X * (1+Z%)^Y
So you know there's a specific result you want, and you know the number of years and the interest rate, and you want to calculate the base amount. Easy: X = result / (1+Z%) ^ Y
Using your variable names, you'd get
$investment = $future_value / pow(1+$interest_rate/100,$years);
Done!
Related
I want to display to a user an amount per day and increment it until the next 124 days assumed to be four months.
I have a system where a user invest and a total ernable profit is calculated with the percentage ROI for such stock. Assuming someone invested in a stockA that has 20% ROI and matures in 4 months; assuming a user purchased that stockA that is sold $100 and he bought 4 units meaning he spent $400 and will earn
as follows:
$units = 4;
$cost = 100;
$roi = 20/100;
$total_invested = $units * $cost;
$profit = $total_invest * $roi;
// $profit will be $80
My problem is I want to display value of $profit/124 that is the displaying a fraction of total earning to the user daily until maturity of 4 months. I can't figure out how to do that daily not just with loop of 124 iterations.
that is if the user total earning is $80/124 giving 0.65 on the first day and increment it with same value the next day until it reached the end date which is 4 months from now
/**
*
* display and increment earning every day for 4 months or 124 days
*
*/
function display_earning() {
$profit = $profit_roi;
$dateBegin = now();
$dateEnd = "date of 4 month from now";
$earning = 0;
for ($i = 0; $i < 124; $i++) {
$earning += $profit / 124;
return $earning;
}
}
I think your problem is to update and save the updated earning of user for 4 months. To do that you need to write a server level cron-job that run on every day and a script in which you update and save the earning of user and check it has reached 4 months for that user since you started or not.
I hope you want this and that will help you. Happy Learning.
It's not clear what you want your code to do. Do you want it to give the total earned cumulatively by day x or give the total earned on any one day? If it is any one day and you don't want to take compound interest into account the earning will be the same every single day. In which case all your function has to do is return
function return_earnings($profit, $totalDays) {
return $profit / $totalDays;
}
as the amount earned each day will be the same as any other day. If you do want compound interest then you'll need to code that it. I assume you don't as there is no sign of it in the code you supplied.
I get the feeling what you are looking for instead is a list of how much was earned each day cumulatively. If that's the case, the code you've written is more appropriate but needs some modification. At the moment your code is returning $earning after the first iteration of the loop. Moving return to the end of the function should fix that.
function display_earning() {
$profit = $profit_roi;
$dateBegin = now();
$dateEnd = "date of 4 month from now";
$earning = 0;
$totalDays = 124; // You might want to change '124' in future
// and having $totalDays in the for loop makes it more
// obvious what your code is trying to do.
for ($i = 0; $i < $totalDays; $i++) {
$earning += $profit / $totalDays;
}
return $earning;
}
However now because of the line $earning += you will return the sum of earning at the end of $totalDays, ie the $profit, which you already know! You may want the cumulative earnings by a given day to be an item in an array, in which case:
function display_earning() {
$profit = $profit_roi;
$dateBegin = now();
$dateEnd = "date of 4 month from now";
$totalEarning = 0; //renamed to $totalEarning
$earningsByDay = array();
$totalDays = 124;
for ($i = 0; $i < $totalDays; $i++) {
$totalEarning += $profit / $totalDays;
$earningsByDay[$i] = $totalEarning;
}
return $earningsByDay;
}
This will now return an array with each element of the array amounting to the sum earned by that day. For example, $earningsByDay[0] will be the first day, $earningsByDay[11] will be the 10th day etc. If this is what you are looking for, you can use php's native range() function to make your life easier:
function display_earning() {
$profit = $profit_roi;
$dateBegin = now();
$dateEnd = "date of 4 month from now";
$totalEarning = 0; //renamed to $totalEarning
$earningsByDay = array();
$totalDays = 124;
return range(0, $profit, $profit/$totalDays)
}
A few final thoughts:
You say you want to display the amount earned each day. You function does not display anything it just calculates a value and returns it. That's good practise. Have your functions do one thing. Some other function can display the data from this one, or perhaps multiple functions can, each formatting it in a way that is appropriate for your current need. I can't help you with the display as I have no way of knowing what format you want. $dateEnd probably doesn't need to be in the function.
On a related note, another function name might lead to less confusion about what the function does.
I'm not sure what $dateBegin = now(); adds, unless as Moeez Saiyam suggests, you are trying to automate this somehow.
You've defined $profit = $profit_roi; without declaring what $profit_roi is in the scope of your function. I know it was in your introductory notes, but the function won't know that.
Is the function the right place to define $profit and $totalDays? They are probably passed to the function form elsewhere.
Combining these thoughts, this gives us:
function getIncrementalEarnings($profit, $totalDays) { //function renamed to clarify its purpose
return range(0, $profit, $profit/$totalDays)
}
I have a date that goes into a loop that the user specifies. The date will always come from the database formatted as a 'Y-m-d' string. I am aware that I can compare the strings directly as long as they are in that format, however, I have also tried using strtotime to convert the dates to compare them with no luck. I am trying to determine how many paycheck a user has before a payment is due
Here is what I have
$due_date = '2016-12-13';
//count paychecks set to zero and added to by loop
$paychecks = 0;
//users next paycheck ('Y-m-d' ALWAYS)
$next_payday = $user['next_payday']; //equal to '2016-12-02'
//how often they get paid (int)
$frequency = 14;
while(strtotime($next_payday) <= strtotime($due_date)){
//next_payday equals 1480654800 when coming into the loop
//due_date equals 1481605200 when coming into the loop
//add 14 days to the date
$next_payday = date('Y-m-d', strtotime("+" .$frequency." days"));;
//add to paychecks
$paychecks++;
}
The problem is that the loop never stops. It keeps going and going.
Thanks for any help anyone can give me.
Ah, be sure to use strtotime to get integers (representing number of seconds since the epoch) for comparison and multiply your frequency of days by the number of seconds in a day (86400):
$due_date = strtotime('2016-12-25');
//count paychecks set to zero and added to by loop
$paychecks = 0;
//users next paycheck (unixtime for comparison)
$next_payday = strtotime($user['next_payday']);
//how often they get paid (int)
$frequency = 14;
while($next_payday <= $due_date){
//add 14 days to the date
$next_payday += ($frequency * 86400);
//add to paychecks
$paychecks++;
}
I am currently working on a reservation system in PHP (Laravel 5) and I can't figure out how to build a time based pricing system that calculates the totalprice with overlaps. Reservations are stored with the following fields
Reservations (Table)
begindate_time (DateTime)
enddate_time (DateTime)
price (decimal(10,2))
I have a prices table to lookup the prices for the input begintime and endtime which looks like this:
Prices (Table)
id (INT)
price (decimal(10,2))
begin_time (time)
end_time (time)
dayOfTheWeeks (varchar(255))
The begin_time/end_time can vary from 00:00:00 to 23:59:59 and the dayOfTheWeeks is a string with days for instance monday,tuesday,wednesday. I know there should only be one value for each field, but I was to lazy to make a whole table for the days of the week.
Than you have a activity that is linked to a reservation that has different prices based on the time the activity this is linked to a price_activity table, because prices can have different activity's
activity_price (Table)
id
activity_id (INT)
price_id (INT)
I tried to get the prices foreach activity and day like this, than I have them sorted and can try to loop through them and substract the endtime of the price minus the begintime of the reservation. This is what I came up with but it is not working...
foreach($activity->prices()->orderBy('begin_time','asc')->get() as $price){
$whichDayArray = explode(',',$price->dayOfTheWeeks);
if(in_array($dayToday,$whichDayArray)){
$prices = array();
if(strtotime($price->end_time) > strtotime($input['begintime']) && strtotime($price->begin_time) < strtotime($input['endtime'])){
$prices[] = array('id' => $price->id,'price' => $price->price,'beginTimePrice' => $price->begin_time, 'endTimePrice' => $price->end_time);
}
}
}
This is a lot of code and I have my prices that are overlapping my reservation now, but how do I calculate the amount of time a reservation is in a price. I think it can be done much easier and better than the above.
I've solved my own question. Hoping to help others with a similar problem, I would like to explain how I solved my problem.
After dumping my variables and making a visualization of the problem as shown below I found that the problem was related to my query.
[--pricerange1--][--pricerange2--][--pricerange2]
[----------reservation-----------]
I have to get all the prices for a activity on a given day of the between the begintime of the reservation and the endtime of a reservation, after that I have to check if there is one price, two prices or more than 2 prices. Than calculate the number of hours that a reservation is in a range and multiply it by the price a range. The code for this will look like this:
$begintijd = \Carbon\Carbon::createFromTime(16,30);
$eindtijd = \Carbon\Carbon::createFromTime(20,30);
$activiteit = \App\Activiteit::find(1);
$prijzen = $activiteit->prices()->where('eindtijd','>=',$begintijd->toTimeString())->where('begintijd','<=',$eindtijd->toTimeString())->orderBy('begintijd','asc')->get();
$prijzenArray = array();
foreach($prijzen as $prijs){
$whichDayArray = explode(',',$prijs->welkedagen);
if(in_array('maandag',$whichDayArray)){
$prijzenArray[] = array('prijs' => $prijs->prijs,'begintijdprijs' => $prijs->begintijd,'eindtijdprijs' => $prijs->eindtijd);
}
}
$countPrijzen = count($prijzenArray);
if($countPrijzen == 1){
$aantaluur = $begintijd->diffInMinutes($eindtijd) / 60;
$totaalprijs = $aantaluur * $prijzenArray[0]['prijs'];
echo('range1');
}
if($countPrijzen == 2){
$aantaluurrange1 = \Carbon\Carbon::createFromFormat('G:i',$prijzenArray[0]['eindtijdprijs'])->diffInMinutes($begintijd) / 60;
$aantaluurrange2 = $eindtijd->diffInMinutes(\Carbon\Carbon::createFromFormat('G:i',$prijzenArray[0]['eindtijdprijs'])) / 60;
$totaalprijs = ($aantaluurrange1 * $prijzenArray[0]['prijs']) + ($aantaluurrange2 * $prijzenArray[1]['prijs']);
echo('range2');
}
if($countPrijzen > 2){
$aantaluurrange1 = \Carbon\Carbon::createFromFormat('G:i',$prijzenArray[0]['eindtijdprijs'])->diffInMinutes($begintijd) / 60;
$prijsrange1 = $prijzenArray[0]['prijs'] * $aantaluurrange1;
$prijsertussen = 0;
for($prijs=1;$prijs<($countPrijzen-1);$prijs++){
$aantaluurertussen = \Carbon\Carbon::createFromFormat('G:i',$prijzenArray[$prijs]['eindtijdprijs'])->diffInMinutes(\Carbon\Carbon::createFromFormat('G:i',$prijzenArray[$prijs]['begintijdprijs'])) / 60;
$prijsertussen += $prijzenArray[$prijs]['prijs'] * $aantaluurertussen;
}
$aantaluurlaatsterange = $eindtijd->diffInMinutes(\Carbon\Carbon::createFromFormat('G:i',$prijzenArray[$countPrijzen-1]['begintijdprijs'])) / 60;
$prijslaatsterange = $prijzenArray[$countPrijzen-1]['prijs'] * $aantaluurlaatsterange;
$totaalprijs = $prijsrange1 + $prijsertussen + $prijslaatsterange;
}
I'm trying to create a for loop where I specify a beginning date and end date and I want to pull a random mix of dates where each date will always be later than it predecessor and earlier than the next number.
There is no pre-defined set of dates I need, I may have 10 - I may have 100 or 1000 as long as they exist within the start and end dates.
Example:
2015-01-15 08:06:00
2015-01-15 15:23:42
2015-01-16 06:03:00
.........
.........
2015-01-20 08:18:32
This is what I have (which is wrong):
$start = strtotime('2015-01-10 08:00:00');
$end = strtotime('2015-01-20 10:57:59');
for ($i=$start;$i<$end;$i++) {
//Current time + Anywhere between 1 hour and 3 days
$x = $i + (int)rand(3600,259200);
echo "<p>" . date('Y-m-d H:i:s', $x) . "</p>";
}
In my tests, I'm not getting any results...I believe the loop is running infinitely...or something else is wrong.
Can anyone help?
If I gather your question correctly, it seems like you're going about it the wrong way. The easiest way would be to generate random times in a range (between $start and $end) and then sort them. That way you don't have to guess at how much time-space you have left when choosing a random interval.
$start = strtotime('2015-01-10 08:00:00');
$end = strtotime('2015-01-20 10:57:59');
$num_randoms = 10;
for ($i=0;$i<$num_randoms;$i++) {
$dates []= (int)rand($start,$end);
}
sort($dates);
foreach ($dates as $x) {
echo "<p>" . date('Y-m-d H:i:s', $x) . "</p>";
}
You assumed that those two will be your dates
$start = strtotime('2015-01-10 08:00:00');
$end = strtotime('2015-01-20 10:57:59');
You assumed also that you will use specific range of seconds for pseudorandom number generation
$min = 3600; // 1 hour
$max = 259200; // 72 hours (3 days)
The first step you need to do is to reduce the ending number of seconds with the range maximum. This will assure you that latter date will be before the specified date
$end -= $max;
And at the end here is the proper loop. I used while loop because it is more readable.
while ($start < $end) {
$start += (int) mt_rand($min, $max); // add the generated value to the start seconds
echo date('Y-m-d H:i:s', $start);
}
PS. Notice I used the mt_rand function
Use the milliseconds representation of you date value. Pseudo-code is as follows:
Convert the start date to its milliseconds representation sm
Convert the end date to its milliseconds representation em
For i = 0 up to n, n is the number of dates...
3.1 randomize some value between sm and sm + offset
3.2 convert the generated value to its date object representation
3.3 assign sm = sm + offset and check if sm < em
offset is the size of the sampling interval, offset <= (em - sm) / n
Heres the code I have at the moment, its all working as intended, however, the cumulative total isn't working, and I'm positive I'm doing something absolutely stupid.
assume period = 20
assume inflation = 3
assume nightlycost = 100
assume nights = 7
$yearlycost = $nightlycost*$nights;
while ($period > 0) {
$period = $period-1;
$yearlyincrease = ($inflation / 100) * $yearlycost;
$nightlyincrease = ($inflation / 100) * $nightlycost;
$nightlycost = $nightlycost + $nightlyincrease;
$yearlycost = ($yearlycost + $yearlyincrease) + $yearlycost;
}
Result:
Nightly Hotel Rate in 20 years: $180.61 - <?php echo round($nightlycost, 2); ?> correct
Weekly Hotel Rate in 20 years: $1264.27 - <?php echo round($nightlycost, 2) * 7; ?> correct
Total cost to you over 20 years: $988595884.74 - <?php echo round($yearlycost, 2); ?> incorrect
Everything outputs correctly and as expected, except for the yearly cumulative cost. It should take the previous yearly cost and add that years cost+inflation.
Example: first year is 700, so second year should be 700 + 700 + 21 (21 is 3%, the inflation for that year). Second year cumulative total is thus: 1421. Third year will be 1421 + 721 (last years total) + 3% of 721.
Hopefully this is clear enough for you to see where I'm going wrong. Thanks!
I find it hard to understand where your code goes wrong, but my intuition is that the last line in your loop body should have a multiplication.
Basically, you have a base cost for period 0. Then you want to calculate the cumulative cost given inflation after X years. That cost is (pseudocode)
base = nightlycost + nights
infl = 1.03
cumulative = base + base*infl + base*infl^2 + base*infl^3 + ... + base*infl^periods
The last expression can be simplified to
cumulative = base*((1-infl^periods)/(1-infl))
(This holds according to Eq. 4 here: http://mathworld.wolfram.com/ExponentialSumFormulas.html)
Example:
$base = 100*7;
$infl = 1.03; // 3% of inflation/year
$periods = 2;
$cumulative = $base * (1-pow($infl, $periods))/(1-$infl);
print "Cumulative cost after $periods is $cumulative\n";
// Let's try with three periods.
$periods = 3;
$cumulative = $base * (1-pow($infl, $periods))/(1-$infl);
print "Cumulative cost after $periods is $cumulative\n";
Output:
Cumulative cost after 2 is 1421
Cumulative cost after 3 is 2163.63