Rate this post

Chúng ta hãy gặp một Object tích hợp mới: Date. Nó lưu trữ Date, Time và cung cấp các phương pháp quản lý Date / Time.

Các bài viết liên quan:

Ví dụ: chúng ta có thể sử dụng nó để lưu trữ thời gian tạo / sửa đổi, để đo thời gian hoặc chỉ để in ra Date hiện tại.

Cách tạo

Để tạo một Object Date mới, hãy gọi new Date () với một trong các parameter sau:

  1. new Date()

Không có parameter – tạo Object Date cho Date và Time hiện tại:

let now = new Date ();
alert (now); // hiển thị Date / Time hiện tại

  1. new Date (mili giây)

Tạo Object Date với thời gian bằng số mili giây (1/1000 giây) được chuyển sau Date 1 Month 1 Year 1970 UTC + 0.

// 0 nghĩa là 01.01.1970 UTC + 0
let Jan01_1970 = new Date(0);
alert( Jan01_1970 );

// Time thêm 24 giờ, nhận 02.01.1970 UTC + 0
let Jan02_1970 = new Date(24 * 3600 * 1000);
alert( Jan02_1970 );

Một số nguyên đại diện cho số mili giây đã trôi qua kể từ đầu Year 1970 được gọi là dấu thời gian.

Đó là một đại diện số nhẹ của Date. Chúng tôi luôn có thể tạo Date từ dấu thời gian bằng cách sử dụng new Date (dấu thời gian) và chuyển đổi Object Date hiện có thành dấu thời gian bằng phương thức date.getTime () (xem bên dưới).

Các Date trước 01.01.1970 có dấu thời gian âm, ví dụ:

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

Nếu có một parameter duy nhất và đó là một chuỗi thì nó sẽ được phân tích cú pháp tự động. Thuật toán Timeng như Date.parse sử dụng, chúng ta sẽ đề cập đến nó ở phần sau.

let date = new Date ("2017-01-26");
alert (Date Month);
// Thời gian không được đặt, vì vậy nó được giả định là nửa đêm theo Time GMT và
// được điều chỉnh theo múi Time mà mã được chạy
// Vì vậy, kết quả có thể là
// Thứ Year, Date 26 Month 1 Year 2017 11:00:00 GMT + 1100 (Time ban Date miền Đông Úc)
// hoặc
// Thứ Tư Date 25 Month 1 Year 2017 16:00:00 GMT-0800 (Time Chuẩn Thái Bình Dương)

  1. new Date (Year, Month, Date, Time, phút, giây, mili giây)

Tạo Date với các thành phần đã cho trong múi Time địa phương. Chỉ có hai parameter đầu tiên là bắt buộc.

  • Year phải có 4 chữ số: 2013 thì được, 98 thì không.
  • Số Month bắt đầu bằng 0 (Month 1), đến 11 (Month 12).
  • Tham số Date thực sự là Date trong Month, nếu không có thì giá trị 1 được giả định.
  • Nếu không có Time / phút / giây / ms, chúng được coi là bằng 0.

Ví dụ:

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

Độ chính xác tối đa là 1 ms (1/1000 giây):

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

Truy cập các thành phần Date

Có các phương pháp để truy cập Year, Month, v.v. từ Object Date:

  • getFullYear () – Lấy Year (4 chữ số)
  • getMonth () – Lấy Month, từ 0 đến 11.
  • getDate() – Lấy Date trong Month, từ 1 đến 31, tên của phương pháp trông hơi lạ.
  • getHours (), getMinutes (), getSeconds (), getMilliseconds () – Nhận các thành phần thời gian tương ứng.

Lưu ý: Không phải getYear (), mà là getFullYear (). Nhiều công cụ JavaScript triển khai một phương thức không chuẩn getYear (). Phương pháp này không được dùng nữa. Nó đôi khi trả về Year 2 chữ số. Xin đừng bao Time sử dụng nó. Có getFullYear () cho Year.

Ngoài ra, chúng ta có thể nhận được một Date trong tuần:

  1. getDay ()

Nhận các Date trong tuần, từ 0 (chủ nhật) đến 6 (thứ bảy). Date đầu tiên luôn là Chủ nhật, ở một số quốc gia không phải như vậy nhưng không thể thay đổi.

Tất cả các phương thức trên trả về các thành phần liên quan đến múi Time địa phương.

