DateTime so với DateTimePackset


742

Hiện tại, chúng tôi có một cách xử lý tiêu chuẩn với .NET DateTimetheo cách nhận biết TimeZone: Bất cứ khi nào chúng tôi sản xuất DateTimechúng tôi đều làm điều đó trong UTC (ví dụ như sử dụng DateTime.UtcNow) và bất cứ khi nào chúng tôi hiển thị, chúng tôi sẽ chuyển đổi lại từ UTC sang giờ địa phương của người dùng .

Điều đó hoạt động tốt, nhưng tôi đã đọc về DateTimeOffsetvà làm thế nào nó nắm bắt thời gian địa phương và UTC trong chính đối tượng. Vì vậy, câu hỏi là, những lợi thế của việc sử dụng DateTimeOffsetso với những gì chúng ta đã và đang làm là gì?


3
Có một số câu trả lời tuyệt vời dưới đây. Nhưng tôi vẫn đang tự hỏi điều gì, nếu có bất cứ điều gì, có thể đã thuyết phục bạn bắt đầu sử dụng DateTime Offerset.
HappyNomad


Khi nói đến lưu trữ, stackoverflow.com/questions/4715620/ cũng rất thú vị.
Dejan

Câu trả lời:


1169

DateTimeOffsetlà một đại diện của thời gian tức thời (còn được gọi là thời gian tuyệt đối ). Theo đó, tôi có nghĩa là một khoảnh khắc thời gian là phổ quát cho tất cả mọi người (không tính đến giây nhuận , hoặc các hiệu ứng tương đối của sự giãn nở thời gian ). Một cách khác để mô tả thời gian tức là với một DateTimenơi .KindDateTimeKind.Utc.

Điều này khác với thời gian theo lịch (còn được gọi là giờ dân sự ), là một vị trí trên lịch của ai đó và có nhiều lịch khác nhau trên toàn cầu. Chúng tôi gọi những múi giờ này . Hiện Lịch được đại diện bởi một DateTimenơi .KindDateTimeKind.Unspecifiedhay DateTimeKind.Local. Và .Localchỉ có ý nghĩa trong các tình huống mà bạn có một sự hiểu biết ngụ ý về nơi máy tính đang sử dụng kết quả được định vị. (Ví dụ: máy trạm của người dùng)

Vậy thì, tại sao DateTimeOffsetthay vì UTC DateTime? Đó là tất cả về quan điểm. Chúng ta hãy sử dụng một sự tương tự - chúng ta sẽ giả làm nhiếp ảnh gia.

Hãy tưởng tượng bạn đang đứng trên dòng thời gian lịch, hướng máy ảnh vào một người trên dòng thời gian tức thời được đặt trước mặt bạn. Bạn sắp xếp máy ảnh của mình theo các quy tắc múi giờ của bạn - thay đổi định kỳ do thời gian tiết kiệm ánh sáng ban ngày hoặc do những thay đổi khác đối với định nghĩa pháp lý về múi giờ của bạn. (Bạn không có bàn tay chắc chắn, vì vậy máy ảnh của bạn bị rung.)

Người đứng trong bức ảnh sẽ nhìn thấy góc mà máy ảnh của bạn đến từ đâu. Nếu những người khác đang chụp ảnh, họ có thể từ các góc độ khác nhau. Đây là những gì Offsetmột phần của DateTimeOffsetđại diện.

Vì vậy, nếu bạn gắn nhãn máy ảnh của mình là "Giờ phương Đông", đôi khi bạn chỉ từ -5 và đôi khi bạn chỉ từ -4. Có máy ảnh trên khắp thế giới, tất cả đều được dán nhãn những thứ khác nhau, và tất cả đều chỉ vào cùng một dòng thời gian tức thời từ các góc độ khác nhau. Một số trong số chúng nằm ngay cạnh (hoặc trên đỉnh) của nhau, vì vậy chỉ cần biết phần bù không đủ để xác định múi giờ mà thời gian có liên quan.

Còn UTC thì sao? Chà, đó là một chiếc máy ảnh ngoài kia được đảm bảo có một bàn tay chắc chắn. Nó nằm trên giá ba chân, neo chắc chắn xuống đất. Nó không đi đâu cả. Chúng tôi gọi góc nhìn của nó là độ lệch bằng không.

