Get Years Months and days from days - javascript

I seem to not be getting it. I have number of days, say 762 which will be 2 years(730 days each 365 days), 1 month(762-730), and 2 days(assuming every month has constant 30 days)
I need to do that on JS. this what I came up with:
days = 762;
ymd = {
d: days % 30,
m: Math.floor((days - (days % 30)) / 30),
y: ((days - (days % 365)) / 365),
}
if (ymd.m > 12){
ymd.y += Math.floor(ymd.m / 12);
ymd.m = ymd.m % 12;
}
console.log(ymd);
Well it's not working.

Using your assumptions on year/month lengths;
function dToYMD(i) {
var y, m ,d;
y = (i / 365) | 0;
i = i - y * 365;
m = (i / 30) | 0;
i = i - m * 30;
d = i | 0;
return [y, m, d];
}
dToYMD(762); // [2 /* years */, 1 /* month */, 2 /* days */]
I thought there was something built in. i meant using Date obj
This would not use your assumptions for lengths, but you could set a date based upon the unix epoch, and then minus 1970 from the year.
function dToYMD(i) {
var d = new Date(i * 864e5);
return [d.getUTCFullYear() - 1970, d.getUTCMonth(), d.getUTCDate() - 1];
}
dToYMD(762); // [2 /* years */, 1 /* month */, 1 /* days */]
Note this time, the number of days is different because January has 31 days.

Modulus (%) returns the remainder after a division. You should be using regular division then flooring the value.
Like so:
var numOfDays = 762;
var years = Math.floor(numOfDays / 365),
months = Math.floor((numOfDays-(years*365)) / 30),
days = ((numOfDays-(years*365))-months*30);
Here is the working code

Related

How to take the differences between two dates, depending on the date of birth [duplicate]

This question already has answers here:
How can I calculate the number of years between two dates?
(22 answers)
Closed 2 years ago.
My code:
function test(val) {
year = parseInt(val.slice(0,2)); // get year
month = parseInt(val.slice(2,4)); // get month
date = val.slice(4,6); // get date
if (month > 40) { // For people born after 2000, 40 is added to the month. (it is specific for my case)
year += 2000;
month -= 40;
} else {
year += 1900;
}
date = new Date(year, month-1, date, 0, 0);
date_now = new Date();
var diff =(date_now.getTime() - date.getTime()) / 1000;
diff /= (60 * 60 * 24);
console.log(Math.abs(Math.round(diff/365.25)));
}
Example 1:
If I was born in
1993-year;
04-month(april);
26-date
I will pass 930426 as value to test function and the result would be 27 which is correct
But in Example 2:
If I was born in:
1993-year;
09-month(september);
14-date;
I will pass 930914 as value to test function and result would be 27, but it's not correct because my birthday is still not come and i'm still 26 years old.
How can I fix this ?
Because 26.9 is still regarded as age of 26, so you should use .floor instead
function test(val) {
year = +val.slice(0, 2) // get year
month = val.slice(2, 4) // get month
date = val.slice(4, 6) // get date
date = new Date(year, month - 1, date, 0, 0)
date_now = new Date()
var diff = (date_now.getTime() - date.getTime()) / 1000
diff /= 60 * 60 * 24
console.log(diff / 365.25)
console.log("Age", Math.floor(diff / 365.25))
}
test("930426")
test("930914")

Converting UTC to Decimal time