Ngoài ra còn có các đối tác UTC của họ, trả về Date, Month, Year, v.v. cho múi Time UTC + 0: getUTCFullYear (), getUTCMonth (), getUTCDay (). Chỉ cần chèn “UTC” Date sau “get”.

Nếu múi Time địa phương của bạn được thay parameter với UTC, thì mã bên dưới sẽ hiển thị các Time khác nhau:

// Date hiện tại
let date = new Date();

// Time trong múi giờ hiện tại của bạn
alert( date.getHours() );

// Time ở múi Time UTC + 0 (Time Luân Đôn không tính tiết kiệm ánh sáng ban Date)
alert( date.getUTCHours() );

Bên cạnh các phương thức đã cho, có hai phương thức đặc biệt không có biến thể UTC:

  1. getTime()

Trả về dấu thời gian cho Date – một số mili giây đã trôi qua kể từ Date 1 Month 1 Year 1970 UTC + 0.

  1. getTimezoneOffset ()

Trả về chênh lệch giữa UTC và múi Time địa phương, tính bằng phút:

// nếu bạn đang ở múi Time UTC-1, kết quả đầu ra là 60
// nếu bạn đang ở múi Time UTC + 3, kết quả đầu ra là -180
alert( new Date().getTimezoneOffset() );

Setting thành phần Date

Các phương pháp sau cho phép thiết lập các thành phần Date / Time:

  • setFullYear (Year, [Month], [Date])
  • setMonth (Month, [Date])
  • setDate (Date Month)
  • setHours (Time, [phút], [giây], [mili giây])
  • setMinutes (phút, [giây], [mili giây])
  • setSeconds (giây, [mili giây])
  • setMilliseconds (mili giây)
  • setTime (mili giây) (đặt toàn bộ Date theo mili giây kể từ Date 01.01.1970 UTC)

Mỗi một trong số chúng ngoại trừ setTime () đều có một biến thể UTC, ví dụ: setUTCHours ().

Như chúng ta thấy, một số phương thức có thể thiết lập nhiều thành phần cùng một lúc, ví dụ setHours. Các thành phần không được đề cập không được sửa đổi.

Ví dụ:

let today = new Date();

today.setHours(0);
alert(today); // vẫn là Date hôm nay, nhưng Time được thay đổi thành 0

today.setHours(0, 0, 0, 0);
alert(today); // vẫn hôm nay, bây Time là 00:00:00 sắc nét.

Autocorrection

Tự động sửa là một tính năng rất tiện dụng của các Object Date. Chúng tôi có thể đặt các giá trị Year ngoài phạm vi và nó sẽ tự động điều chỉnh.

Ví dụ:

let date = new Date (2013, 0, 32); // 32 thg 1, 2013?!?
alert (Date Month); // ... là Date 1 Month 2 Year 2013!

Các thành phần Date Year ngoài phạm vi được phân phối tự động.

Giả sử chúng tôi cần tăng Date “28 Month 2 Year 2016” lên 2 Date. Nó có thể là “2 Month 3” hoặc “1 Month 3” trong trường hợp là Year nhuận. Chúng tôi không cần phải nghĩ về nó. Chỉ cần thêm 2 Date. Object Date sẽ thực hiện phần còn lại:

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

alert( date ); // 1 Mar 2016

Tính năng đó thường được sử dụng để lấy Date sau một khoảng thời gian nhất định. Ví dụ: hãy lấy Date cho “70 giây sau bây Time”:

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

alert( date ); // shows the correct date

Chúng tôi cũng có thể đặt giá trị bằng 0 hoặc thậm chí âm. Ví dụ:

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

date.setDate(1); //  đặt Date 1 trong Month
alert( date );

date.setDate(0); // Date tối thiểu là 1, vì vậy Date cuối cùng của Month trước được giả định
alert( date ); // 31 Dec 2015

Date thành number, Date Diff

Khi một Object Date được chuyển đổi thành số, nó sẽ trở thành dấu thời gian Timeng như date.getTime ():

let date = new Date();
alert(+date); // số mili giây, Timeng như date.getTime ()

Tác dụng phụ quan trọng: Date có thể được trừ đi, kết quả là sự khác biệt của chúng tính bằng mili giây.

Điều đó có thể được sử dụng cho các phép đo thời gian:

let start = new Date();  // bắt đầu đo thời gian

// thực hiện công việc
for (let i = 0; i < 100000; i++) {
  let doSomething = i * i * i;
}

let end = new Date();  // kết thúc thời gian đo

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

Date.now()

Nếu chúng tôi chỉ muốn đo thời gian, chúng tôi không cần Object Date.

Có một phương thức đặc biệt Date.now () trả về dấu thời gian hiện tại.

Về mặt ngữ nghĩa, nó tương đương với Date (). GetTime () mới, nhưng nó không tạo Object Date trung gian. Vì vậy, nó nhanh hơn và không gây áp lực cho việc thu gom rác.

Nó được sử dụng chủ yếu để thuận tiện hoặc khi hiệu suất quan trọng, như trong các trò chơi bằng JavaScript hoặc các ứng dụng chuyên biệt khác.

Vì vậy, điều này có lẽ tốt hơn:

let start = Date.now(); // số mili giây từ Date 1 Month 1 Year 1970

// thực hiện công việc
for (let i = 0; i < 100000; i++) {
  let doSomething = i * i * i;
}

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

alert( `The loop took ${end - start} ms` ); // trừ số, không trừ Date Month

Benchmarking

Nếu chúng ta muốn có một điểm chuẩn đáng tin cậy cho chức năng ngốn CPU, chúng ta nên cẩn thận.

Ví dụ: hãy đo lường hai hàm tính toán sự khác biệt giữa hai Date: cái nào nhanh hơn?

Các phép đo hiệu suất như vậy thường được gọi là “điểm chuẩn”.

// chúng ta có date1 và date2, hàm nào trả về sự khác biệt của chúng theo ms nhanh hơn?
function diffSubtract(date1, date2) {
  return date2 - date1;
}

// hoặc
function diffGetTime(date1, date2) {
  return date2.getTime() - date1.getTime();
}

Hai công cụ này thực hiện chính xác cùng một việc, nhưng một trong số chúng sử dụng date.getTime () rõ ràng để lấy Date bằng mili giây và cái còn lại dựa vào biến đổi Date thành số. Kết quả của họ luôn luôn Timeng nhau.

Vì vậy, cái nào nhanh hơn?

Ý tưởng đầu tiên có thể là chạy chúng nhiều lần liên tiếp và đo chênh lệch thời gian. Đối với trường hợp của chúng ta, các hàm rất đơn giản, vì vậy chúng ta phải thực hiện nó ít nhất 100000 lần.

Hãy đo lường:

<!DOCTYPE html>
<script>
"use strict";

function diffSubtract(date1, date2) {
  return date2 - date1;
}

function diffGetTime(date1, date2) {
  return date2.getTime() - date1.getTime();
}

function bench(f) {
  let date1 = new Date(0);
  let date2 = new Date();

  let start = Date.now();
  for (let i = 0; i < 100000; i++) f(date1, date2);
  return Date.now() - start;
}

alert( 'Time of diffSubtract: ' + bench(diffSubtract) + 'ms' );
alert( 'Time of diffGetTime: ' + bench(diffGetTime) + 'ms' );
</script>

Sử dụng getTime () nhanh hơn rất nhiều! Đó là vì không có chuyển đổi loại, nên các công cụ tối ưu hóa dễ dàng hơn nhiều.

Được rồi, chúng tôi có một cái gì đó. Nhưng đó vẫn chưa phải là một điểm chuẩn tốt.

Hãy tưởng tượng rằng tại thời điểm CPU chạy trên băng ghế dự bị (diffSubtract) đang làm một việc gì đó song song và nó đang sử dụng tài nguyên. Và đến thời điểm chạy băng ghế dự bị (diffGetTime) công việc đó đã kết thúc.

Một kịch bản khá thực tế cho một hệ điều hành đa quy trình hiện đại.

Do đó, điểm chuẩn đầu tiên sẽ có ít tài nguyên CPU hơn điểm chuẩn thứ hai. Điều đó có thể dẫn đến kết quả sai.

Để có điểm chuẩn đáng tin cậy hơn, toàn bộ gói điểm chuẩn nên được chạy lại nhiều lần.

Ví dụ, như thế này:

function diffSubtract(date1, date2) {
  return date2 - date1;
}

function diffGetTime(date1, date2) {
  return date2.getTime() - date1.getTime();
}

