Làm cách nào để thay đổi múi giờ trong html?

Nhiều nhà phát triển JavaScript tiếp cận xử lý các vấn đề về ngày và múi giờ với sự e ngại. Và thực sự, thật dễ dàng để trở thành một nút thắt khi bạn đang cố gắng sắp xếp thời gian làm việc hợp lý cho tất cả người dùng của mình. Các vấn đề về ngày tháng và múi giờ cũng không phải là vấn đề mà một thư viện tuyệt vời có thể giải quyết dễ dàng. Nhưng với sự hiểu biết vững chắc về các nguyên tắc cơ bản, bạn sẽ thấy rằng việc suy nghĩ về cách làm việc với ngày tháng trong JavaScript trở thành một vấn đề dễ giải quyết

Hãy bắt đầu với một cái nhìn tổng quan ngắn gọn về ý nghĩa của một điều gì đó xảy ra trong vũ trụ

Đây là một cái gì đó

Làm cách nào để thay đổi múi giờ trong html?

Nó xảy ra vào một thời điểm cụ thể và chúng tôi chủ yếu muốn biết đây là mấy giờ trong múi giờ địa phương của chúng tôi. JavaScript rất xuất sắc trong việc xử lý kiểu biểu diễn ngày này, cho dù chúng ta đang làm việc trên trình duyệt hay máy chủ

> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 14:47:00 GMT-0500 (Eastern Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"2:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"2:47 PM Jan 08, 2020"

Nếu chúng tôi thay đổi cài đặt múi giờ trên máy tính của mình thành Oslo, chúng tôi sẽ nhận được một kết quả khác

> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"

Điều này là vì nó nên được. Dòng tweet xảy ra tại một thời điểm và thời điểm đó phải được bản địa hóa cho người dùng. Múi giờ mà Dave Jorgenson tình cờ tham gia không phải là điều chúng tôi thực sự quan tâm và múi giờ của trung tâm dữ liệu Twitter chắc chắn không phải là điều chúng tôi quan tâm. Biểu diễn bên trong của JavaScript sử dụng thời gian UTC “phổ quát” nhưng vào thời điểm ngày/giờ được hiển thị, nó có thể đã được bản địa hóa theo cài đặt múi giờ trên máy tính của người dùng

Và quả thực, đó là cách JavaScript được thiết lập để hoạt động. JavaScript Date luôn được lưu trữ dưới dạng UTC và hầu hết các phương thức gốc tự động bản địa hóa kết quả

Có một vài ngoại lệ đáng chú ý đối với quy tắc của các phương pháp ngày tự động bản địa hóa. Đầu tiên, phương thức getTime() trả về thứ gần nhất với biểu diễn cơ bản thực của ngày trong bộ nhớ. số mili giây kể từ năm 1970, giờ UTC. Tương tự như vậy, toISOString() luôn trả về ngày theo giờ UTC, bạn có thể biết điều này vì chuỗi kết thúc bằng chữ Z, biểu thị thời gian UTC vì các lý do lịch sử liên quan đến Đế quốc Anh (và nằm ngoài phạm vi của bài viết này)

Dù bằng cách nào, ngày JavaScript luôn đại diện cho một thời điểm trong vũ trụ, sao cho nó có thể dễ dàng – và hầu hết thời gian tự động – được bản địa hóa cho môi trường của người dùng. Và nếu đây là tất cả những gì chúng ta từng muốn, cuộc sống sẽ thật tuyệt

Nhưng, tất nhiên, nó không phải là. Không phải lúc nào chúng ta cũng muốn và không phải lúc nào cũng phải nghĩ về những ngày tháng diễn ra vào một thời điểm nhất định.

Tại sao chống nội địa hóa?

Không phải tất cả mọi thứ với một ngày thực sự xảy ra tại một thời điểm trong vũ trụ. Ngày lễ tình nhân là khi nào? . Nó bắt đầu vào những thời điểm khác nhau (phổ quát) cho những người ở các múi giờ khác nhau. Nó đủ để nói rằng nó bắt đầu lúc 12 giờ sáng ngày 14 tháng 2

Ngày thuần túy - ngày lễ, thời hạn bảo hiểm, v.v. - là ví dụ rõ ràng nhất về ngày tháng chống nội địa hóa

Đây là một ví dụ khác. điều gì sẽ xảy ra nếu tôi nói rằng tôi nghĩ 4. 30 là thời gian quá sớm để dậy vào buổi sáng? . 30 và sẽ không phù hợp nếu giá trị đó thay đổi trên màn hình nếu bạn thay đổi múi giờ trên máy tính của mình

Không quá khó để lưu trữ lý tưởng kinh điển này trong một cấu trúc dữ liệu chống nội địa hóa

> "Steve thinks 4:30 is too early"
"Steve thinks 4:30 is too early"

> moment.localizeThisSomehow("Steve thinks 4:30 is too early")
Uncaught TypeError: moment.localizeThisSomehow is not a function

Ở đây, nhập người bạn cũ của chúng tôi

> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
0, đây là giải pháp thay thế được tôn vinh theo thời gian để lưu trữ ngày trong khi tránh các mối quan tâm về múi giờ và UTC. Không phải các chuỗi đó là một lựa chọn hoàn hảo để biểu thị “thời gian trên tường”, đặc biệt nếu chúng ta phải thực hiện một số tính toán ngày tháng, chẳng hạn như xác định thời gian sớm nhất quá sớm giữa một nhóm người

Bây giờ chúng tôi đã xác định rằng có một số trường hợp mà chúng tôi không muốn tự động bản địa hóa, hãy xem ngôn ngữ JavaScript tiếp cận vấn đề này hợp lý như thế nào

Đây là một cái gì đó để làm hỏng ngày của bạn

console.log(new Date("2020-01-01").toString());
// -> Tue Dec 31 2019 19:00:00 GMT-0500 (Eastern Standard Time)

console.log(format(new Date("2020-01-01"), "MMMM do yyyy"));
// -> December 31st 2019

// moment magically fixes this problem for you
console.log(moment("2020-01-01").format("MMMM Do YYYY"));
// -> January 1st 2020

// .. unless you invoke with a date and not a string
console.log(moment(new Date("2020-01-01")).format("MMMM Do YYYY"));
// -> December 31st 2019

Những gì đang xảy ra ở đây?

Như chúng tôi đã đề cập, JavaScript lưu trữ ngày tháng trên toàn cầu và bản địa hóa chúng cho người dùng. Khi chúng tôi tạo một ngày mới vào ngày

> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
1, ngày phổ biến mà JavaScript đã chọn là nửa đêm ở Luân Đôn, tức là đêm giao thừa ở Hoa Kỳ, điều này giải thích cho cách đáng tiếc là ngày đó đã được bản địa hóa

console.log(new Date("2020-01-01").toISOString());
// -> 2020-01-01T00:00:00.000Z

console.log(new Date("2020-01-01").toString());
// -> Tue Dec 31 2019 19:00:00 GMT-0500 (Eastern Standard Time)

Cách làm cho ngày JavaScript phù hợp với bạn

Hầu hết các cơ sở dữ liệu đều có một tập hợp phong phú các lựa chọn thay thế để lưu trữ ngày tháng.

> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
2,
> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
3,
> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
4,
> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
5 và
> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
6. Chúng thậm chí có thể được lưu trữ dưới dạng
> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
7 hoặc một số kiểu dữ liệu giống như chuỗi. Bất kể chúng được thể hiện như thế nào trong cơ sở dữ liệu, rất có thể chúng sẽ trở thành JavaScript Date vào thời điểm chúng tôi muốn làm việc với chúng. Do đó, điều quan trọng là phải hiểu các giả định đã được xây dựng trong quá trình chuyển đổi này

Bởi vì JavaScript chỉ có một loại dữ liệu tối đa để biểu thị ngày tháng, nên phần lớn vấn đề đau đầu khi làm việc với ngày tháng và múi giờ trong JavaScript xoay quanh việc xử lý ngày tháng JavaScript chỉ biểu thị một phần thông tin mà chúng tôi thực sự đang cố mã hóa. Thông tin đó cần được trích xuất cẩn thận từ phần còn lại của thông tin mà JavaScript yêu cầu thêm vào

Ví dụ: giả sử chúng ta đang chạy Node. js trên máy chủ, kết nối với cơ sở dữ liệu PostgreSQL thông qua thư viện

> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
9 và truy vấn cột
> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
2 của PostgreSQL. Hãy nhớ rằng JavaScript Date luôn đại diện cho một thời điểm cụ thể, vì vậy cuộc sống của chúng ta sắp trở nên khó chịu

Trong trường hợp này, thư viện

> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
9 sẽ trả về thời điểm nửa đêm xảy ra vào ngày được đề cập bằng cách sử dụng múi giờ mà máy chủ đã đặt thành. Đây không nhất thiết phải là múi giờ của người dùng, cũng không phải là thời gian mà sự kiện thực sự xảy ra. Trên thực tế, có khả năng giá trị này hoàn toàn không đại diện cho một sự kiện thực sự đã xảy ra, vì nó được lưu trữ dưới dạng
> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
2 trong cơ sở dữ liệu chứ không phải
> new Date("2020-01-08T19:47:00.000Z")
Wed Jan 08 2020 20:47:00 GMT+0100 (Central European Standard Time)

> moment("2020-01-08T19:47:00.000Z").format("h:mm a MMM DD, YYYY") // using moment.js
"8:47 pm Jan 08, 2020"

> format(parseISO("2020-01-08T19:47:00.000Z"), "h:mm a MMM dd, yyyy") // using date-fns
"8:47 PM Jan 08, 2020"
4/
> "Steve thinks 4:30 is too early"
"Steve thinks 4:30 is too early"

> moment.localizeThisSomehow("Steve thinks 4:30 is too early")
Uncaught TypeError: moment.localizeThisSomehow is not a function
5/v.v.

Tuy nhiên, chúng tôi bị mắc kẹt ở đây với một Date JavaScript không thực sự đại diện cho những gì chúng tôi muốn nó đại diện. Tuy nhiên, một số phần của nó đại diện cho những gì chúng tôi muốn hiển thị, và chúng tôi cần trêu chọc và xoa bóp những phần chúng tôi muốn

Giả sử bạn là nhà phát triển front-end. Bạn chỉ đang tìm cách hiển thị “Ngày 14 tháng 2” và đã nhận được báo cáo lỗi rằng người dùng ở các múi giờ khác đang nhìn thấy “Ngày 13 tháng 2”. Khi bạn đào sâu một chút vào đối tượng này, bạn sẽ thấy rằng ngay cả khi bạn hiển thị chính xác nó là “Ngày 14 tháng 2”, bạn vẫn đang gặp may, bởi vì thời gian cơ bản đôi khi cách nửa đêm vài giờ. Bây giờ bạn có ấn tượng rõ ràng rằng ngày của bạn sắp bị hủy hoại

Hãy hít một hơi thật sâu và suy nghĩ về các nguyên tắc sau

  • JavaScript luôn coi ngày là thời điểm cụ thể
  • Chúng được lưu trữ dưới dạng UTC nhưng hầu hết các phương pháp đều tự động bản địa hóa cho bạn
  • Không phải mọi ngày thực sự là một cái gì đó xảy ra tại một thời điểm cụ thể
  • Trong những trường hợp này, đối tượng JavaScript Date thường cung cấp quá nhiều hoặc thông tin sai

Vì vậy, những gì đang xảy ra ở đây? . Bây giờ là nửa đêm của múi giờ mà máy chủ được đặt. Mã của bạn có thể đang bản địa hóa nó theo cài đặt múi giờ trên máy tính của người dùng. Nếu bạn chỉ hiển thị ngày, tháng và năm, thì bạn có khoảng 50% cơ hội hiển thị đúng

Bạn có thể quản lý bản địa hóa múi giờ của người dùng, bởi vì điều này chỉ được thực hiện bởi một số phương thức Date gốc. Đáng chú ý, toISOString() sẽ luôn trả về cùng một kết quả bất kể múi giờ của người dùng là gì. Nếu đây là loại ngày mà bạn không muốn bản địa hóa, thì đó là một nơi tốt để bắt đầu

Mặt khác, bạn không thể dễ dàng viết mã theo cách của mình để thoát khỏi bản địa hóa múi giờ của máy chủ, bởi vì điều này đã được đưa vào thời gian chung của ngày JavaScript. Vì vậy, bạn thực sự cần biết múi giờ của máy chủ, đây là công việc cần được thực hiện phía máy chủ

Chống lại sự cám dỗ để cho rằng bạn biết múi giờ của máy chủ. Giải pháp đó không chỉ không khả dụng, mà ở Hoa Kỳ, múi giờ của máy chủ của bạn sẽ thay đổi hai lần một năm, khi thời gian tiết kiệm ánh sáng ban ngày chạm mốc. Thay vào đó, hãy thuyết phục các nhà phát triển back-end thêm một điểm cuối để hiển thị múi giờ của máy chủ

const localOffset = new Date().getTimezoneOffset(); // in minutes
// -> 480 for California in the winter

Để hiển thị ngày này một cách chắc chắn, chúng ta phải thực sự thay đổi thời gian chung mà đối tượng JavaScript đang cố gắng biểu thị. Hãy nhớ rằng getTime() chuyển đổi ngày thành một số nguyên đại diện cho mili giây. Nếu chúng tôi sao lưu phần bù múi giờ của máy chủ và áp dụng phần bù múi giờ địa phương, chúng tôi sẽ chuyển giờ quốc tế từ nửa đêm của máy chủ sang nửa đêm địa phương của người dùng

const dateFromServer = new Date("2010-02-14T08:00:00.000Z"); // California midnight
const serverOffset = 480; // in minutes, from that API call
const serverOffsetMillis = 60 * 1000 * serverOffset;
const localOffset = new Date().getTimezoneOffset(); // in minutes
const localOffsetMillis = 60 * 1000 * localOffset;
const localMidnight = new Date(dateFromServer.getTime() - serverOffsetMillis + localOffsetMillis);
console.log(localMidnight.toString());
// -> Sun Feb 14 2010 00:00:00 GMT-0500 (Eastern Standard Time)

Trong cộng đồng JavaScript, chúng tôi ghét viết sáu dòng mã cho một thứ cơ bản như hiển thị ngày theo lịch một cách tự tin. Cả

console.log(new Date("2020-01-01").toString());
// -> Tue Dec 31 2019 19:00:00 GMT-0500 (Eastern Standard Time)

console.log(format(new Date("2020-01-01"), "MMMM do yyyy"));
// -> December 31st 2019

// moment magically fixes this problem for you
console.log(moment("2020-01-01").format("MMMM Do YYYY"));
// -> January 1st 2020

// .. unless you invoke with a date and not a string
console.log(moment(new Date("2020-01-01")).format("MMMM Do YYYY"));
// -> December 31st 2019
1 và
console.log(new Date("2020-01-01").toString());
// -> Tue Dec 31 2019 19:00:00 GMT-0500 (Eastern Standard Time)

console.log(format(new Date("2020-01-01"), "MMMM do yyyy"));
// -> December 31st 2019

// moment magically fixes this problem for you
console.log(moment("2020-01-01").format("MMMM Do YYYY"));
// -> January 1st 2020

// .. unless you invoke with a date and not a string
console.log(moment(new Date("2020-01-01")).format("MMMM Do YYYY"));
// -> December 31st 2019
2 đều có các chức năng tiện ích có thể giúp ích một chút, nhưng chúng không thể làm tất cả việc này cho bạn. Khi bạn đang làm việc với ngày tháng trong JavaScript, vẫn không có cách nào khác để hiểu điều gì đang diễn ra bên trong

Làm cách nào để tạo múi giờ trong HTML?

Danh sách múi giờ - Đoạn mã HTML chọn/thả xuống .
dữ liệu-múi giờ-id. Tương ứng với một mã định danh duy nhất múi giờ nội bộ, thường là một mục trong bảng cơ sở dữ liệu
điều chỉnh dữ liệu gmt. Điều chỉnh GMT
data-use-daylight. Cho biết nếu múi giờ sử dụng "Giờ tiết kiệm ánh sáng ban ngày"

Làm cách nào để chuyển đổi múi giờ trong JavaScript?

Phương thức toLocaleString() được sử dụng để trả về một chuỗi định dạng ngày theo ngôn ngữ và các tùy chọn đã chỉ định. Nó sẽ chuyển đổi ngày mà phương thức được sử dụng từ múi giờ này sang múi giờ khác. cú pháp. Hoa KỳThời gian = ngày.