Background
I want to create a new date/time system based on an old French version with some modifications.
This involves converting UTC date/times to new quantities:
12 months => 10 months
52 weeks => 36.5 weeks
28/31 days per month => 36/37 days per month
24 hours => 20 hours
60 minutes => 100 minutes
60 seconds => 100 seconds
I've coded a clock in JavaScript as proof of concept, but unsure as to whether I have correctly calculated everything, additionally whether it's the best approach:
Code
1) getDecimalDate() calculates the day of the year, then works out which month it exists within a new calendar of 36 or 37 days per month. Then calculates the new date of the month.
function getDecimalDate(date) {
var oldDay = 1000 * 60 * 60 * 24,
startYear = new Date(Date.UTC(date.getUTCFullYear(), 0, 0)),
day = Math.floor((date - startYear) / oldDay),
num = 0,
month = 1;
if (day > 36) { num += 36; month = 2; }
if (day > 73) { num += 37; month = 3; }
if (day > 109) { num += 36; month = 4; }
if (day > 146) { num += 37; month = 5; }
if (day > 182) { num += 36; month = 6; }
if (day > 219) { num += 37; month = 7; }
if (day > 255) { num += 36; month = 8; }
if (day > 292) { num += 37; month = 9; }
if (day > 328) { num += 36; month = 10; }
return { day: day - num, month: month, year: date.getUTCFullYear(), num: num };
}
2) getDecimalTime() calculates the number of milliseconds since midnight, then changes it from old milliseconds per day to new totals, then calculates hours, mins etc
function getDecimalTime(date) {
var oldDay = 1000 * 60 * 60 * 24,
newDay = 1000 * 100 * 100 * 20,
startDay = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())),
delta = ((date - startDay) / oldDay) * newDay;
var hours = Math.floor(delta / 10000000) % 20;
delta -= hours * 10000000;
var minutes = Math.floor(delta / 100000) % 100;
delta -= minutes * 100000;
var seconds = Math.floor(delta / 1000) % 100;
delta -= seconds * 1000;
var milliseconds = Math.floor(delta) % 1000;
return { milliseconds: milliseconds, seconds: seconds, minutes: minutes, hours: hours };
}
You can see a working version here:
https://jsfiddle.net/kmturley/7mrwc3x3/9/
Results
Bear in mind i've made up day/month names using Latin (Nov = 9, die = day, dec = 10, mense = month)
String - Saturday December 3 => Novdie Decmense 10
Date - 03-12-2016 => 10-10-2016
Time - 22:47:52 => 18:98:43
Questions
Is the math correct?
Are there any issues with timezones? i've
tried converting all Date objects to UTC but JavaScript can be
tricky
Can I improve the code? the month selection seems like it
could be improved but I couldn't figure out a better way to count 36
and 37 day months. if (num % 36.5 === 1) wouldn't work?
Thanks!
Update - 7th December 2016 - new versions based on solution:
https://jsfiddle.net/kmturley/7mrwc3x3/10/
https://github.com/kmturley/decimal-time
Is the math correct?
You didn't say which months have 35 days and which have 36 so we have to accept that the if statements are correct. You don't show how date is created so it may or may not be OK. And you don't say what happens for leap years, this system seems to only have 365 days per year.
The following:
24 hours => 20 hours
60 minutes => 100 minutes
60 seconds => 100 seconds
doesn't seem correct. Do you actually mean:
1 day = 20 decimal hours
1 decimal hour = 100 decimal minutes
1 decimal minute = 100 decimal seconds
1 decimal second = 1000 decimal milliseconds
Your strategy of getting the time in ms and scaling to decimal ms seems fine, I'll just make the following comments.
In getDecimalTime it is simpler to calculate startDay by first copying date then setting its UTC hours to zero:
startDay = new Date(+date);
startDate.setUTCHours(0,0,0,0);
Then scale:
var diffMilliseconds = date - startDate;
var decimalMilliseconds = diffMilliseconds / 8.64e7 * 2.0e8;
so 1 standard millisecond = 2.314814814814815 decimal milliseconds
In the date function, the expression:
new Date(date.getUTCFullYear(), 0, 0)
will create a date for 31 December the previous year (i.e. date of 0), if you're after 1 January then it should be:
new Date(date.getUTCFullYear(), 0, 1);
So likely you're one day out. Otherwise, the code seems to be correct. For me, the get decimal time function would be simpler as:
function getDecimalTime(date) {
// Pad numbers < 10
function z(n){return (n<10?'0':'')+n;}
// Copy date so don't modify original
var dayStart = new Date(+date);
var diffMs = date - dayStart.setUTCHours(0,0,0,0);
// Scale to decimal milliseconds
var decMs = Math.round(diffMs / 8.64e7 * 2.0e8);
// Get decimal hours, etc.
var decHr = decMs / 1.0e7 | 0;
var decMin = decMs % 1.0e7 / 1.0e5 | 0;
var decSec = decMs % 1.0e5 / 1.0e3 | 0;
decMs = decMs % 1.0e3;
return z(decHr) + ':' + z(decMin) + ':' + z(decSec) + '.' + ('0' + z(decMs)).slice(-3);
}
// Helper to format the time part of date
// as UTC hh:mm:ss.sss
function formatUTCTime(date) {
function z(n){return (n<10?'0':'')+n;}
return z(date.getUTCHours()) + ':' +
z(date.getUTCMinutes()) + ':' +
z(date.getUTCSeconds()) + '.' +
('00' + date.getUTCMilliseconds()).slice(-3);
}
// Test 00:00:00.003 => 00:00:00.007
// i.e. 3ms * 2.31decms => 6.93decms
var d = new Date(Date.UTC(2016,0,1,0,0,0,3));
console.log(getDecimalTime(d));
// Test 12:00:00.000 => 10:00:00.000
// i.e. noon to decimal noon
var d = new Date(Date.UTC(2016,0,1,12,0,0,0));
console.log(getDecimalTime(d));
// Test current time
d = new Date();
console.log(formatUTCTime(d));
console.log(getDecimalTime(d));

How to count month and days between two dates through JavaScript?

We have using below code.
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var firstDate = new Date(2008,01,12);
var secondDate = new Date(2008,01,22);
var diffDays = Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay));
But we can't find both month and days between them.
I want like suppose start date is 27-sep-2014 and end date is 1-nov-2014. Result will be 1 month and 5 days.
There multiple ways to count months and days. Without further restrictions all correct of them are correct even though the results might differ.
For example from September 27 to November 1 could be either
1 month and 5 days or
4 days and 1 month.
This is one possible solution.
// swap dates if difference would be negative
if (firstDate.getTime() > secondDate.getTime()) {
var tmp = firstDate;
firstDate = secondDate;
secondDate = tmp;
}
var years = secondDate.getFullYear() - firstDate.getFullYear();
var months = secondDate.getMonth() - firstDate.getMonth();
var days = secondDate.getDate() - firstDate.getDate();
// prevent negative amount of days by breaking up months
for (var i = 0; days < 0; ++i) {
// while the day difference is negative
// we break up months into days, starting with the first
months -= 1;
days += new Date(
firstDate.getFullYear(),
firstDate.getMonth() + 1 + i,
0, 0, 0, 0, 0
).getDate();
}
// prevent negative amount of months by breaking up years
if (months < 0) {
years += Math.floor(months / 12);
months = (months % 12 + 12) % 12;
}
// print the result
console.log([
{amount: days, unit: 'day'},
{amount: months, unit: 'month'},
{amount: years, unit: 'year'},
].filter(value => value.amount).map(value =>
value.amount === 1 ?
`${value.amount} ${value.unit}` :
`${value.amount} ${value.unit}s`
).reduce((result, part, index, parts) =>
index > 0 ? index === parts.length - 1 ?
`${result} and ${part}` :
`${result}, ${part}` :
`${part}`,
`0 days`
));
Examples:
02/12 to 02/22: 10 days
09/27 to 11/01: 4 days and 1 month // instead of 1 month and 5 days
12/31 to 03/01: 1 day and 2 months // instead of 1 month and 29 days
05/31 to 06/30: 30 days
01/31 to 03/30: 30 days and 1 month // instead of 1 month and 27 days
10/27/2010 to 08/26/2014: 30 days, 9 months and 3 years
Try this
var oneDay = 24*60*60*1000;
var firstDate = new Date(2007,01,12);
var secondDate = new Date(2008,01,22);
var diffDays = Math.abs((firstDate.getTime() - secondDate.getTime()));
var result = '',
years, months, days;
if((years = diffDays / (365 * oneDay)) > 1){
result += Math.floor(years) + ' Year(s)';
diffDays %= (365 * oneDay);
}
if((months = diffDays / (30 * oneDay)) > 1){
result += Math.floor(months) + ' Month(s)';
diffDays %= (30 * oneDay);
}
result += (diffDays / oneDay) + ' Days(s)';
alert(result);

