Math Functions that turns decimal value from Months into Days/Weeks - javascript

So i have a really complex system i wrote for my teacher it does a bunch of math that he had in a spreadsheet that finds out basically how long it takes someone to save up enough money to cover an asset of there. Long story short i currently have it saying for example "You will receive enough money to cover this asset in 0.38 months"
I would like to be as user friendly as possible, i dont care if i have to come up with a math function for each month. My question is, how would i spit out 0.39 Month to Weeks and Possibly if i can Days (which would actually make more sense because i can make a script that says if greater then 7 then that is equal to 1 week) to make it even more precise. I know for starters i need to know how many days are in each month, not every month is the same as we all know. Any starting point after that would be great. Im jQuery/JS for this math functions to this application.

To put my comments in answer form:
function getDays(numMonth, month, year) {
var numDays = new Date(year, month, 0).getDate();
return numMonth * numDays;
}
function getWeeks(numMonth, month, year) {
var days = getDays(numMonth, month, year);
return Math.floor(days / 7);
}
This is where numMonth = 0.39, etc.

Related

Javascript Date, loop around to original date when over one year?

not sure how exactly to phrase this question, but I want to basically "loop around" a date, when it's more than a base date
What does that mean?
Let's say my start date is 7/7/2021
And let's say that the input date is one year later than 7/7/2021 [not sure exactly due to leap years [in other cases] etc, but] let's say that's 7/9/2022
since it's more than a year, I want to "loop back" to the original date, and add the remainder [if that makes sense], so in this case the result would be
7/9/2021
basically, it finds the remainder after taking into account the extra year, if that makes sense
another example, say my base date is the same, and my input is
7/10/2026 [without leap years for now]
then the output should give
7/10/2021
because it's more than a year etc...
obviously in these cases I can simply subtract the years and keep the dates, but I don't know how to calculate it for different months and different days, while taking into account DLS and leap years etc...
so far I was able to come up with this function for calculating the difference of days between two dates with timezone offsets, based on other answers from here on similar questions, but I don't know how to apply it to the above case [obviously I can simply check the amount of times of differences for, say, 365 days between each one, but that wouldn't take nito account leap years...]
var yoymaweemBayn = (w, e) => {
var d1 = new Date(w)
var d2 = new Date(e)
var day2 = (d2 - d1) / 1000 / 60 / 60 / 24
var ac = day2 - (d2.getTimezoneOffset() - d1.getTimezoneOffset()) / (60 * 24)
return ac
}
k.onclick = () => {
ok.innerHTML = yoymaweemBayn(
d2.value,
d3.value
)
}
B"H
<br>
<input id=d2 value="7/7/2021">
<input id=d3 value="4/6/2023"><br>
<button id="k">Calculate?!</button>
<div id=ok></div>
To clarify:
How do I subtract a certain number of years from the latter date, until the date "loops back around" to be within the base year, while taking into account leap years [such that its not always 365 days apart]?

Javascript Subtract/Add 1 month from date [duplicate]

This question already has answers here:
JavaScript function to add X months to a date
(24 answers)
Adding months to a Date in JavaScript [duplicate]
(2 answers)
Closed 2 years ago.
I'm trying to find a method that reliably subtracts 1 month from a javascript date object.
I have this code:
var shippedDate = new Date('12/31/2020');
var tempDate = new Date(shippedDate.setMonth(shippedDate.getMonth() - 1)); //subtract 1 month
alert(tempDate);
The value in tempDate after this code runs is 12/1/2020 when it should actually be 11/30/2020.
I checked my math with this online date calculator: https://www.timeanddate.com/date/dateadded.html?m1=12&d1=31&y1=2020&type=sub&ay=&am=1&aw=&ad=&rec=
Thanks.
December has 31 days so when you subtract 1 month, you get 31 November which doesn't exist, so it rolls over to 1 December.
You can test the date (day in month) to see if it's the same, and if not, set the date to 0 so it goes to the last day of the previous month.
Also, setDate modifies the Date object so no need to create a new one:
function subtractMonth(date, months) {
let d = date.getDate();
date.setMonth(date.getMonth() - months);
if (date.getDate() != d) {
date.setDate(0);
}
return date;
}
let d = new Date(2020, 11, 31); // 31 Dec 2020
console.log(subtractMonth(d, 1).toString()); // 30 Nov 2020
This has side effects so that sequentially subtracting 2 months may give a different result to subtracting 2 months in one go.
Also in regard to new Date('12/31/2020'), see see Why does Date.parse give incorrect results?
PS
I answered this before I remembered that there were plenty of questions about adding months that also cover subtracting. So I marked this question as a duplicate and rather than delete this answer, left it for posterity.
If you wish to vote for an answer, please go to one of the duplicates and vote for an answer there. :-)
On my own experience, I may qualify all around Date calculation in javascript as completely unbearable pain.
Avoid as possible own crafted function to any Date manipulation. There are too many traits to lose mind at all. Timezones, wrong clocks, timezone on your own host vs. timezone on server, unexpected toString conversion according to local host timezone/clock.
If you rally need to make some dates calculation use battle tested library, like date-fns, moment.js, etc.
By the way your example almost correct, you just have chosen not suitable time to try to test it. The only one that I see problematic it's using setMonth that mutate original shippedDate.