Thời gian tức thời so với trực quan hóa thời gian lịch

Vậy - sự tương tự này nói với chúng ta điều gì? Nó cung cấp một số hướng dẫn trực quan-

  • Nếu bạn đại diện cho thời gian liên quan đến một nơi cụ thể, hãy biểu thị thời gian theo lịch với a DateTime. Chỉ cần chắc chắn rằng bạn không bao giờ nhầm lẫn một lịch với nhau. Unspecifiednên là giả định của bạn. Localchỉ hữu ích đến từ DateTime.Now. Ví dụ, tôi có thể lấy DateTime.Nowvà lưu nó trong cơ sở dữ liệu - nhưng khi tôi truy xuất nó, tôi phải thừa nhận rằng nó là như vậy Unspecified. Tôi không thể tin rằng lịch địa phương của tôi giống với lịch ban đầu được lấy từ đó.

  • Nếu bạn phải luôn chắc chắn về thời điểm này, hãy chắc chắn rằng bạn đang đại diện cho thời gian tức thời. Sử dụng DateTimeOffsetđể thực thi nó, hoặc sử dụng UTC DateTimetheo quy ước.

  • Nếu bạn cần theo dõi một khoảnh khắc của thời gian tức thời, nhưng bạn cũng muốn biết "Thời gian nào người dùng nghĩ rằng đó là trên lịch địa phương của họ?" - thì bạn phải sử dụng a DateTimeOffset. Điều này rất quan trọng đối với các hệ thống chấm công, ví dụ - cả về mối quan tâm kỹ thuật và pháp lý.

  • Nếu bạn cần sửa đổi một bản ghi đã được ghi lại trước đó DateTimeOffset- bạn không có đủ thông tin trong phần bù để đảm bảo rằng phần bù mới vẫn phù hợp với người dùng. Bạn cũng phải lưu trữ một mã định danh múi giờ (nghĩ - tôi cần tên của máy ảnh đó để tôi có thể chụp ảnh mới ngay cả khi vị trí đã thay đổi).

    Cũng cần chỉ ra rằng Noda Time có một đại diện được gọi ZonedDateTimecho điều này, trong khi thư viện lớp cơ sở .Net không có gì tương tự. Bạn sẽ cần lưu trữ cả a DateTimeOffsetvà một TimeZoneInfo.Idgiá trị.

  • Đôi khi, bạn sẽ muốn đại diện cho một thời gian theo lịch là "địa phương đang xem nó". Ví dụ, khi xác định những gì ngày nay có nghĩa. Hôm nay luôn luôn là nửa đêm đến nửa đêm, nhưng chúng đại diện cho một số lượng phạm vi chồng chéo gần như vô tận trên dòng thời gian tức thời. (Trong thực tế, chúng tôi có số lượng múi giờ hữu hạn, nhưng bạn có thể thể hiện độ lệch xuống mức tích tắc) Vì vậy, trong những tình huống này, hãy đảm bảo bạn hiểu cách hạn chế "ai hỏi?" đặt câu hỏi xuống một múi giờ duy nhất, hoặc giải quyết việc dịch chúng trở lại thời gian tức thời khi thích hợp.

Dưới đây là một vài thông tin nhỏ khác về DateTimeOffsetsự tương tự này và một số mẹo để giữ cho nó thẳng:

  • Nếu bạn so sánh hai DateTimeOffsetgiá trị, đầu tiên chúng được chuẩn hóa thành zero offset trước khi so sánh. Nói cách khác, 2012-01-01T00:00:00+00:002012-01-01T02:00:00+02:00đề cập đến cùng một khoảnh khắc tức thời, và do đó là tương đương.

  • Nếu bạn đang làm bất kỳ kiểm tra đơn vị và cần phải chắc chắn trong những bù đắp, kiểm tra cả các DateTimeOffsetgiá trị, và các .Offsettài sản riêng.

  • Có một chuyển đổi ngầm định một chiều được tích hợp trong khung .Net cho phép bạn chuyển một tham số hoặc DateTimebất kỳ DateTimeOffsettham số nào . Khi làm như vậy, các .Kindvấn đề . Nếu bạn vượt qua một loại UTC, nó sẽ mang theo với độ lệch bằng 0, nhưng nếu bạn vượt qua .Localhoặc .Unspecified, nó sẽ giả sử là cục bộ . Khung cơ bản là nói, "Chà, bạn đã yêu cầu tôi chuyển đổi thời gian lịch sang thời gian tức thời, nhưng tôi không biết điều này đến từ đâu, vì vậy tôi sẽ sử dụng lịch địa phương." Đây là một vấn đề lớn nếu bạn tải lên một thông tin không xác định DateTimetrên máy tính có múi giờ khác. (IMHO - điều đó sẽ tạo ra một ngoại lệ - nhưng không.)