Calculate number of specific weekdays between dates

I'm trying to calculate the number of Mondays, Wednesdays, and Fridays between 2 dates in Tasker, thus I need a math formula, possibly utilizing the date in seconds form, i.e. unix time, or a javascript code. I've tried Googling and racking my brain for any way to even start this and I'm lost so I haven't tried anything yet. The only thing I could think of was getting the total number of days and dividing by 7, but that clearly does not help me very much, especially if one or both of the days is midweek. Can anyone point me in a better direction?
How to count specific days of the week between two dates in O(1):
// days is an array of weekdays: 0 is Sunday, ..., 6 is Saturday
function countCertainDays( days, d0, d1 ) {
var ndays = 1 + Math.round((d1-d0)/(24*3600*1000));
var sum = function(a,b) {
return a + Math.floor( ( ndays + (d0.getDay()+6-b) % 7 ) / 7 ); };
return days.reduce(sum,0);
}
Example on counting Mondays, Wednesdays, and Fridays [1,3,5] between two dates:
countCertainDays([1,3,5],new Date(2014,8,1),new Date(2014,8,1)) // 1
countCertainDays([1,3,5],new Date(2014,8,1),new Date(2014,8,2)) // 1
countCertainDays([1,3,5],new Date(2014,8,1),new Date(2014,8,3)) // 2
countCertainDays([1,3,5],new Date(2014,8,1),new Date(2014,8,4)) // 2
countCertainDays([1,3,5],new Date(2014,8,1),new Date(2014,8,5)) // 3
countCertainDays([1,3,5],new Date(2014,8,1),new Date(2014,8,6)) // 3
countCertainDays([1,3,5],new Date(2014,8,1),new Date(2014,8,7)) // 3
Note that the month parameter to Date is 0-based, so 1 Sept 2014 is Date(2014,8,1).
Assume total number of days is n. Then number of any day of a week is initially n / 7. Now take n = n % 7. Depending on the value of current n you can easily calculate the final count of days.
As example:
Assume your first day is Friday and total number of days is 100. So, n = 100. There are minimum 100/7 or 14 of each weekday is in the interval. 100 % 7 = 2. So final count is,
Friday -> 14+1 = 15
Saturday -> 14+1 = 15
Sunday -> 14
Monday -> 14
Tuesday -> 14
Wednesday -> 14
Thursday -> 14
const start_date = "2022-06-02";// standard date format YYYY-MM-DD
const end_date = "2022-06-18";
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; // standard week days
const getNumberOfWeekDays = (day) => {
// this will return number of week days between given start and end date
const startDay = moment(start_date).format("ddd");
const index = days.indexOf(startDay); // index of the start day
const totalDays = moment(end_date).diff(moment(start_date), "days"); // 16
const numberOfDays = Math.round(totalDays / 7); // 16/7 = 2; number of sessions by week
const remainingDays = totalDays % 7; // 16 % 7 = 2
const newArray = days.rotate(index).slice(0, remainingDays); // ["Thu","Fri"]
if (newArray.includes(day)) {
return numberOfDays + 1;
}
return numberOfDays;
};
getNumberOfWeekDays('Thu');// Thursday between given start and end date is 3
getNumberOfWeekDays('Mon');// Wednesday between given start and end date is 2
How to count the number of friday between two date in JavaScript
function myfunction() {
var frist = document.getElementById("dt_VacStart").value
var answer = 0;
var second = document.getElementById("dt_VacEnd").value;
if (frist != null && second != null) {
var startDate = new Date(frist);
var endDate = new Date(second);
var totalfriday = 0;
for (var i = startDate; i <= endDate;) {
if (i.getDay() ==5) {
totalfriday++;
}
i.setTime(i.getTime() + 1000 * 60 * 60 * 24);
}
document.getElementById('<%=Friday.ClientID%>').value = totalfriday;
} else {
totalfriday = 0;
document.getElementById('<%=Friday.ClientID%>').value = totalfriday;
}
}

