ทำไม Javascript getYear () ส่งคืน 108


95

เหตุใดจาวาสคริปต์นี้จึงส่งคืน 108 แทนปี 2008 มันทำให้วันและเดือนถูกต้อง แต่ไม่ใช่ปี?

myDate = new Date();
year = myDate.getYear();

ปี = 108?


30
โอ้บาปที่เราพยายามจะผ่าน Y2K
DGentry

3
year = myDate.getFullYear() % 100;
Andrew Larsson

คำตอบ:


128

มันเป็นสิ่งที่Y2Kนับเฉพาะปีตั้งแต่ปี 1900 เท่านั้น

ขณะนี้มีปัญหาความเข้ากันได้ที่อาจgetYear()ได้รับการเลิกใช้งานgetFullYear()- from quirksmode :

เพื่อให้เรื่องซับซ้อนยิ่งขึ้น date.getYear () เลิกใช้แล้วในปัจจุบันและคุณควรใช้ date.getFullYear () ซึ่งในทางกลับกันเบราว์เซอร์รุ่นเก่าไม่รองรับ อย่างไรก็ตามหากใช้งานได้ก็ควรให้ทั้งปีเสมอเช่น 2000 แทนที่จะเป็น 100

เบราว์เซอร์ของคุณให้เวลาสองปีต่อไปนี้:

* The year according to getYear(): 108
* The year according to getFullYear(): 2008

นอกจากนี้ยังมีความแตกต่างของการนำไปใช้งานระหว่าง Internet Explorer และ Firefox เนื่องจากการใช้งานของ IE getYear()ถูกเปลี่ยนให้ทำงานเหมือนgetFullYear()- จากIBM :

ตามข้อกำหนด ECMAScript getYear ส่งคืนปีลบ 1900 เดิมหมายถึงส่งคืน "98" สำหรับปี 1998 getYear เลิกใช้งานใน ECMAScript เวอร์ชัน 3 และแทนที่ด้วย getFullYear ()

Internet Explorer เปลี่ยน getYear () ให้ทำงานเหมือน getFullYear () และทำให้เป็นไปตามมาตรฐาน Y2k ในขณะที่ Mozilla ยังคงพฤติกรรมมาตรฐาน


25

เนื่องจาก getFullYear ไม่ทำงานในเบราว์เซอร์รุ่นเก่าคุณสามารถใช้สิ่งนี้ได้:

Date.prototype.getRealYear = function() 
{ 
    if(this.getFullYear)
        return this.getFullYear();
    else
        return this.getYear() + 1900; 
};

ต้นแบบ Javascript สามารถใช้เพื่อขยายวัตถุที่มีอยู่ได้เช่นเดียวกับวิธีการขยาย C # ตอนนี้เราทำได้แค่นี้

var myDate = new Date();
myDate.getRealYear();
// Outputs 2008

8
บางที smth เช่น Date.prototype.getRealYear = Date.prototype.getFullYear? Date.prototype.getFullYear: function () {return this.getYear () + 1900; };
Valentin Golev

12

ตรวจสอบเอกสาร ไม่ใช่ปัญหา Y2K แต่เป็นปัญหา Y2K ที่ขาดไป! การตัดสินใจนี้เริ่มต้นในภาษา C และถูกคัดลอกไปยัง Perl ซึ่งเห็นได้ชัดว่าเป็น JavaScript และอาจเป็นภาษาอื่น ๆ อีกหลายภาษา เห็นได้ชัดว่าเมื่อนานมาแล้วมันยังคงรู้สึกพึงปรารถนาที่จะใช้ตัวเลขสองหลักปี แต่ที่น่าทึ่งคือใครก็ตามที่ออกแบบอินเทอร์เฟซนั้นมีความคิดล่วงหน้ามากพอที่จะตระหนักได้ว่าพวกเขาจำเป็นต้องคิดถึงสิ่งที่จะเกิดขึ้นในปี 2000 และหลังจากนั้นดังนั้นแทนที่จะระบุเพียงสองตัวสุดท้าย ตัวเลขเหล่านี้ระบุจำนวนปีตั้งแต่ปี 1900 คุณสามารถใช้ตัวเลขสองหลักได้หากคุณรีบร้อนหรือต้องการที่จะเสี่ยง หรือถ้าคุณต้องการให้โปรแกรมของคุณทำงานต่อไปคุณสามารถเพิ่ม 100 ในผลลัพธ์และใช้ตัวเลขสี่หลักปีเต็ม