Ổ cắm không biết xấu hổ:

Nhiều người đã chia sẻ với tôi rằng họ thấy sự tương tự này vô cùng quý giá, vì vậy tôi đã đưa nó vào khóa học Pluralsight của mình, Nguyên tắc cơ bản về Ngày và Giờ . Bạn sẽ tìm thấy hướng dẫn từng bước của sự tương tự máy ảnh trong mô-đun thứ hai, "Các vấn đề bối cảnh", trong clip có tiêu đề "Thời gian lịch so với thời gian tức thời".


4
@ZackJannsen Nếu bạn có DateTimeOffsetC #, thì bạn nên duy trì điều đó với DATETIMEOFFSETSQL Server. DATETIME2hoặc chỉ DATETIME(tùy thuộc vào phạm vi yêu cầu) là tốt cho các DateTimegiá trị thông thường . Có - bạn có thể giải quyết thời gian cục bộ từ bất kỳ cặp múi giờ + dto hoặc utc nào. Sự khác biệt là - bạn có luôn muốn tính toán các quy tắc với mỗi lần giải quyết hay bạn muốn tính toán trước chúng? Trong nhiều trường hợp (đôi khi vì những lo ngại về pháp lý), DTO là lựa chọn tốt hơn.
Matt Johnson-Pint

3
@ZackJannsen Đối với phần thứ hai của câu hỏi của bạn, tôi khuyên bạn nên làm nhiều nhất có thể phía máy chủ. Javascript không phải là tuyệt vời để tính toán múi giờ. Nếu bạn phải làm điều đó, sử dụng một trong những thư viện này . Nhưng phía máy chủ là tốt nhất. Nếu bạn có câu hỏi chi tiết khác, vui lòng bắt đầu một câu hỏi SO mới cho họ và tôi sẽ trả lời nếu tôi có thể. Cảm ơn.
Matt Johnson-Pint

4
@JoaoLeme - Điều đó phụ thuộc vào việc bạn lấy nó từ đâu. Bạn đúng rằng nếu bạn nói DateTimeOffset.Nowtrên máy chủ, bạn thực sự sẽ nhận được sự bù đắp của máy chủ. Điểm quan trọng là DateTimeOffsetloại có thể giữ lại phần bù đó. Bạn có thể dễ dàng làm điều đó trên máy khách, gửi nó đến máy chủ và sau đó máy chủ của bạn sẽ biết bù đắp của máy khách.
Matt Johnson-Pint

8
Thực sự thích máy ảnh tương tự.
Sachin Kainth

2
Vâng đúng rồi. Ngoại trừ việc DTO được lưu trữ dưới dạng cặp (thời gian cục bộ, bù), không phải cặp (thời gian utc, bù). Nói cách khác, phần bù từ UTC đã được phản ánh theo giờ địa phương. Để chuyển đổi trở lại utc, đảo ngược dấu của phần bù và áp dụng nó cho giờ địa phương.
Matt Johnson-Pint

328

Từ Microsoft:

Những cách sử dụng này cho các giá trị DateTimePackset phổ biến hơn nhiều so với các giá trị DateTime. Do đó, DateTime Offerset nên được coi là loại ngày và thời gian mặc định để phát triển ứng dụng.

nguồn: "Lựa chọn giữa DateTime, DateTime Offerset, TimeSpan và TimeZoneInfo" , MSDN

Chúng tôi sử dụng DateTimeOffsetcho hầu hết mọi thứ khi ứng dụng của chúng tôi xử lý kịp thời các điểm cụ thể (ví dụ: khi bản ghi được tạo / cập nhật). Là một lưu ý phụ, chúng tôi cũng sử dụng DATETIMEOFFSETtrong SQL Server 2008.

Tôi thấy DateTimelà hữu ích khi bạn muốn chỉ xử lý ngày, chỉ thời gian hoặc xử lý theo nghĩa chung. Ví dụ, nếu bạn có một báo động mà bạn muốn đi tắt mỗi ngày lúc 7 giờ sáng, bạn có thể lưu trữ trong một DateTimesử dụng một DateTimeKindsố Unspecifiedbởi vì bạn muốn nó đi tắt vào lúc 7h sáng bất kể DST. Nhưng nếu bạn muốn đại diện cho lịch sử xảy ra báo động, bạn sẽ sử dụng DateTimeOffset.

Hãy thận trọng khi sử dụng kết hợp DateTimeOffsetDateTimeđặc biệt là khi gán và so sánh giữa các loại. Ngoài ra, chỉ so sánh các DateTimetrường hợp giống nhau DateTimeKindDateTimebỏ qua bù thời gian khi so sánh.


146
Câu trả lời được chấp nhận là quá dài và sự tương tự bị căng thẳng, đây là một câu trả lời IMO tốt hơn và ngắn gọn hơn nhiều.
nexus nói

10
Tôi sẽ chỉ nói rằng tôi cũng thích câu trả lời này, và được nâng cấp. Mặc dù trong phần cuối cùng - thậm chí đảm bảo Kindlà như nhau, so sánh có thể bị lỗi. Nếu cả hai bên DateTimeKind.Unspecifiedbạn không thực sự biết rằng họ đến từ cùng múi giờ. Nếu cả hai bên đều như vậy DateTimeKind.Local, hầu hết các so sánh sẽ ổn, nhưng bạn vẫn có thể có lỗi là một bên là mơ hồ trong múi giờ địa phương. Thực sự chỉ DateTimeKind.Utcso sánh là hoàn hảo, và vâng, DateTimeOffsetthường được ưa thích. (Chúc mừng!)
Matt Johnson-Pint

1
+1 Tôi muốn thêm vào điều này: Kiểu dữ liệu bạn chọn sẽ phản ánh ý định của bạn. Không sử dụng DateTimePackset ở mọi nơi, chỉ vì nguyên nhân. Nếu Offset quan trọng đối với Tính toán và Đọc-Từ / Kiên trì-Đối với DataBase, thì hãy sử dụng DateTimePackset. Nếu điều đó không quan trọng, thì hãy sử dụng DateTime, để bạn hiểu (chỉ cần nhìn vào Kiểu dữ liệu) rằng Offset sẽ không có liên quan và Thời gian sẽ vẫn liên quan đến Địa phương của Máy chủ / Máy mà Mã C # của bạn đang chạy.
MikeTeeVee

"Nhưng nếu bạn muốn đại diện cho lịch sử xảy ra báo động, bạn sẽ sử dụng DateTime Offerset." Bạn có quan tâm để giải thích lý do tại sao bạn nghĩ rằng đây là? Tôi có thể điền thông tin đó bằng cách đọc tất cả thông tin trên trang này nhưng có lẽ bạn cũng có thể cung cấp thông tin đó theo cách dễ đọc. Đây là một câu trả lời rất dễ đọc.
Barrosy

77

DateTime chỉ có khả năng lưu trữ hai lần riêng biệt, giờ địa phương và UTC. Các Loại bất động sản chỉ ra đó.

DateTimePackset mở rộng về điều này bằng cách có thể lưu trữ thời gian địa phương từ bất cứ nơi nào trên thế giới. Nó cũng lưu trữ phần giữa giờ địa phương và UTC. Lưu ý cách DateTime không thể thực hiện việc này trừ khi bạn thêm một thành viên bổ sung vào lớp của mình để lưu trữ phần bù UTC đó. Hoặc chỉ từng làm việc với UTC. Mà trong đó là một ý tưởng tốt btw.


33

Có một vài nơi có DateTimeOffsetý nghĩa. Một là khi bạn đang xử lý các sự kiện định kỳ và thời gian tiết kiệm ánh sáng ban ngày. Giả sử tôi muốn đặt báo thức để tắt vào lúc 9 giờ sáng mỗi ngày. Nếu tôi sử dụng quy tắc "lưu trữ dưới dạng UTC, hiển thị dưới dạng giờ địa phương", thì báo thức sẽ tắt vào một thời điểm khác khi thời gian tiết kiệm ánh sáng ban ngày có hiệu lực.

