Skip to main content

Date

Date and time

เรามารู้จักกับ built-in Object อีกหนึ่งตัว : Date มันเก็บค่า วัน เวลา และ methods สำหรับการจัดการวันและเวลา

ตัวอย่างเช่น เราสามารถจะใช้มันในการสร้าง/แก้ไข วันและเวลา, วัดเวลา, หรือแสดงผลวันและเวลาออกมา

Creation

ในการสร้าง Date เราสามารถเรียกใช้ new Date() โดยใส่ argument 1 ตัวลงไป

new Date()

ที่ไม่มี argument - สำหรับการสร้าง Date Object สำหรับค่าปัจจุบัน

let now = new Date();
alert( now ); // shows current date/time

new Date(milliseconds)

ในการสร้าง Date Object โดยใส่ค่ามิลลิวินาทีลงไป (1/1000 ของ 1 วินาที) หลังจาก 1 มกราคม ค.ศ. 1970 UTC+0 จะเป็นการดึงวันที่ออกมา

 // 0 means 01.01.1970 UTC+0
let Jan01_1970 = new Date(0);
alert( Jan01_1970 );

// now add 24 hours, get 02.01.1970 UTC+0
let Jan02_1970 = new Date(24 * 3600 * 1000);
alert( Jan02_1970 );

ตัวเลข integer แสดงถึงเลขมิลลิวินาทีที่ผ่าน 1970 มาแล้ว เรียกว่า timestamp

เราสามารถสร้างวันที่จาก timestamp โดยการใช้ new Date(timestamp) และก็สามารถแปลงจาก Date ให้เป็น timestamp ได้ โดยใช้ date.getTime() method

วันที่หลัง 01.01.1970 เราก็จะใช้เลขที่เป็นเลขติดลบ

// 31 Dec 1969
let Dec31_1969 = new Date(-24 * 3600 * 1000);
alert( Dec31_1969 );

new Date(datestring)

ถ้ามี argument ตัวเดียว และเป็น string ระบบจะวิเคราะห์โดยอัตโนมัติ โดยหลักการทำงานจะเหมือนกับ Date.parse โดยเราจะมาสอนอีกที

let date = new Date("2017-01-26");
alert(date);
// The time is not set, so it's assumed to be midnight GMT and
// is adjusted according to the timezone the code is run in
// So the result could be
// Thu Jan 26 2017 11:00:00 GMT+1100 (Australian Eastern Daylight Time)
// or
// Wed Jan 25 2017 16:00:00 GMT-0800 (Pacific Standard Time)

new Date(year, month, date, hours, minutes, seconds, ms)

สร้างวันที่โดยใช้ ส่วนประกอบใน local Timezone โดยบังคับให้มี 2 argument อย่างต่ำ

  • year ควรมี 4 หลัก เพื่อความเข้าใจ โดย 2 หลัก ก็สามารถใช้ได้ โดยจะถูกมองเป็น 19xx เช่น 98 ก็จะถูกมองเป็น 1998 แต่การใช้ 4 หลักก็จะเข้าใจมากกว่า
  • month นับเริ่มจาก 0 (Jan), ไปจนถึง 11 (Dec)
  • date เป็นตัวที่ใส่วันที่ของเดือนนั้น ถ้าไม่มี จะเป็น 1 โดยอัตโนมัติ
  • ถ้า hours/minutes/seconds/ms ไม่มี มันจะถูกตั้งเป็น 0

ตัวอย่างเช่น

new Date(2011, 0, 1, 0, 0, 0, 0); // 1 Jan 2011, 00:00:00
new Date(2011, 0, 1); // the same, hours etc are 0 by default

โดยความแม่นยำที่สูงที่สุดคือ 1 มิลลิวินาที

let date = new Date(2011, 0, 1, 2, 3, 4, 567);
alert( date ); // 1.01.2011, 02:03:04.567

Access date components

มี method ที่จะเข้าถึง ปี, เดือน และ อื่น ๆ จาก Date Object

getFullYear()

ดึงค่าปี (4 หลัก)

getMonth()

ดึงค่าเดือนจาก 0 ถึง 11

getDate()

ดึงค่าวัน จาก 1 ถึง 31

**getHours()getMinutes()getSeconds()getMilliseconds()**

ดึงค่า ชั่วโมง นาที วินาที และ มิลลิวินาที

