getYear. No, not that year!

The great thing about JavaScript's Date.getYear()? It makes reading source code fun again.. …

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";}

Source

The "string length" approach (well, it works until 2900!)

var y=date.getYear()+"";
if (y.length < 4) {y=""+(y-0+1900);}

Source

Both 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;
}

Source

The "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) Source

The "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 workaround

Source

The "1793 correct years to go ought to be enough for anybody" approach

var Y = time.getYear();
if(Y<1900){Y+=1900;

Source

Off-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.");

Source

And 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
}

Source

Fun.

Advertisements

19 thoughts on “getYear. No, not that year!

  1. var year=time.getYear();
    if(year <1000)
    {year+=1900}
    

    Confusing enough to find the correct code :p 2nd edit.Whats your way to doing it correctly? :)ok I think I got it 🙂

    var year=time.getYear();
    if(100<year)
    {year+=1900}
    

    There :p

  2. @Hallvord: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).

  3. @Jere:Hehe, great advice 🙂 I now remember reading that using getFullYear is always recommended, but since I don't code that much JS, I had already forgotten that again. But AFAIK getFullYear is not supported by old (how old?) browsers.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; };)

  4. var time=new Date(); var year=time.getFullYear()?time.getFullYear():time.getYear(); if(year<1900){year+=1900};
    

    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 🙂 , again changed code, I should experiment with it more :right: edit: me gives up

  5. The trinary version above would be my preferred way, fixed with a proper object detection:

    var year=time.getFullYear ? time.getFullYear() : time.getYear();

    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:

    var year=time.getFullYear ? time.getFullYear() : time.getYear()+1900;

    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.

  6. @shoust: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 🙂

  7. "Trinary"? I've never seen it called that before. I usually see "ternary". I myself prefer to be more specific and always call it the "conditional operator". Both the ECMAScript and C++ specifications call it the "conditional operator".

  8. Originally posted by Andrew Gregory:

    It just reinforces my view that most people building web sites have no idea what they're doing!

    :spock:Originally posted by GKiller:

    So what do you recommend?

    You are joking right ?:right:

  9. Originally posted by HeroreV:

    "Trinary"? I've never seen it called that before. I usually see "ternary". I myself prefer to be more specific and always call it the "conditional operator". Both the ECMAScript and C++ specifications call it the "conditional operator".

    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!

  10. if (year==106){year="2006";}

    :yikes: (runs away screaming…)xErath has quoted me from another blog post, and I couldn't agree with myself more! :p:cry:

  11. var today = new Date(); 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.

  12. The problem is that the spec for getYear actually _changed_ between javascript 1.2 and 1.3 (netscape 4 or somesuch), and IE just didn't change with it. So any browser that does _not_ implement getFullYear is guaranteed to have the sequence "…1898, 1899, 0, 1, … 99, 2000, 2001…" as with IE.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; }}) ()

  13. As I know, Internet Explorer work difference Opera and FireFox. I use filter browser because almost people use Internet Eplorer, Opera and Firefox, of course it have another way to fix this line.(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 ADvar 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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s