JavaScript - Calc days between 2 dates (Including end date)?

Ive been searching quite a lot find an answer for this , and couldn't find one.
I have 2 dates ,
I want to calc days between them
but I Also want the end day to be counted.
Example :
me and my wife go to hotel from [20 jan] till [26 Jan] , so its 7 days total.
the only code which I find working is :
Math.round((b - a) / ( 1000 * 60 * 60 * 24)) +1
where :
var a= new Date (y,0,20);
var b= new Date (y,0,26);
I also made a nested loop to test all months within a 150 years , and it works Ok.
var y = 1970;
var m = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
for(var i = 0; i < 150; i++)
{
for(var j = 0; j < 12; j++)
{
var a = new Date(y + i, m[j], 20);
var b = new Date(y + i, m[j], 26);
var days = Math.round((b - a) / (1000 * 60 * 60 * 24)) + 1;
if(days != 7) console.log(i + y); //tell me if result is unexpected.
}
}
console.log('-FINISH-' + new Date().getTime())
So where is the problem ?
I can't figure how the math function like round can do the trick here.
We are talking about milliseconds here and I can't see where the round behavior gives me the right result.
(p.s. - forget about ceil and floor , they do not help here and have inconsistent results) , I have also tried to add one day to the b value , and use ceil || floor but with no success
here is the code
The reason your rounding is working is because you're only working with full days. myDate.getTime() will yield the number of milliseconds since 1970-01-01. If you're always assigning your dates as new Date(y,m,d) you will always have the time part set to 00:00:00.000, and hence the date comparison will always yield a multiple of 86400000, which is your divisor. The rounding here is for the most part superfluous.
If you're creating all of your dates as specified above, the only time rounding does come into play, is when the daylight savings offset at date b is different from that at date a. round will take care of these discrepancies, as they're rarely more than an hour.
From your script, October 1970 is problematic (in CEST) because Oct 20th is in daylight savings, and Oct 26th isn't.
var a = new Date(1970, 9, 20);
var b = new Date(1970, 9, 26);
(b - a) / (1000 * 60 * 60 * 24) // 6.041666666666667
You could work around this by rounding, or by using UTC dates
var a = new Date(Date.UTC(1970, 9, 20));
var b = new Date(Date.UTC(1970, 9, 26));
(b - a) / (1000 * 60 * 60 * 24) // 6
Here is your answer:
http://www.direct.gov.uk/en/Nl1/Newsroom/DG_185398
Basically, March 25 has 23 hours in it instead of 24. And 28'th October has 25 hours in it. That's why rounding works well while floor/ceil does not.
Also, as you can see, DST date changes with each year (you can see that in same article), that's why only once every 5-10 years the floor/cail test fails. On other years DST is applied to different date, therefore test result appears to be normal.
I found the reason! :) (e.g. year 2035)
Date {Sun Mar 25 2035 00:00:00 GMT+0100 (CET)}
Date {Mon Mar 26 2035 00:00:00 GMT+0200 (CEST)}
Look at the GMT Times one is GMT+0100 (CET) and one is GMT+0200 (CEST)
To get always the result without round you have to use UTC:
var a = Date.UTC(y + i, m[j], 25);
var b = Date.UTC(y + i, m[j], 26);
var days = (b - a) / (1000 * 60 * 60 * 24);
I modified your code slightly to find this bug:
var y = 1970;
var m = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
for(var i = 0; i < 150; i++)
{
for(var j = 0; j < 12; j++)
{
var a = new Date(y + i, m[j], 25);
var b = new Date(y + i, m[j], 26);
var days = (b - a);
if(days != 86400000) console.log(i + y, days); //tell me if result is unexpected.
}
}
1983 90000000
1984 82800000
1988 90000000
...
This was already discussed here:
http://www.webdeveloper.com/forum/archive/index.php/t-5195.html
As already answered in a previous post:
var days = Math.floor(enddate.getTime()-startdate.getTime())/(24*60*60*1000);

Categories