2009-08-05 39 views
8

Tôi đã cố gắng tìm một cách hợp lý để lưu trữ dữ liệu hàng ngày bằng cách sử dụng Dữ liệu cốt lõi trên iPhone.Cách lưu trữ ngày tháng không có thời gian trong Dữ liệu chính

Ứng dụng của tôi nhận dữ liệu ở định dạng csv, với một ngày nhưng không có thời gian:

date, cycles 
2009-08-01, 123 
2009-08-02, 234 
2009-08-03, 345 
2009-08-04, 456 

Khi dữ liệu này được lưu trữ, chỉ nên là một kỷ lục mỗi ngày. Tôi đã tìm ra điều tốt nhất để làm là tạo ra một NSDate được lưu trữ, nhưng loại bỏ thời gian & dữ liệu múi giờ.

Tôi có thể dễ dàng tạo NSDate mà không cần giờ, phút hoặc giây bằng cách sử dụng NSDateComponents hoặc NSDateFormatter. Tuy nhiên ngay cả khi tôi thiết lập múi giờ một cách rõ ràng để UTC hoặc không giây từ giờ, xuất ra một ngày tạo ra với NSLog() luôn có múi giờ địa phương của tôi như:

2009-07-29 00:00:00 +0100 

Có ai biết một cách tốt hơn để tạo NSDates không có thành phần thời gian? Hoặc có lẽ một cách tốt hơn để lưu trữ các ngày?

Trả lời

9

Quy tắc chung về lập trình tốt là luôn lưu trữ ngày trong UTC. Nó không quan trọng cho dù bạn sử dụng dữ liệu cốt lõi hay không; bạn vẫn sẽ phải làm một số công việc bởi vì các lớp ngày của Apple khá nhiều suck.

Ngày được biểu diễn nội bộ dưới dạng số giây kể từ ngày tham chiếu, tôi tin rằng, 1 tháng 1 năm 2001 00:00:00 (mặc dù ngày tham chiếu thực tế không quan trọng lắm). Điểm là, NSDate đối tượng luôn luôn là nguyên bản trong UTC. Nếu những ngày bạn đang nhận được trong tập tin CSV của bạn là địa phương, bạn sẽ cần phải làm một cái gì đó như thế này để có được thời gian tính theo giờ UTC:

NSDate *UTCDate = [localDate addTimeInterval:-[[NSTimeZone localTimeZone] secondsFromGMT]]; 

Sau đó, tôi muốn thiết lập thời gian để 00:00:00 . Bây giờ bạn đang lưu ngày, vào lúc nửa đêm, ở UTC. Đối với mục đích thuyết trình, bạn sẽ sử dụng cấu hình NSDateFormatter được định cấu hình theo múi giờ bạn chọn (múi giờ hệ thống là mặc định nếu bạn không chỉ định một) để hiển thị những ngày đó.

Múi giờ không thực sự quan trọng khi bạn chỉ giao dịch với ngày. Miễn là bạn đảm bảo đặt múi giờ trên NSDateFormatter thành UTC, bạn sẽ luôn hiển thị cùng ngày, bất kể múi giờ nào người dùng đã chọn trên thiết bị của mình.

Nếu bạn không thích giải pháp này, bạn luôn có thể lưu trữ ngày của mình ở định dạng thay thế. Bạn có thể sử dụng một số double hoặc int để lưu trữ ngày theo một số định dạng tùy chỉnh (ví dụ:số ngày kể từ ngày tham chiếu) hoặc thậm chí bạn có thể cuộn lớp của riêng mình để lập mô hình ngày chính xác theo cách bạn muốn và lưu trữ dưới dạng đối tượng NSData. Miễn là lớp thực hiện NSCoding, bạn có thể tuần tự hóa lớp đó thành đối tượng NSData trong Dữ liệu chính. Bạn chỉ cần đặt loại thuộc tính trong Dữ liệu cốt lõi thành "Biến đổi".