Có thể có những cái khác, nhưng ví dụ trên thực tế là một ví dụ mà tôi đã gặp trong quá khứ (đây là trước khi bổ sung DateTimeOffsetBCL - giải pháp của tôi lúc đó là lưu trữ rõ ràng thời gian trong múi giờ địa phương và tiết kiệm thông tin múi giờ dọc theo nó: về cơ bản là những gì DateTimeOffsetbên trong).


12
DateTime
Offerset

2
Sử dụng lớp TimeZoneInfo thực hiện các quy tắc cho DST. nếu bạn đang sử dụng .net 3.5 trở lên thì hãy sử dụng các lớp TimeZone hoặc TimeZoneInfo để xử lý các ngày phải xử lý Giờ tiết kiệm ánh sáng ban ngày kết hợp với phần bù múi giờ.
Zack Jannsen

1
Có ví dụ hay về một ngoại lệ (ứng dụng báo thức) nhưng khi thời gian quan trọng hơn ngày bạn nên thực sự lưu trữ riêng biệt trong cấu trúc dữ liệu lịch biểu của mình cho ứng dụng, tức là loại xảy ra = Hàng ngày và thời gian = 09:00. Vấn đề ở đây là nhà phát triển cần phải biết loại ngày họ đang ghi, tính toán hoặc trình bày cho người dùng. Đặc biệt là các ứng dụng có xu hướng toàn cầu hơn bây giờ chúng ta có internet như các cửa hàng ứng dụng tiêu chuẩn và lớn để viết phần mềm. Là một nút bên tôi cũng muốn thấy Microsoft thêm một cấu trúc Ngày và Giờ riêng biệt.
Tony Wall

3
Tóm tắt ý kiến ​​của Jarrett và Zack: Có vẻ như một mình DateTimePackset sẽ không xử lý vấn đề DST nhưng sử dụng DateTimePackset kết hợp với TimeZoneInfo sẽ xử lý nó. Điều này không khác với DateTime, nơi loại là Utc. Trong cả hai trường hợp, tôi phải biết múi giờ (không chỉ là phần bù) của lịch mà tôi đang chiếu vào thời điểm này. (Tôi có thể lưu trữ nó trong hồ sơ của người dùng hoặc lấy nó từ máy khách (ví dụ: Windows) nếu có thể). Âm thanh phải không?
Jeremy Cook

"Có một vài nơi mà DateTimePackset có ý nghĩa." --- Có thể cho rằng, nó thường có ý nghĩa hơn là không.
Ronnie Overby

23

Điểm khác biệt quan trọng nhất là DateTime không lưu trữ thông tin múi giờ, trong khi DateTime Offerset thì có.

Mặc dù DateTime phân biệt giữa UTC và Local, nhưng hoàn toàn không có bù múi giờ rõ ràng liên quan đến nó. Nếu bạn thực hiện bất kỳ loại tuần tự hóa hoặc chuyển đổi nào, múi giờ của máy chủ sẽ được sử dụng. Ngay cả khi bạn tạo thủ công giờ địa phương bằng cách thêm phút để bù giờ UTC, bạn vẫn có thể nhận được bit trong bước tuần tự hóa, vì (do không có bất kỳ khoảng bù rõ ràng nào trong DateTime), nó sẽ sử dụng bù múi giờ của máy chủ.

Ví dụ: nếu bạn tuần tự hóa một giá trị DateTime với Kind = Local bằng Json.Net và định dạng ngày ISO, bạn sẽ nhận được một chuỗi như thế 2015-08-05T07:00:00-04. Lưu ý rằng phần cuối (-04) không liên quan gì đến DateTime của bạn hoặc bất kỳ phần bù nào bạn đã sử dụng để tính toán ... đó hoàn toàn là phần bù múi giờ của máy chủ.

Trong khi đó, DateTimePackset rõ ràng bao gồm phần bù. Nó có thể không bao gồm tên của múi giờ, nhưng ít nhất nó bao gồm phần bù và nếu bạn tuần tự hóa nó, bạn sẽ nhận được phần bù được bao gồm rõ ràng trong giá trị của bạn thay vì bất cứ thời gian nào của máy chủ xảy ra.


14
với tất cả các câu trả lời ở trên, tôi tự hỏi tại sao không ai bận tâm viết câu đơn của bạn mà tổng hợp tất cả lênThe most important distinction is that DateTime does not store time zone information, while DateTimeOffset does.
Korayem