ฉันจำได้ว่าครั้งแรกที่ฉันเดทกับ Perl แปลกพอฉันอ่านเอกสาร เห็นได้ชัดว่านี่ไม่ใช่เรื่องธรรมดา หนึ่งหรือสองปีต่อมาฉันถูกเรียกตัวไปที่สำนักงานในวันที่ 31 ธันวาคม 2542 เพื่อแก้ไขข้อบกพร่องที่ถูกค้นพบในนาทีสุดท้ายที่เป็นไปได้ในรหัส Perl ของสัญญาซึ่งเป็นสิ่งที่ฉันไม่เคยเกี่ยวข้องกับมันเลย นี่คือปัญหาที่แน่นอน: การโทรวันที่มาตรฐานส่งคืนปีตั้งแต่ปี 1900 และโปรแกรมเมอร์ถือว่าเป็นปีสองหลัก (พวกเขาคิดว่าพวกเขาจะได้รับ "00" ในปี 2000) ในฐานะโปรแกรมเมอร์อายุน้อยที่ไม่มีประสบการณ์มันทำให้ฉันคิดว่าเราต้องจ่ายเงินเพิ่มมากสำหรับงาน "มืออาชีพ" และคนเหล่านั้นก็ไม่สนใจที่จะอ่าน เอกสารประกอบ. มันเป็นจุดเริ่มต้นของความท้อแท้มาหลายปี ตอนนี้ฉันแก่แล้วและถูกเหยียดหยาม :)

ในปี 2000 การประชุม YAPC Perl ประจำปีถูกเรียกว่า "YAPC 19100" เพื่อเป็นเกียรติแก่การไม่พบข้อผิดพลาดนี้

ในปัจจุบันอย่างน้อยที่สุดในโลก Perl ก็มีเหตุผลมากกว่าที่จะใช้โมดูลมาตรฐานสำหรับการจัดการวันที่ซึ่งใช้ปีตัวเลขสี่หลักจริง ไม่แน่ใจว่ามีอะไรบ้างสำหรับ JavaScript


1
ฮิฮิ ... ทำให้ฉันนึกถึงการ์ตูนเรื่อง Dilbert ... "คุณเคยอ่านเรื่องราวเกี่ยวกับผู้ชายชาวสเปนชื่อ Manual หรือไม่?" ;)
Adhip Gupta

ฉันเชื่อว่า @skiphoppy หมายถึงการเพิ่ม 1900 เพื่อ getYear () จะทำให้ได้ทั้งปีที่ต้องการ คล้ายกับการเพิ่ม +1 ใน getMonth () เมื่อดึงข้อมูลตัวเลขที่มนุษย์อ่านได้ของเดือน ตัวอย่าง: var ts = new Date (); var fullYear = (ts.getYear () + 1900); แต่แนะนำให้ใช้ getFullYear () ตัวอย่าง: var fullYear = วันที่ใหม่ (). getFullYear ();
recurse


4

ใช้date.getFullYear().

นี่คือ (ตามที่ระบุไว้อย่างถูกต้องที่อื่น) เป็นสิ่งที่ Y2K Netscape (เขียนก่อนปี 2000) ส่งคืนครั้งแรกเช่น98จากgetYear(). แทนที่จะกลับไปใช้00มันกลับมา100ในปี 2000 แทนจากนั้นเบราว์เซอร์อื่น ๆ ก็เข้ามาและทำมันแตกต่างกันไปและทุกคนก็ไม่พอใจเพราะความไม่ลงรอยกัน

เบราว์เซอร์รุ่นหลังได้รับการสนับสนุนgetFullYearเป็นวิธีมาตรฐานในการส่งคืนปีที่สมบูรณ์


3

คำถามนี้เก่ามากจนทำให้ฉันร้องไห้ด้วยความคิดถึงวันดอทคอม!

