
//     JAVASCRIPT INCLUDE FILE - (c) J R Stockton  >= 2002-10-12
//             http://www.merlyn.demon.co.uk/include3.js
//       Routines may be copied, but URL must not be linked to.
//               Needs, for LZ at least, include1.js



function VSF() { document.writeln( // After Michael Donn
  ' <a href="view-source:'+this.location+'">View Source File<\/a>') }


// Date/Time Utilities :


// Date.prototype.getTimezoneOffset = new Function("with (this) return 0 ")


function DoWstr(DoWk) { // JS & ISO
 return "SunMonTueWedThuFriSatSun".substr(3*DoWk, 3) }


Date.prototype.ISOlocaltimeStr =
 new Function("with (this) return " +
  "LZ(getHours())+':'+LZ(getMinutes())+':'+LZ(getSeconds())")


Date.prototype.ISOlocaldateStr =
 new Function("with (this) return " +
  "getFullYear()+'-'+LZ(getMonth()+1)+'-'+LZ(getDate())")


Date.prototype.ISOlocalDTstr =
 new Function("with (this) return " +
  "ISOlocaldateStr()+' '+ISOlocaltimeStr()")


Date.prototype.UTCstr =
 new Function("with (this) return " +
  "getUTCFullYear()+'-'+LZ(getUTCMonth()+1)+'-'+LZ(getUTCDate())+' '+ " +
  "LZ(getUTCHours())+':'+LZ(getUTCMinutes())+':'+LZ(getUTCSeconds()) ")


Date.prototype.UTCDstr =
 new Function("with (this) return " +
  "DoWstr(getUTCDay())+', '+UTCstr() ")



Date.prototype.TZstr = // SIGN SHOULD BE RIGHT
 new Function("var X, Y, Z ; with (this) { X=getTimezoneOffset() ; " +
  " Y = Math.abs(X) ; Z = Y % 60 ; Y = (Y-Z)/60 ;" +
  " return (X>0?'-':'+')+LZ(Y)+':'+LZ(Z) }")



function ValidDate(y, m, d) // m = 0..11
 { with (new Date(y, m, d)) return ((getFullYear()==y) && (getMonth()==m)) }

function ReadISO8601date(Q) { var T // adaptable for other layouts
 if ((T = /^(\d+)([-\/])(\d\d)(\2)(\d\d)$/.exec(Q)) == null)
  { return -2 } // bad format
 for (var j=1; j<=5; j+=2) { T[j] = parseInt(T[j], 10) } // wanted ?
 if (!ValidDate(T[1], T[3]-1, T[5])) { return -1 } // bad value
 return [ T[1], T[3], T[5] ] }



if (!String.substr) {
 String.prototype.substr =
  new Function("J", "K", "return this.substring(J, J+K)") }




// MJD 40587 = 1970-01-01 = Javascript day 0. Generally, m is 1..12.

function YMDtoMJD(y, m, d) { return 40587 + (Date.UTC(y, m-1, d)/86400000) }

function MJDtoYMD(MJD) {
 with (new Date((MJD-40587)*86400000)) {
  return [getUTCFullYear(), getUTCMonth()+1, getUTCDate()] }
 /* UTC from 20001115 */ }

function MJDtoISOdow(MJD) { return ((MJD-40587+77777773)%7)+1 } // ISO


function YMDtoYND(y, m, d) { // ISO WkNo. m = 1..12
 var ms1d = 86400000, ms3d=3*ms1d, ms7d=7*ms1d

 var D3=Date.UTC(y,m-1,d)+ms3d
 var wk=Math.floor(D3/ms7d)

 with (new Date(wk*ms7d)) { var yy=getUTCFullYear() }
 return [yy, 1+wk-Math.floor((Date.UTC(yy,0,4)+ms3d)/ms7d),
  ((D3/ms1d)+777777)%7+1] // revised 2001-06-28 for < 1970.

 // for a more general case, alter that "0, 4" and maybe "ms3d"
 }



function UKtaxWN(y, m, d) { // m = 1..12
 var St = 'UK Inland Revenue Tax:'

 var fy = y ; if (m*32+d<134) fy--
 var dd = (Date.UTC(y, m-1, d) - Date.UTC(fy, 3, 6))/86400000
 St += '\nYear ' + fy +
  ', Week ' + LZ(Math.floor(dd/7)+1) + ', Day ' + LZ((dd%7)+1) + ';'

 var yy = y, mm = m
 if (d<6) mm--
 if (mm<4) { yy-- ; mm += 12 }
 St += '\nYear ' + yy + ', Month ' + LZ(mm-3) + '.'

 return St }

function WkNoDtoMJD(Y, N, D) {
 var Jan4 = YMDtoMJD(Y, 1, 4)
 var DoWk = (Jan4+777772)%7
 return Jan4 - DoWk + 7*(N-1) + (D-1)
 }

function JDNtoMJD(YYYY, DDD) {
 return YMDtoMJD(YYYY, 1, 1) + (DDD-1)
 }

function LastSun(y, m, ult) {
 return ult - (YMDtoMJD(y, m, ult)+77777773)%7
 }

function Easter(Yr) {
 // Gregorian, after E G Richards, Algorithm P - upper limit ~ AD 112000?
 var AA = Math.floor(Yr / 100)
 var BB = AA - Math.floor(AA / 4)
 var CC = Yr % 19
 var DD =
  (15 + 19*CC + BB - Math.floor((AA + 1 - Math.floor((AA+8) / 25)) / 3)) % 30
 var EE = DD - Math.floor((CC+11*DD) / 319)
// var S = 22 + EE + (140004 -  Yr - Math.floor(Yr / 4)    + BB - EE) % 7
   var S = 22 + EE + (140004 - (Yr + Math.floor(Yr / 4))%7 + BB - EE) % 7
// Extra %7 greatly increases year range - jrs 20021012
 var EMo = 3 + Math.floor(S / 32)
 var EDy = 1 + (S-1) % 31
 return [EMo, EDy]
 }

function DaysInMonth(Y, M) { // M=1..12   >= 2000-09-01
 with (new Date(Y,M,1,12)) { setDate(0) ; return getDate() } } // OK in NS4?

function leapyear(y)
 { return (new Date(y, 1, 29)).getMonth() == 1 } // F X Mahoney

function Suffix(j) {
 return "thstndrd".substr("01230000000000000000012300000001".charAt(j)*2,2) }

function TimeChangeDates(Y) {
 var Ton, Tof, JanOff, JulOff, TonMin, TonMax, TofMin, TofMax, K
 with(new Date(Y, 00, 01)) {
  TonMin = TofMin = getTime() ; JanOff = getTimezoneOffset()
  setMonth(06) ; JulOff = getTimezoneOffset()
  if (JanOff == JulOff) { return [0,0] }
  setMonth(12) ; TonMax = TofMax = getTime()
  var Min = Math.min(JanOff, JulOff), Max = Math.max(JanOff, JulOff)
  Ton = Tof = (TonMin + TofMax)/2
  for (K=0; K<22; K++) {
   setTime(Ton) ; if (getTimezoneOffset() != Max)
    { TonMax = Ton ; Ton = (TonMin+Ton)/2 }
    else
    { TonMin = Ton ; Ton = (Ton+TonMax)/2 }
   setTime(Tof) ; if (getTimezoneOffset() != Min)
    { TofMax = Tof ; Tof = (TofMin+Tof)/2 }
    else
    { TofMin = Tof ; Tof = (Tof+TofMax)/2 }
   }
  }
 return [Math.round(Ton/60000)*60000, Math.round(Tof/60000)*60000]
 }





// end.