เพิ่มเติม เราสามารถดึงค่าวันมาได้ด้วย

getDay()

ดึงค่าวันจากสัปดาห์, จาก 0 (วันอาทิตย์) ไปถึง 6 (วันเสาร์). โดยวันแรกจะเป็นวันอาทิตย์เสมอ

ค่าทุกตัวด้านบน จะคืนค่าตาม Time zone นั้น ๆ

และยังมี UTC-counterparts ที่จะคืนค่า วัน เดือน ปี และ อื่น ๆ ที่สอดคล้องกับ Time zone UTC + 0

getUTCFullYear()getUTCMonth()getUTCDay(). แค่ใส่ "UTC" หลังจาก "get".

// current date
let date = new Date();

// the hour in your current time zone
alert( date.getHours() );

// the hour in UTC+0 time zone (London time without daylight savings)
alert( date.getUTCHours() );

getTime()

คืนค่า timestamp สำหรับวันที่ – เลขมิลลิวินาทีจากหลังจาก 1st of 1970 UTC+0.

getTimezoneOffset()

คืนค่าที่แตกต่างกัน ระหว่าง Timezone กับ UTC+0 คืนมาเป็นค่านาที

// if you are in timezone UTC-1, outputs 60
// if you are in timezone UTC+3, outputs -180
alert( new Date().getTimezoneOffset() );

Setting date components

ทุกอันยกเว้น setTime() มี UTC-variant ตัวอย่างเช่น  setUTCHours(). อย่างที่เราเห็น method บางตัว สามารถตั้งค่าหลาย ๆ ตัวได้พร้อมกัน ตัวอย่างเช่น setHours ตัวที่ไม่ถูกตั้งค่า ก็จะไม่ถูกเปลี่ยนค่า

let today = new Date();

today.setHours(0);
alert(today); // still today, but the hour is changed to 0

today.setHours(0, 0, 0, 0);
alert(today); // still today, now 00:00:00 sharp.

Autocorrection

autocorrection เป็นสิ่งที่มีประโยน์มากของ Date Object เราสามารถตั้งค่านอกระยะได้ และ มันจะแก้ไขโดยอัตโนมัติ

ตัวอย่างเช่น

let date = new Date(2013, 0, 32); // 32 Jan 2013 ?!?
alert(date); // ...is 1st Feb 2013!

ค่าที่นอกระยะของมัน จะทำการแก้ไขโดยอัตโนมัติ

ลองพูดว่า เราต้องการจะบวกวันไป 2 วัน ไปที่วันที่ “28 กุมภาพันธ์ุ 2016” มันอาจเป็น “2 มีนาคม” หรือ “1 มีนาคม” ก็ได้ ในกรณีที่เป็น leap year เราไม่จำเป็นต้องไปคิดกับมันมาก เพราะว่า Date จะจัดการเองทั้งหมด

let date = new Date(2016, 1, 28);
date.setDate(date.getDate() + 2);

alert( date ); // 1 Mar 2016

อีกตัวอย่าง ถ้าเราต้องการที่จะเพิ่ม 70 วินาทีเข้าไป จากเวลาปัจจุบัน

let date = new Date();
date.setSeconds(date.getSeconds() + 70);

alert( date ); // shows the correct date

เราสามารถใช้เลข 0 หรือ 1 ได้เหมือนกัน

let date = new Date(2016, 0, 2); // 2 Jan 2016

date.setDate(1); // set day 1 of month
alert( date );

date.setDate(0); // min day is 1, so the last day of the previous month is assumed
alert( date ); // 31 Dec 2015

Date to number, date diff

เมื่อ Date ถูกแปลงเป็น Number มันจะมาเป็น timestamp เหมือนกับ date.getTime():

let date = new Date();
alert(+date); // the number of milliseconds, same as date.getTime()

ผลข้างเคียงที่สำคัญ: dates สามารถเอามาลบกันได้ ผลลัพธ์จะเป็น เวลาที่แตกต่างกันในหน่วยวินาที

let start = new Date(); // start measuring time

// do the job
for (let i = 0; i < 100000; i++) {
let doSomething = i * i * i;
}

let end = new Date(); // end measuring time

alert( `The loop took ${end - start} ms` );

Date.now()

ถ้าเราต้องการจะวัดเวลา และไม่ใช้ Date Object

method พิเศษ  Date.now() ที่จะคืนค่า timestamp ปัจจุบันออกมา

มันจะเหมือนกับการใช้ new Date().getTime() แต่ว่ามันไม่ต้องสร้าง Object Date มา ดังนั้นในการใช้งานแล้ว มันจะเร็วกว่า และ ไม่เพิ่มการทำงานของ garbage collection

มันจะใช้เมื่อเราต้องการเน้นประสิทธิภาพของโค้ด

let start = Date.now(); // milliseconds count from 1 Jan 1970

// do the job
for (let i = 0; i < 100000; i++) {
let doSomething = i * i * i;
}

let end = Date.now(); // done

alert( `The loop took ${end - start} ms` ); // subtract numbers, not dates

Date.parse from a string

method Date.parse(str) สามารถอ่านวันได้จาก string

โดย string จะมี format แบบนี้ YYYY-MM-DDTHH:mm:ss.sssZ โดยที่:

  • YYYY-MM-DD – วัน เดือน ปี
  • ตัวอักษร "T" ใช้เพื่อกำหนดขอบเขต
  • HH:mm:ss.sss – ใช้บอกเวลา - ชั่วโมง นาที วินาที มิลลิวินาที
  • การใช้ (optional) 'Z' เป็นการกำหนด Timezone ใน format +-hh:mm. ตัวอักษร Z ตัวเดียว หมายถึง UTC+0.

เราสามารถเขียนให้สั้นลงได้ เช่น YYYY-MM-DD หรือ YYYY-MM หรือ YYYY.

การเรียกใช้ Date.parse(str) เราจะใส่ string เข้าไปในรูปแบบเดียวกันกับด้านบน และถ้า รูปแบบผิด จะรีเทิร์นเป็น NaN

ตัวอย่างเช่น

let ms = Date.parse('2012-01-26T13:51:50.417-07:00');

alert(ms); // 1327611110417 (timestamp)

เราสามารถสร้างวันที่ใหม่ new Date จาก method นี้ได้เหมือนกัน

let date = new Date( Date.parse('2012-01-26T13:51:50.417-07:00') );

alert(date);

Summary

  • วัน และ เวลาใน JavaScript จะใช้งานได้ด้วย Date object. เราไม่สามารถสร้างแค่ เวลา หรือ วัน ได้ เราต้องสร้างมันทั้งคู่
  • เดือนเริ่มนับจาก 0
  • วันในสัปดาห์ getDay() ก็เริ่มนับจาก 0 เหมือนกัน (เริ่มจากวันอาทิตย์)
  • Date จะทำการแก้ไขโดยอัตโนมัติ เมื่อส่วนประกอบต่าง ๆ ออกนอกเหนือขอบเขตุ เป็นผลดีในการ เพิ่มหรือลบ วัน/เดือน/ปี
  • Dates สามารถลบได้ และจะคืนค่าความแตกต่างที่เป็นวินาทีออกมา นั่นเพราะว่า Date จะเป็น timestamp เมื่อมันถูกแปลงเป็น Number
  • ใช้ Date.now() ในการดึงเวลาปัจจุบันจะเร็วกว่า

จำไว้ว่า timestamp ของ JavaScript ไม่เหมือนกับระบบอื่น ๆ เพราะว่า timestamp มาในรูปแบบของ มิลลิวินาที ไม่ใช่ วินาที

บางทีเราต้องการจะเพิ่มความแม่นยำในการวัดเวลา แต่ JavaScript ไม่มีการวัดเวลาในหน่วย ไมโครวินาที (1 ใน ล้าน ของวินาที) แต่ว่า environments ส่วนใหญ่มี function มาให้ใช้ ตัวอย่างเช่น Browser อาจมี performance.now() ที่จะให้ตัวเลข milliseconds จากเริ่มของการโหลดหน้า page ในหน่วย microsecond

alert(`Loading started ${performance.now()}ms ago`);
// Something like: "Loading started 34731.26000000001ms ago"
// .26 is microseconds (260 microseconds)
// more than 3 digits after the decimal point are precision errors, only the first 3 are correct

Node.js มี microtime module และ ทางอื่น ๆ ทางเทคนิค environment หรือ อุปกรณ์อื่น ๆ ก็อนุญาตให้เราใช้ความแม่นยำได้สูงขึ้น ไม่ใช่มีแค่ Date