Bạn có nhiều tùy chọn ở đây và không có tùy chọn nào liên quan đến nỗ lực viết các truy vấn và cơ sở dữ liệu SQLite của riêng bạn.

+1

Cảm ơn rất nhiều. Tôi đã có nó được sắp xếp ngay bây giờ. Câu trả lời của bạn làm cho các chuyển đổi có ý nghĩa hơn và Peter Hosey dưới đây giải thích đầu ra NSLog. – Ben

2

Đối tượng NSDate sẽ luôn kết hợp ngày giờ - để trích dẫn tài liệu "đại diện cho [một] điểm duy nhất" và làm như vậy bằng cách lưu trữ giá trị thời gian kể từ ngày tham chiếu (bắt đầu từ ngày 1 tháng 1 năm 2001 tại GMT) , một lần nữa theo các tài liệu). Do đó bạn không thể có NSDate không biết thời gian trong ngày. Thay vì thử và lưu trữ ngày theo cách riêng của bạn, tôi vẫn sẽ sử dụng NSDate trong mô hình của bạn và xem xét thêm một cặp phương thức vào lớp thực thể của bạn, một trong số đó sẽ làm những gì bạn mô tả ở trên, đặt NSDate thành 00: 00:00 vào một ngày nhất định. Người kia chỉ có thể trả về ngày từ một NSDate theo định dạng ưa thích của bạn. Sau đó, chúng sẽ sử dụng trình lấy dữ liệu lõi và trình thiết lập để truy cập thuộc tính NSDate.

Bằng cách sử dụng NSDate, bạn đang sử dụng lớp mà dữ liệu chính có thể hoạt động với nguyên bản, nghĩa là bạn vẫn có thể dễ dàng sử dụng biến vị ngữ để lọc hoặc sắp xếp kết quả đã tìm nạp của bạn mà không phải suy nghĩ quá nhiều về nó.

+0

Cảm ơn bạn đã trả lời. Điều này vẫn để lại vấn đề về múi giờ. Ví dụ: Tôi lưu dữ liệu của mình vào tháng 7 tại Luân Đôn (GMT + 0100) và một người khác lưu dữ liệu đó vào Cupertino (GMT-0700). Hiện tại có sự khác biệt 8 giờ trong ngày được lưu trữ. Tôi nghĩ rằng nó có lẽ hiệu quả hơn chỉ để quay trở lại SQLite thô. – Ben

+0

Tôi không hiểu rõ vấn đề: ngày trong một NSDate được lưu trữ dưới dạng ngày tuyệt đối, giây kể từ 00:00:00 1/1/2001 * GMT *. Vì vậy, nếu hai người trong các múi giờ khác nhau lưu trữ ngày 'hiện tại' tại cùng một thời điểm, thì NSDate của họ giống hệt nhau. Múi giờ chỉ hoạt động khi truy xuất/hiển thị và trừ khi bạn nói NSDate nếu không nó sẽ đi cùng với múi giờ địa phương của hệ thống. Nói cách khác, nếu hai bộ dữ liệu của bạn được lưu trữ cùng lúc tại Luân Đôn và Cupertino, các ngày được lưu trữ giống nhau, không có sự khác biệt. – marramgrass

3

NSDate không có múi giờ. NSLog sử dụng múi giờ địa phương của bạn; nó nói +0100 vì đó là nơi bạn đang ở.

+0

Cảm ơn bạn. Tôi không biết rằng đó là NSLog sử dụng múi giờ địa phương. Sau khi bạn chỉ ra điều này, tôi đã chơi với ngày tháng và thời gian của hệ thống và một số chi tiết khác và giờ đây nó đã có ý nghĩa hơn nhiều. – Ben

+0

Tôi không hiểu số +0100. Nó chính xác là gì? –

+0

srikanth rongali: Chênh lệch múi giờ. Người hỏi là một giờ trước GMT: GMT + 0100. (Cặp chữ số sau là phút, do đó, múi giờ năm giờ rưỡi trước GMT sẽ là +0530.) –

Các vấn đề liên quan