ถูกต้อง Date.getYear () ส่งคืนจำนวนปีตั้งแต่ปี 1900 เช่นเดียวกับ Localtime ของ Perl () มีสิ่งหนึ่งที่น่าแปลกใจว่าทำไมภาษาที่ออกแบบในปี 1990 จึงไม่นับว่ามีการหมุนเวียนในศตวรรษนี้ แต่ฉันจะพูดอะไรได้ คุณต้องอยู่ที่นั่น มันเป็นเรื่องที่สมเหตุสมผลในเวลานั้น (เช่นที่ pet.com ทำ)

ก่อนปี 2000 หนึ่งอาจได้รับการล่อลวงเพื่อแก้ไขปัญหานี้โดยการผนวก "19" ถึงผลของการ getYear (The) ส่งผลให้"ปี 19100 ข้อผิดพลาด" มีคนอื่นตอบคำถามนี้เพียงพอแล้ว (เพิ่ม 1900 ในผลลัพธ์ของ getDate ())

บางทีหนังสือที่คุณกำลังอ่านเกี่ยวกับ JavaScript อาจจะเก่าไปหน่อย?

ขอบคุณสำหรับการระเบิดในอดีต!


สาเหตุที่ภาษา (Perl) ไม่ได้กล่าวถึงเป็นเพราะมันคัดลอกการตัดสินใจออกแบบ C ที่ทำไปก่อนหน้านี้อย่างสุ่มสี่สุ่มห้า (20 ปี?)
skiphoppy

ฉันกำลังใช้งาน JavaScript ไม่ใช่ Perl Perl มักจะเปิดเผยกิจวัตร C ที่เป็นพื้นฐานโดยตรง อย่างที่คุณพูดมันเป็นผลผลิตของเวลา JS ซึ่งได้รับการออกแบบอย่างน้อยหนึ่งทศวรรษต่อมาอาจมีเส้นทางที่แตกต่างออกไป
jjohn

2

คุณควรตามที่ระบุไว้ห้ามgetYear()ใช้ แต่ใช้แทนgetFullYear()

อย่างไรก็ตามเรื่องนี้ไม่ง่ายอย่างที่ "IE ใช้GetYear()เช่นเดียวกับgetFullYear()Opera และ IE ในปัจจุบันgetYear()ตามที่getYear()ระบุไว้เดิมสำหรับวันที่ก่อนปี 2000 แต่จะถือว่าเป็นgetFullYear()วันที่หลังปี 2000 ในขณะที่ webkit และ Firefox ยึดติดกับพฤติกรรมเดิม ๆ

สิ่งนี้ส่งผล 99 ในเบราว์เซอร์ทั้งหมด:

javascript:alert(new Date(917823600000).getYear());

เอาต์พุต 108 ใน FF / WebKit และ 2008 ใน Opera / IE:

javascript:alert(new Date().getYear());




0

ตามที่คนอื่น ๆ กล่าวไว้มันจะคืนค่าจำนวนปีตั้งแต่ปี 1900 เหตุผลที่เป็นเช่นนั้นก็คือเมื่อ JavaScript ถูกประดิษฐ์ขึ้นในช่วงกลางทศวรรษที่ 90 พฤติกรรมนั้นทั้งสะดวกและสอดคล้องกับ API วันที่ - เวลาในภาษาอื่น ๆ โดยเฉพาะอย่างยิ่ง C. และแน่นอนว่าเมื่อสร้าง API แล้วจะไม่สามารถเปลี่ยนแปลงได้ด้วยเหตุผลด้านความเข้ากันได้ย้อนหลัง


0

BTW เบราว์เซอร์ที่แตกต่างกันอาจให้ผลลัพธ์ที่แตกต่างกันดังนั้นจึงเป็นการดีกว่าที่จะข้ามฟังก์ชันนี้ไปพร้อมกันและใช้ getFullYear () เสมอ


0

var date_object = วันที่ใหม่ (); var ปี = date_object.getYear (); ถ้า (ปี <2000) {ปี = ปี + 1900; } // จะได้ครบปี ....


-1

กำลังส่งคืนตัวเลข 4 หลักในปี 1900 ซึ่งอาจจะดูดีเมื่อ 9+ ปีที่แล้ว แต่ตอนนี้ค่อนข้างปัญญาอ่อน java.util.Date ของ Java ก็ทำเช่นนี้เช่นกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.