Skip to content

Instantly share code, notes, and snippets.

@Fordi
Forked from anonymous/dates.js
Last active February 20, 2018 05:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fordi/5a03d4c15dbe2d62ff8a7f8f9a40972f to your computer and use it in GitHub Desktop.
Save Fordi/5a03d4c15dbe2d62ff8a7f8f9a40972f to your computer and use it in GitHub Desktop.
Calculating the average of our Presidents' birthdays.
const CURRENT_YEAR = new Date(new Date().getFullYear(), 0, 0, 0, 0, 0, 0);
const DAY = 1000 * 60 * 60 * 24;
const dates = ['Feb 22', 'Oct 30', 'Apr 13', 'Mar 16', 'Apr 28', 'July 11', 'Mar 15', 'Dec 5', 'Feb 9', 'Mar 29', 'Nov 2', 'Nov 24', 'Jan 7', 'Nov 23', 'Apr 23', 'Feb 12', 'Dec 29', 'Apr 27', 'Oct 4', 'Nov 19', 'Oct 5', 'Mar 18', 'Aug 20', 'Jan 29', 'Oct 27', 'Sep 15', 'Dec 28', 'Nov 2', 'July 4', 'Aug 10', 'Jan 30', 'May 8', 'Oct 14', 'May 29', 'Aug 27', 'Jan 9', 'July 14', 'Oct 1', 'Feb 6', 'June 12', 'Aug 19', 'July 6', 'Aug 4', 'June 14'];
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const TAU = Math.PI * 2;
const getDayNum = d => {
let diff = +new Date(d) - CURRENT_YEAR;
return Math.floor(diff / DAY);
};
const polarToCartesian = (theta, phi) => {
return [ Math.cos(theta) * phi, Math.sin(theta) * phi ];
};
const cartesianToPolar = (x, y) => {
return [ Math.atan2(y, x), Math.sqrt(x * x + y * y) ];
};
const dayOfYearToAngle = day => {
return day * TAU / 365;
};
const angleToDayOfYear = theta => {
return theta * 365 / TAU;
};
const totalDayNums = dates.map(getDayNum).reduce((acc, day) => {
// Make the day into an angle on the year-circle
let theta = dayOfYearToAngle(day);
// Convert polar coords to cartesian, considering the year-circle to be a unit circle
let pos = polarToCartesian(theta, 1);
// Add the coordinates to the sum
acc[0] += pos[0];
acc[1] += pos[1];
return acc;
}, [0, 0]);
// Don't actually need this part, as it'll only change rho, which we later ignore
// const avg = totalDayNums.map(part => part / dates.length);
// Convert the (x, y) back to (theta, rho), and just grab theta.
let theta = cartesianToPolar(totalDayNums[0], totalDayNums[1])[0]; // Only need the angle
// atan2 can return negative angles; we only want positive angles here.
if (theta < 0) {
theta += TAU;
}
// Convert back to the year-circle
const day = angleToDayOfYear(theta);
// Build it into a date
const p_day = new Date(+CURRENT_YEAR + (day * DAY));
// Pretty-print it.
console.log(`${months[p_day.getMonth()]} ${p_day.getDate()}`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment