/* @param {Date} [date] - Date object to be converted
** @returns {number} - whole days since 1 January 0 to d
**
** epoch date must set year separately as in many implementations
** new Date(0,0,1) returns 1 Jan 1900, not 1 Jan 0000
*/
function dateToGregorianDays(date) {
// Create a Date object for 0000-Jan-01 (months are zero based)
var epoch = new Date(0,0,1);
// Set the epoch to year 0 as in the above some browsers will
// create a date for 1900 not 0, even though 0 was passed in
epoch.setFullYear(0);
// Copy the passed in Date so it's not modified by next step
var e = new Date(+date);
// Set the time part of the copied date to 00:00:00, which
// helps to calculate whole days
e.setHours(0,0,0,0);
// In mathematic operations, dates are converted to their time value
// which is milliseconds, so get the difference in milliseconds between
// the two dates and divide by milliseconds per day. Round to remove
// fractional parts caused occasionally over daylight saving boundaries
// to get whole day count between the two dates and return it
return Math.round((e - epoch)/8.64e7);
}
/* @param {number} [days] - Gregorian day number
** @returns {Date} - Based on whole days since 1 January 0
**
** 0 -> 1 Jan 0000
** 719528 -> 1 Jan 1970
*/
function gregorianDaysToDate(days) {
// Create a date for 0000-Jan-01
var epoch = new Date(0,0,1);
epoch.setFullYear(0);
// Add the number of days to the date
// epoch.getDate() could be replaced by 1 since that's what
// the date was set to just above
epoch.setDate(epoch.getDate() + days);
// Return the date
return epoch;
}
/* Simple function to return a date string as dd-MMM-yyyy
** @param {Date} [date] - Date to format
** @returns {string} - formatted string for date
*/
function formatDateDMY(date) {
// Month names
var months = ['Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec'];
// Add leading zero to single digit days
// Get the month name for the month (zero indexed, 0 is Jan)
// Add leading zeros to years with less than 4 digits
// Use '-' as separator
return ('0' + date.getDate()).slice(-2) + '-' +
months[date.getMonth()] + '-' +
('000' + date.getFullYear()).slice(-4);
}
// Create an alias for the above function to save typing
var fd = formatDateDMY;
// Gregorian days for 01-Jan-1970
document.write(dateToGregorianDays(new Date(1970,0,1)) + '<br>'); // 719528
// Gregorian calendar date for 719528 formatted as dd-MMM-yyyy
document.write(fd(gregorianDaysToDate(719528)) + '<br>') // 01 Jan 1970
// Gregorian calendar date for 0 formatted as dd-MMM-yyyy
document.write(fd(gregorianDaysToDate(0)) + '<br>'); // 01 Jan 0000
// Gregorian calendar date for 736202 formatted as dd-MMM-yyyy
document.write(fd(gregorianDaysToDate(736202)) + '<br>'); // 27 Aug 2015
// Gregorian days for 28-Aug-2015
document.write(dateToGregorianDays(new Date(2015,7,28))); // 736203