calculate back date using jquery

I have a requirement where I want to calculate back date.
For example if I am giving 5 months then it should return the 5 month back date and if i give 5 years then it should return the 5 years back date keeping leap year in mind.i tried to implement some of the examples which I found in web but non of them are giving me the exact result.
Can someone please help me to achieve so.
You can use setMonth setDate and setFullYear on a Date object easily.
The thing is, if you're adding a whole year, and it's a leap year, you'll still end on the same date (month and day) of the last year. which i think it's the correct behaviour.
now = new Date() // 2016-11-24T13:21:55.841Z
now.setFullYear(now.getFullYear() -1) // 2015-11-24T13:21:55.841Z
If you want to subtract a standard-sized-year, I think you should instead remove 365 days from the current day. Which will take you to a slightly different date.
now = new Date() // 2016-11-24T13:21:55.841Z
now.setDate(now.getDate() - 365) // 2015-11-25T13:21:55.841Z

Trying to create Javascript form to calculate end times

I'm trying to create a form that users can fill out to calculate a projected project end time (think time punches).
For example:
You're projected to spend 8 hours on a project, you start that project at 8 am and you'll have 1 hour of downtime that doesn't count towards project time in the middle.
8am start + 8 hour projection + 1 hour delay = Projected End Time of 5pm.
I'm a novice at best with Javascript though I can typically find a similar script online and cannibalize then rewrite it for my needs. In this instance though, I feel like I'm out of my depth by a long shot, as the closest I could get was a script that adds 2 boxes together but doesn't account for time (so 8+9=17, not 5 like I needed).
Any help would be greatly appreciated! If need be I can paste the script I was trying to edit, though I'm pretty sure it's useless. I tried to Google how to write this basic thing I want to use but after 3 hours and no progress I decided to cave in and ask.
Thanks for taking the time to read!
I am not sure about your overall calculation, but if you want to account for AM/PM time in your result you simply subtract 12 hours from the result. 17-12 = 5 PM.
Here is a rough sample...
var time = 17;
AmPmTime(17); // 5 PM
function AmPmTime(t) {
var result = t + " AM";
if (t > 12) {
result = (t-12) + " PM";
} else if (t == 0)
result = "12 AM";
}
return result;
}

JavaScript Addition Date Functions

I don't really know too much about core JavaScript, just a dot of jQuery. But I know jQuery is not necessary for what I need here:
I want to use the getdate function to find out the server's day of the week. Then add a bunch of clauses like:
if its Monday add 6 to the date and return the date in MM/DD/YYYY form.
if its Tuesday add 5 to the date and return the date in MM/DD/YYYY form.
if its Wednesday add 4 to the date and return the date in MM/DD/YYYY form.
and so on until Sunday when it will add 0.
So lets say todays Monday, it will return 1/8/2012
And in real dates today's Sunday so it will really return 1/1/2012
Then I just want to call a document.write function to write the MM/DD/YYYY it returns into my HTML document.
Can anybody help me? I can clarify if you need me to...
getDay() returns the day of the week, Sunday = 0, Monday = 1, etc, etc.
So say today was Monday getDay() would return 1, which means daysToAdd would be 5.
Once we know how many days we want to add we can create a new date and add those days. We do this by getting today in milliseconds and then adding the number of days (daysToAdd) in milliseconds.
We convert days to milliseconds by multiplying by 24*60*60*1000 which is the number of milliseconds in a day.
I add 1 to the month because JavaScript returns 0 based month, but for display purposes we want to format it so that January for example is 1 not zero.
function getEndOfWeek() {
var today = new Date();
var weekDay = today.getDay();
// if you want the week to start on Monday instead of Sunday uncomment the code below
//weekDay -= 1;
//if(weekDay < 0) {
// weekDay += 7;
//}
var daysToAdd = 6 - weekDay;
var newDate = new Date(today.getTime() + daysToAdd *24*60*60*1000);
var month = newDate.getMonth() + 1;
var day = newDate.getDate();
var year = newDate.getFullYear();
var formatedDate = month + "/" + day + "/" + year;
return formatedDate;
}
You could implement in your code like so, JavaScript:
$(function() {
$("#TheDate").html(getEndOfWeek());
});
Your HTML would be something like this:
The week ends on <span id="TheDate"></span>.
You can find the jsFiddle here: jsFiddle
If you want to adjust the weekday so that you consider Monday the start of the week instead of Sunday you can do the following after you get the weekDay:
weekDay -= 1;
if(weekDay < 0) {
weekDay += 7;
}
var day = 1000*60*60*24
, nextSunday = new Date(+new Date() + day*(7-((0|(+new Date()/day)%7-3)||7)));
alert(
(101+nextSunday.getMonth()).toString().substr(1) + '/' +
(100+nextSunday.getDate()).toString().substr(1) + '/' +
nextSunday.getFullYear()
)
As fas as adding dates in JavaScipt my "DateExtensions" library does this well enough, I think. You can get it here:
http://depressedpress.com/javascript-extensions/dp_dateextensions/
Once refenced you can call "add()" as a method for any valid date and pass it any of many date parts (second, minutes, days, hours, etc). So assuming "curDate" is a valid JavaScript date object you can add 5 days like this:
newDate = curDate.add(5, "days");
Using a negative value will subtract:
newDate = curDate.add(-5, "days");
Once you get the date you want you can the use the library's dateFormat() method to display it like so:
curDate.dateFormat("MM/DD/YYYY");
There's full documentation at the link.
Integer Values for Day of Week
As for getting the integer value you want, it's actually easier that it looks (and you don't need an "if" just some math). The getDay() method of date returns the day of week with Sunday as "0" and Saturday as "6". So the week, from Sunday, would normally be:
0,1,2,3,4,5,6
First, you want to reverse that scale. That's easily done via subtraction by taking 7 (to total number of members of the set) from the value. This gives you this scale:
-7,-6,-5,-4,-3,-2,-1
We're getting closer. You want the first value to be zero as well. The simplest way (I think) to do this is to get the modulus (remainder) of the value by the total number of members. All this basically does is make "-7" a zero and leave the rest alone giving us this:
0,-6,-5,-4,-3,-2,-1
Almost done. Finally you don't want negative numbers so you need to use the Math.abs() method to eliminate the sign (get the absolute value) leaving us with our desired result:
0,6,5,4,3,2,1
For all the talk the acutual code is pretty compact:
Math.abs((cnt-7)%7)
Wrapping this into the original example gives us:
newDate = curDate.add(Math.abs((curDate.getDay()-7)%7), "days");
Server Vs Client
However take nnnnnn's comment to heart: in JavaScript the getDate() function gets the current date/time of the machine that it's running on - in the case of a web page that's the client, not the server.
If you actually meant the client time them you're set and done. If you really need the server time however that's annoying-to-impossible. If you own the server then it's actually not to hard to set up a rule that includes the current server in a cookie withing each fufilled request (you could then use my cookie library, also at the site above, to access the information!)
It's messier but depending on the server you might also be able to create an old-school server-side include that adds a bit of JavaScript to each page (preferably as a marked replace in the header) that hard-codes the date as a global variable.
You might also create a web service that returns the current server time but the client-overhead for that is insane compared to the data being delivered.
If the server's NOT yours (and you can't get the owner to provide the above) then the only real potential option is to do a straight http call and examine the HTTP "Date" header. Again however the overhead on this is immense compared to the return but it's really the only way. Any system like this would have to be very flexible however as any particular server might not return the date header or might not return it correctly.
Even if it does work understand that you might still not be getting the "server" time - or at least not the server you want. In a tiered architecture, for example an application server might render then page and hand it to a web server to return - you'd be getting the web server time, not the app server. Any number of appliances might also rewrite the headers (for example it's common to use dedicated SSL appliances to offload all the encryption work - these often re-write the headers themselves).
Sorry to get overly technical - JavaScript is definately one area where there's unfortunately rarely a "simple question". ;^)
Good Luck!

Categories

Resources