Skip navigation.

exploreopera

| Help

Sign up | Help

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.

ECMAScript's FunctionDeclaration versus FunctionExpressionreal *nix devs don't test in IE

Comments

avatar

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? :smile:

ok I think I got it :smile:


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


There p:

By shoust, # 7. February 2007, 19:41:54

avatar
@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).

By GKiller, # 7. February 2007, 20:27:29

avatar
@shoust and GKiller...

Just use .getFullYear()

By Jere, # 7. February 2007, 20:34:05

avatar
@Jere:

Hehe, great advice :smile: 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; }

:wink:

By GKiller, # 7. February 2007, 20:44:32

avatar

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 :smile:

Edit: Changed less than sign to more than sign, oops :smile: , again changed code, I should experiment with it more :right: edit: me gives up

By shoust, # 7. February 2007, 21:11:39

avatar
@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 :smile:

By GKiller, # 7. February 2007, 22:15:42

avatar
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.

By hallvors, # 7. February 2007, 22:40:23

avatar
I remember shortly after new year 1999/2000 where "19100" started to show up at several places :smile:

By hzr, # 7. February 2007, 23:22:29

avatar
http://www.quirksmode.org/js/datecompat.html tells about getYear support in historical browsers (until year 2000). According to this site, Op2+ and NS2 and NS4+ and WinIE3 follow the spec, NS3 and MacIE3 and IE4+ and WebTV break it.

It is NS3 and WebTV that break the spec while also do not supporting getFullYear...

By Rijk, # 7. February 2007, 23:40:04

avatar
"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".

By HeroreV, # 8. February 2007, 01:28:39

avatar

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:

By xErath, # 8. February 2007, 03:55:05

avatar

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!

By johnnysaucepn, # 8. February 2007, 09:34:13

avatar
Yeah, it should be "ternary", as you can see in http://en.wikipedia.org/wiki/Ternary_operation

@xErath:
No, I was not joking, why?

By GKiller, # 8. February 2007, 18:15:40

avatar
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:

By Andrew Gregory, # 9. February 2007, 02:29:40

avatar
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.

By ZeroJ, # 28. March 2007, 01:25:46

avatar
ZeroJ: NO. Please Do NOT use browser sniffing unless absolutely necessary. sniffing is a last resort, see http://dev.opera.com/articles/view/using-capability-detection/ for better approaches.

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

avatar
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; }
}) ()

By Random832, # 22. May 2007, 18:11:49

avatar
My wife have stuck trying to fill out this online application for E-ZPass in Opera. See PAYMENT METHOD section for problemmatic Expiration Date fields.

By FataL, # 4. June 2007, 16:23:27

avatar
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 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

Write a comment

You must be logged in to write a comment. if you're not a registered member, please sign up.