9
DateTime Offerset KHÔNG lưu trữ thông tin múi giờ. Tài liệu MS có tiêu đề "Lựa chọn giữa DateTime, DateTimePackset, TimeSpan và TimeZoneInfo" chỉ định thông báo này: "Giá trị DateTimePackset không được gắn với một múi giờ cụ thể, nhưng có thể bắt nguồn từ bất kỳ múi giờ nào". Điều đó nói rằng, DateTime Offerset IS múi giờ AWARE, chứa phần bù từ UTC, điều này tạo ra sự khác biệt và đó là lý do tại sao MS khuyến nghị lớp mặc định khi xử lý phát triển ứng dụng liên quan đến thông tin ngày. Nếu bạn thực sự quan tâm đến việc múi giờ cụ thể của dữ liệu đến từ đâu, bạn phải giữ riêng dữ liệu đó
stencedauwg

1
Có, nhưng như đã được hiển thị ở nhiều nơi, + hoặc - giờ không nói gì về múi giờ bạn đã ở và cuối cùng là vô dụng. Tùy thuộc vào những gì bạn cần làm, bạn cũng có thể lưu trữ một datetime như Kind.Unspecified và sau đó lưu trữ id của múi giờ của nó và tôi nghĩ rằng bạn thực sự tốt hơn.
Arwin

13

Đoạn mã này của Microsoft giải thích mọi thứ:

// Find difference between Date.Now and Date.UtcNow
  date1 = DateTime.Now;
  date2 = DateTime.UtcNow;
  difference = date1 - date2;
  Console.WriteLine("{0} - {1} = {2}", date1, date2, difference);

  // Find difference between Now and UtcNow using DateTimeOffset
  dateOffset1 = DateTimeOffset.Now;
  dateOffset2 = DateTimeOffset.UtcNow;
  difference = dateOffset1 - dateOffset2;
  Console.WriteLine("{0} - {1} = {2}", 
                    dateOffset1, dateOffset2, difference);
  // If run in the Pacific Standard time zone on 4/2/2007, the example
  // displays the following output to the console:
  //    4/2/2007 7:23:57 PM - 4/3/2007 2:23:57 AM = -07:00:00
  //    4/2/2007 7:23:57 PM -07:00 - 4/3/2007 2:23:57 AM +00:00 = 00:00:00

9

Hầu hết các câu trả lời đều tốt, nhưng tôi nghĩ sẽ thêm một số liên kết của MSDN để biết thêm thông tin



7

Một sự khác biệt lớn là DateTimeOffsetcó thể được sử dụng cùng với TimeZoneInfođể chuyển đổi sang thời gian cục bộ trong các múi giờ khác với thời gian hiện tại.

Điều này rất hữu ích trên một ứng dụng máy chủ (ví dụ ASP.NET) được người dùng truy cập trong các múi giờ khác nhau.


3
@Bugeo Bugeo là đúng, nhưng có một rủi ro. Bạn có thể so sánh hai DateTimes bằng cách gọi "ToUniversalTime" đầu tiên trên mỗi. Nếu bạn có chính xác một giá trị trong so sánh đó là DateTimeKind = Không xác định, chiến lược của bạn sẽ thất bại. Khả năng thất bại này là một lý do để xem xét DateTimePackset qua DateTime khi cần chuyển đổi sang giờ địa phương.
Zack Jannsen

Như trên, tôi nghĩ trong kịch bản này, bạn nên lưu trữ TimeZoneId hơn là sử dụng DateTime Offerset, điều này cuối cùng không có nghĩa gì.
Arwin

2

Mặt tiêu cực duy nhất của DateTimePackset tôi thấy là Microsoft "quên" (theo thiết kế) để hỗ trợ nó trong lớp XmlSerializer của họ. Nhưng nó đã được thêm vào lớp tiện ích XmlConvert.

XmlConvert.ToDateTime Offerset

XmlConvert.ToString

Tôi nói hãy tiếp tục và sử dụng DateTimePackset và TimeZoneInfo vì tất cả các lợi ích, chỉ cần cẩn thận khi tạo các thực thể sẽ hoặc có thể được tuần tự hóa đến hoặc từ XML (sau đó tất cả các đối tượng kinh doanh).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.