function bench(f) {
  let date1 = new Date(0);
  let date2 = new Date();

  let start = Date.now();
  for (let i = 0; i < 100000; i++) f(date1, date2);
  return Date.now() - start;
}

let time1 = 0;
let time2 = 0;

// chạy  bench(diffSubtract) và băng ghế dự bị (diffGetTime) mỗi 10 lần xen kẽ
for (let i = 0; i < 10; i++) {
  time1 += bench(diffSubtract);
  time2 += bench(diffGetTime);
}

alert( 'Total time for diffSubtract: ' + time1 );
alert( 'Total time for diffGetTime: ' + time2 );

Các công cụ JavaScript hiện đại chỉ bắt đầu áp dụng các tối ưu hóa nâng cao cho “hot code” thực thi nhiều lần (không cần tối ưu hóa những thứ hiếm khi được thực thi). Vì vậy, trong ví dụ trên, các lần thực thi đầu tiên không được tối ưu hóa tốt. Chúng tôi có thể muốn thêm một đợt khởi động:

// được thêm vào để "làm nóng" trước vòng lặp chính
bench(diffSubtract);
bench(diffGetTime);

// điểm chuẩn với Time
for (let i = 0; i < 10; i++) {
  time1 += bench(diffSubtract);
  time2 += bench(diffGetTime);
}

Hãy cẩn thận khi thực hiện đánh dấu microbenchmarking

Các công cụ JavaScript hiện đại thực hiện nhiều tối ưu hóa. Họ có thể điều chỉnh kết quả của “kiểm tra nhân tạo” so với “sử dụng bình thường”, đặc biệt khi chúng tôi đánh giá một thứ gì đó rất nhỏ, chẳng hạn như cách hoạt động của một nhà điều hành hoặc một chức năng tích hợp. Vì vậy, nếu bạn thực sự muốn hiểu về hiệu suất, thì hãy nghiên cứu cách hoạt động của JavaScript engine. Và sau đó, bạn có thể sẽ không cần microbenchmarks gì cả.

Bạn có thể tìm thấy nhiều bài viết về V8 tại http://mrale.ph.

Date.parse từ một String

Phương thức Date.parse (str) có thể đọc Date Month từ một chuỗi.

  • Định dạng chuỗi phải là: YYYY-MM-DDTHH: mm: ss.sssZ, trong đó:
  • YYYY-MM-DD – là Date: Year-Month-Date.
  • Ký tự “T” được sử dụng làm dấu phân cách.
  • HH: mm: ss.sss – là thời gian: Time, phút, giây và mili giây.

Phần ‘Z’ tùy chọn biểu thị múi Time ở định dạng + -hh: mm. Một chữ cái Z có nghĩa là UTC + 0.

Các biến thể ngắn hơn cũng có thể xảy ra, như YYYY-MM-DD hoặc YYYY-MM hoặc thậm chí YYYY.

Lệnh gọi đến Date.parse (str) phân tích cú pháp chuỗi theo định dạng đã cho và trả về dấu thời gian (số mili giây từ Date 1 Month 1 Year 1970 UTC + 0). Nếu định dạng không hợp lệ, trả về NaN.

Ví dụ:

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

alert(ms); // 1327611110417  (timestamp)

Chúng tôi có thể tạo Date một Object new Date từ dấu thời gian:

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

alert(date);

Tóm lược

  • Date và Time trong JavaScript được biểu diễn bằng Object Date. Chúng tôi không thể tạo “chỉ Date” hoặc “chỉ thời gian”: Các Object Date luôn mang cả hai.
  • Các Month được tính từ 0 (vâng, Month 1 là Month 0).
  • Các Date trong tuần trong getDay () cũng được tính từ 0 (đó là Chủ nhật).
  • Date tự động sửa khi các thành phần Year ngoài phạm vi được đặt. Tốt để cộng / trừ Date / Month / Time.
  • Date có thể được trừ đi, tạo ra sự khác biệt của chúng tính bằng mili giây. Đó là vì Date trở thành dấu thời gian khi được chuyển đổi thành số.
  • Sử dụng Date.now () để lấy nhanh dấu thời gian hiện tại.

Lưu ý rằng không Timeng như nhiều hệ thống khác, dấu thời gian trong JavaScript tính bằng mili giây chứ không phải giây.

Leave a Reply

Call now
%d bloggers like this: