getYear. No, not that year!
Wednesday, 7. February 2007, 17:38:50
Date and time calculation is hard. JavaScript's getYear (specified as "returns the number of years since 1900") doesn't make it easier. And then there are the browser differences - quick recap: Opera, Netscape and Firefox follow the spec while IE and Safari don't, they return a full four-digit year (unless the year is between 1900 and 1999, in which case they follow the spec).
Confusing? No match for the web's JavaScript authors! Here are some actual workarounds for this problem - taken from real websites:
The habitual sniffer approach
var year=time.getYear(); if ((navigator.appName == "Microsoft Internet Explorer") && (year < 2000)) year="19" + year; if (navigator.appName == "Netscape") year=1900 + year;Source
The "I'll never forget when I wrote that code" approach
var year=RightNow.getYear();
if (year==106){year="2006";}SourceThe "string length" approach (well, it works until 2900!)
var y=date.getYear()+"";
if (y.length < 4) {y=""+(y-0+1900);}SourceBoth above approaches at the same time!
var anyo = ''+fecha.getYear();
var ano;
if (anyo == "99") {
ano=1999;
}
else if (anyo.length!=4) {
ano=1900 + parseInt(anyo,10);
}
else {
ano=anyo;
}SourceThe "let's implement some Y2K bugs" approach
var cc_year = today.getYear();
if (cc_year > 99 && cc_year < 200) {cc_year += 1900} else { if (cc_year < 100) {cc_year = 2000 + cc_year}} (Works as expected for years between 2000 and 2100 only) SourceThe "Y2K bugs are OK for dates before 1970" approach
a=new Date(document.lastModified);
lm_year=a.getYear();
if (lm_year<1000){ //just in case date is delivered with 4 digits
if (lm_year<70){
lm_year=2000+lm_year;
}
else lm_year=1900+lm_year;
}//end workaroundSourceThe "1793 correct years to go ought to be enough for anybody" approach
var Y = time.getYear();
if(Y<1900){Y+=1900;
SourceOff-topic, another gem from the same script - I really wonder what the Mac IE bug was..
//This will need to be adjusted every year
if(MAC_tz && IE_tz && (time<Date.parse('Sun Oct 31 01:00:00 EDT 2004') || time>Date.parse('Sun Apr 3 01:00:00 EDT 2005')) && tzOffset != -1 && tzOffset!=4)The "well, let's just hardcode it" approach
copyright=new Date();
update=copyright.getYear();
//---write copyright
document.write("Copyright © 1998/2006 Brightwater Engineers - All rights reserved.");SourceAnd finally, the priceless "string concatenation" approach
var today = new Date()
var theYear = parseInt(today.getYear(),10)
if (mthIdx < today.getMonth()) {
theYear = (parseInt(today.getYear(), 10) + 1)
}
if(theYear<100){
theYear = "19" + theYear
}
else{
if((theYear-100) < 10){
theYear = "0" + (theYear-100)
}
else{
theYear = (theYear-100)+""
}
theYear = "20" + theYear
}SourceFun.
Confusing enough to find the correct code
Whats your way to doing it correctly?
ok I think I got it
There
By shoust, # 7. February 2007, 19:41:54
So what do you recommend?
@shoust:
*edit, here stood a wrong statement*
Your code does not work for years between 1900 and 2000 (for spec-compliant browsers) and 1900 - 1999 (IE-like).
By GKiller, # 7. February 2007, 20:27:29
Just use .getFullYear()
By Jere, # 7. February 2007, 20:34:05
Hehe, great advice
I think the maximum with getYear you can get is a modification from an example above:
var Y = time.getYear();
if (Y < 2000) { Y+=1900; }
By GKiller, # 7. February 2007, 20:44:32
Just was working with the context of older browsers, knew there was getFullYear, but that above should be pretty much cross browser compatible I think
Edit: Changed less than sign to more than sign, oops
By shoust, # 7. February 2007, 21:11:39
The problem with your trinary operator is, that if a browser does not implement getFullYear, it does not return "null" or false or something like that, but throws a javascript error.
That may be caught with a try-catch statement, but, of course, browsers that do not support getFullYear certainly don't support try-catch
By GKiller, # 7. February 2007, 22:15:42
Naturally, in pre-getFullYear browsers that support getYear correctly, "year" would now be years since 1900.
If one can trust that the browsers that do not support getFullYear also implement getYear according to the spec this is the perfect solution:
However, I don't know if this assumption holds. I guess older IE version is a possible headache - I don't know if they started violating the getYear spec before implementing getFullYear. In such a browser, you might end up with a value that is 1900 years in the future.
By hallvors, # 7. February 2007, 22:40:23
By hzr, # 7. February 2007, 23:22:29
It is NS3 and WebTV that break the spec while also do not supporting getFullYear...
By Rijk, # 7. February 2007, 23:40:04
By HeroreV, # 8. February 2007, 01:28:39
Originally posted by Andrew Gregory:
Originally posted by GKiller:
You are joking right ?By xErath, # 8. February 2007, 03:55:05
Originally posted by HeroreV:
Maybe Hallvord likes to code in dolphin poetry. I must admit, I think I've called it the trinary operator more than once - never would have noticed that!
By johnnysaucepn, # 8. February 2007, 09:34:13
@xErath:
No, I was not joking, why?
By GKiller, # 8. February 2007, 18:15:40
xErath has quoted me from another blog post, and I couldn't agree with myself more!
By Andrew Gregory, # 9. February 2007, 02:29:40
if(navigator.appName == "Opera"){
var yearNow = today.getFullYear();
}else{
var yearNow = today.getYear();
}
Check if browser is Opera, use getFullYear instead of getYear..
No need to fix date.
By ZeroJ, # 28. March 2007, 01:25:46
On this specific issue look at the "perfect solution" a few comments up. If WebTV compliance is required, sniff specifically for the problematic WebTV versions and amend the value as required.
By hallvors, # 28. March 2007, 13:55:22
Real perfect solution:
(function () {
var orig_getYear = Date.prototype.getYear;
if(!Date.prototype.getFullYear) {
Date.prototype.getFullYear = function() {
// won't work for years that are actually 0..99 AD
var x = orig_getYear.call(this);
return ((x >= 0 && x < 100 )? 1900 : 0 ) + x;
}
}
Date.prototype.getYear = function() { return this.getFullYear() - 1900; }
}) ()
By Random832, # 22. May 2007, 18:11:49
By FataL, # 4. June 2007, 16:23:27
(function () {
var orig_getYear = Date.prototype.getYear;
if(!Date.prototype.getFullYear) {
Date.prototype.getFullYear = function() {
// won't work for years that are actually 0..99 AD
var x = orig_getYear.call(this);
return ((x >= 0 && x < 100 )? 1900 : 0 ) + x;
}
}
Date.prototype.getYear = function() { return this.getFullYear() - 1900; }
}) ()
Greate. I'll try another way to fix this solution
By ZeroJ, # 18. October 2007, 06:15:02