/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml */ dojo.provide("dojo.date.common"); /* Supplementary Date Functions *******************************/ dojo.date.setDayOfYear = function(/*Date*/dateObject, /*Number*/dayOfYear){ // summary: sets dateObject according to day of the year (1..366) dateObject.setMonth(0); dateObject.setDate(dayOfYear); return dateObject; // Date } dojo.date.getDayOfYear = function(/*Date*/dateObject){ // summary: gets the day of the year as represented by dateObject var fullYear = dateObject.getFullYear(); var lastDayOfPrevYear = new Date(fullYear-1, 11, 31); return Math.floor((dateObject.getTime() - lastDayOfPrevYear.getTime()) / 86400000); // Number } dojo.date.setWeekOfYear = function(/*Date*/dateObject, /*Number*/week, /*Number*/firstDay){ if(arguments.length == 1){ firstDay = 0; } // Sunday dojo.unimplemented("dojo.date.setWeekOfYear"); } dojo.date.getWeekOfYear = function(/*Date*/dateObject, /*Number*/firstDay){ if(arguments.length == 1){ firstDay = 0; } // Sunday // work out the first day of the year corresponding to the week var firstDayOfYear = new Date(dateObject.getFullYear(), 0, 1); var day = firstDayOfYear.getDay(); firstDayOfYear.setDate(firstDayOfYear.getDate() - day + firstDay - (day > firstDay ? 7 : 0)); return Math.floor((dateObject.getTime() - firstDayOfYear.getTime()) / 604800000); } dojo.date.setIsoWeekOfYear = function(/*Date*/dateObject, /*Number*/week, /*Number*/firstDay){ // summary: unimplemented if (arguments.length == 1) { firstDay = 1; } // Monday dojo.unimplemented("dojo.date.setIsoWeekOfYear"); } dojo.date.getIsoWeekOfYear = function(/*Date*/dateObject, /*Number*/firstDay) { // summary: unimplemented if (arguments.length == 1) { firstDay = 1; } // Monday dojo.unimplemented("dojo.date.getIsoWeekOfYear"); } /* Informational Functions **************************/ //DEPRECATED: These timezone arrays will be deprecated in 0.5 dojo.date.shortTimezones = ["IDLW", "BET", "HST", "MART", "AKST", "PST", "MST", "CST", "EST", "AST", "NFT", "BST", "FST", "AT", "GMT", "CET", "EET", "MSK", "IRT", "GST", "AFT", "AGTT", "IST", "NPT", "ALMT", "MMT", "JT", "AWST", "JST", "ACST", "AEST", "LHST", "VUT", "NFT", "NZT", "CHAST", "PHOT", "LINT"]; dojo.date.timezoneOffsets = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -240, -210, -180, -120, -60, 0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840]; /* dojo.date.timezones = ["International Date Line West", "Bering Standard Time", "Hawaiian Standard Time", "Marquesas Time", "Alaska Standard Time", "Pacific Standard Time (USA)", "Mountain Standard Time", "Central Standard Time (USA)", "Eastern Standard Time (USA)", "Atlantic Standard Time", "Newfoundland Time", "Brazil Standard Time", "Fernando de Noronha Standard Time (Brazil)", "Azores Time", "Greenwich Mean Time", "Central Europe Time", "Eastern Europe Time", "Moscow Time", "Iran Standard Time", "Gulf Standard Time", "Afghanistan Time", "Aqtobe Time", "Indian Standard Time", "Nepal Time", "Almaty Time", "Myanmar Time", "Java Time", "Australian Western Standard Time", "Japan Standard Time", "Australian Central Standard Time", "Lord Hove Standard Time (Australia)", "Vanuata Time", "Norfolk Time (Australia)", "New Zealand Standard Time", "Chatham Standard Time (New Zealand)", "Phoenix Islands Time (Kribati)", "Line Islands Time (Kribati)"]; */ dojo.date.getDaysInMonth = function(/*Date*/dateObject){ // summary: returns the number of days in the month used by dateObject var month = dateObject.getMonth(); var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (month == 1 && dojo.date.isLeapYear(dateObject)) { return 29; } // Number else { return days[month]; } // Number } dojo.date.isLeapYear = function(/*Date*/dateObject){ // summary: // Determines if the year of the dateObject is a leap year // // description: // Leap years are years with an additional day YYYY-02-29, where the year // number is a multiple of four with the following exception: If a year // is a multiple of 100, then it is only a leap year if it is also a // multiple of 400. For example, 1900 was not a leap year, but 2000 is one. var year = dateObject.getFullYear(); return (year%400 == 0) ? true : (year%100 == 0) ? false : (year%4 == 0) ? true : false; // Boolean } // FIXME: This is not localized dojo.date.getTimezoneName = function(/*Date*/dateObject){ // summary: // Get the user's time zone as provided by the browser // // dateObject: needed because the timezone may vary with time (daylight savings) // // description: // Try to get time zone info from toString or toLocaleString // method of the Date object -- UTC offset is not a time zone. // See http://www.twinsun.com/tz/tz-link.htm // Note: results may be inconsistent across browsers. var str = dateObject.toString(); // Start looking in toString var tz = ''; // The result -- return empty string if nothing found var match; // First look for something in parentheses -- fast lookup, no regex var pos = str.indexOf('('); if (pos > -1) { pos++; tz = str.substring(pos, str.indexOf(')')); } // If at first you don't succeed ... else{ // If IE knows about the TZ, it appears before the year // Capital letters or slash before a 4-digit year // at the end of string var pat = /([A-Z\/]+) \d{4}$/; if((match = str.match(pat))) { tz = match[1]; } // Some browsers (e.g. Safari) glue the TZ on the end // of toLocaleString instead of putting it in toString else{ str = dateObject.toLocaleString(); // Capital letters or slash -- end of string, // after space pat = / ([A-Z\/]+)$/; if((match = str.match(pat))) { tz = match[1]; } } } // Make sure it doesn't somehow end up return AM or PM return tz == 'AM' || tz == 'PM' ? '' : tz; //String } //FIXME: not localized dojo.date.getOrdinal = function(dateObject){ // summary: returns the appropriate suffix (English only) for the day of the month, e.g. 'st' for 1, 'nd' for 2, etc.) var date = dateObject.getDate(); if(date%100 != 11 && date%10 == 1){ return "st"; } // String else if(date%100 != 12 && date%10 == 2){ return "nd"; } // String else if(date%100 != 13 && date%10 == 3){ return "rd"; } // String else{ return "th"; } // String } /* compare and add ******************/ dojo.date.compareTypes={ // summary // bitmask for comparison operations. DATE:1, TIME:2 }; dojo.date.compare=function(/* Date */ dateA, /* Date */ dateB, /* dojo.date.compareTypes */ options){ // summary // Compare two date objects by date, time, or both. Returns 0 if equal, positive if a > b, else negative. var dA=dateA; var dB=dateB||new Date(); var now=new Date(); //FIXME: shorten this code with(dojo.date.compareTypes){ var opt=options||(DATE|TIME); var d1=new Date( (opt&DATE)?dA.getFullYear():now.getFullYear(), (opt&DATE)?dA.getMonth():now.getMonth(), (opt&DATE)?dA.getDate():now.getDate(), (opt&TIME)?dA.getHours():0, (opt&TIME)?dA.getMinutes():0, (opt&TIME)?dA.getSeconds():0 ); var d2=new Date( (opt&DATE)?dB.getFullYear():now.getFullYear(), (opt&DATE)?dB.getMonth():now.getMonth(), (opt&DATE)?dB.getDate():now.getDate(), (opt&TIME)?dB.getHours():0, (opt&TIME)?dB.getMinutes():0, (opt&TIME)?dB.getSeconds():0 ); } if(d1.valueOf()>d2.valueOf()){ return 1; // int } if(d1.valueOf() 0) ? 5 : -5; weeks = (incr > 0) ? ((incr-5)/5) : ((incr+5)/5); } else { days = mod; weeks = parseInt(incr/5); } // Get weekday value for orig date param strt = dt.getDay(); // Orig date is Sat / positive incrementer // Jump over Sun if (strt == 6 && incr > 0) { adj = 1; } // Orig date is Sun / negative incrementer // Jump back over Sat else if (strt == 0 && incr < 0) { adj = -1; } // Get weekday val for the new date trgt = (strt + days); // New date is on Sat or Sun if (trgt == 0 || trgt == 6) { adj = (incr > 0) ? 2 : -2; } // Increment by number of weeks plus leftover days plus // weekend adjustments sum.setDate(dat + (7*weeks) + days + adj); break; case HOUR: sum.setHours(sum.getHours()+incr); break; case MINUTE: sum.setMinutes(sum.getMinutes()+incr); break; case SECOND: sum.setSeconds(sum.getSeconds()+incr); break; case MILLISECOND: sum.setMilliseconds(sum.getMilliseconds()+incr); break; default: // Do nothing break; } } return sum; // Date }; dojo.date.diff = function(/* Date */ dtA, /* Date */ dtB, /* dojo.date.dateParts */ interv){ // summary: // Get the difference in a specific unit of time (e.g., number of months, weeks, // days, etc.) between two dates. // // dtA: // A Javascript Date object // // dtB: // A Javascript Date object // // interv: // A constant representing the interval, e.g. YEAR, MONTH, DAY. See dojo.date.dateParts. // Accept timestamp input if(typeof dtA == 'number'){dtA = new Date(dtA);} if(typeof dtB == 'number'){dtB = new Date(dtB);} var yeaDiff = dtB.getFullYear() - dtA.getFullYear(); var monDiff = (dtB.getMonth() - dtA.getMonth()) + (yeaDiff * 12); var msDiff = dtB.getTime() - dtA.getTime(); // Millisecs var secDiff = msDiff/1000; var minDiff = secDiff/60; var houDiff = minDiff/60; var dayDiff = houDiff/24; var weeDiff = dayDiff/7; var delta = 0; // Integer return value with(dojo.date.dateParts){ switch(interv){ case YEAR: delta = yeaDiff; break; case QUARTER: var mA = dtA.getMonth(); var mB = dtB.getMonth(); // Figure out which quarter the months are in var qA = Math.floor(mA/3) + 1; var qB = Math.floor(mB/3) + 1; // Add quarters for any year difference between the dates qB += (yeaDiff * 4); delta = qB - qA; break; case MONTH: delta = monDiff; break; case WEEK: // Truncate instead of rounding // Don't use Math.floor -- value may be negative delta = parseInt(weeDiff); break; case DAY: delta = dayDiff; break; case WEEKDAY: var days = Math.round(dayDiff); var weeks = parseInt(days/7); var mod = days % 7; // Even number of weeks if (mod == 0) { days = weeks*5; } // Weeks plus spare change (< 7 days) else { var adj = 0; var aDay = dtA.getDay(); var bDay = dtB.getDay(); weeks = parseInt(days/7); mod = days % 7; // Mark the date advanced by the number of // round weeks (may be zero) var dtMark = new Date(dtA); dtMark.setDate(dtMark.getDate()+(weeks*7)); var dayMark = dtMark.getDay(); // Spare change days -- 6 or less // ---------- // Positive diff if (dayDiff > 0) { switch (true) { // Range starts on Sat case aDay == 6: adj = -1; break; // Range starts on Sun case aDay == 0: adj = 0; break; // Range ends on Sat case bDay == 6: adj = -1; break; // Range ends on Sun case bDay == 0: adj = -2; break; // Range contains weekend case (dayMark + mod) > 5: adj = -2; break; default: // Do nothing break; } } // Negative diff else if (dayDiff < 0) { switch (true) { // Range starts on Sat case aDay == 6: adj = 0; break; // Range starts on Sun case aDay == 0: adj = 1; break; // Range ends on Sat case bDay == 6: adj = 2; break; // Range ends on Sun case bDay == 0: adj = 1; break; // Range contains weekend case (dayMark + mod) < 0: adj = 2; break; default: // Do nothing break; } } days += adj; days -= (weeks*2); } delta = days; break; case HOUR: delta = houDiff; break; case MINUTE: delta = minDiff; break; case SECOND: delta = secDiff; break; case MILLISECOND: delta = msDiff; break; default: // Do nothing break; } } // Round for fractional values and DST leaps return Math.round(delta); // Number (integer) };