2011-09-20 44 views
14

Tôi có đối tượng NSDate. Giả sử nó đại diện cho "1-10-2011"Nhận NSDate từ NSDate được điều chỉnh theo múi giờ

NSDate *date = [df dateFromString:@"2011-10-01 00:00:00"]; 

Ngày đó chuyển thành "2011-09-30 22:00:00" vì múi giờ của tôi.

Câu hỏi: Làm cách nào để nhận đối tượng Ngày mới đại diện cho "2011-10-01 00:00:00" trong múi giờ địa phương của tôi?

+0

thử \t [df setLocale: [NSLocale currentLocale]]; –

Trả lời

27

NSDate chỉ đại diện cho một điểm tuyệt đối trong thời gian . Nó không có khái niệm về múi giờ hoặc lịch. Khi bạn tạo một cá thể NSDate nó chỉ là một số giây kể từ ngày 1 tháng 1 năm 2001 GMT! Nó không quan trọng nếu bạn đang ở New York, Tokyo, Barcelona hoặc Jerusalem.

Ví dụ của bạn, bạn thể hiện NSDate dựa trên GMT, nhưng [date description] (được sử dụng trong NSLog) dịch nó vào giờ địa phương của bạn. Ở đó bạn có sự không phù hợp.

Vì vậy, có hai phần để xem xét:

1. NSDate tạo sử dụng NSCalendar và NSTimeZone

Nếu bạn đang tạo một ngày bằng tay bạn nên xác định lịch (năm 2012 tại Gregorian, nhưng 5772 bằng tiếng Hebrew) và múi giờ (22 giờ Luân Đôn, nhưng giờ 7 giờ Sydney).

// Use the user's current calendar and time zone 
NSCalendar *calendar = [NSCalendar currentCalendar]; 
[calendar setTimeZone: [NSTimeZone systemTimeZone]]; 

// Specify the date components manually (year, month, day, hour, minutes, etc.) 
NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init]; 
[timeZoneComps setHour:22]; 
[timeZoneComps setMinute:0]; 
[timeZoneComps setSecond:0]; 
// ... year, month, ... 

// transform the date compoments into a date, based on current calendar settings 
NSDate *date = [calendar dateFromComponents:timeZoneComps]; 

Tại thời điểm này lưu trữ điểm chính xác theo thời gian (tính bằng giây) thể hiện lịch hiện tại.

2. NSDate sản lượng sử dụng NSDateFormatter

Đối với một kiểm soát đầu ra của NSDate của bạn, bạn cần NSDateFormatter, được sử dụng để chuyển đổi ngày thành chuỗi.

Dựa trên Apple NSDateFormatter Class Reference tài liệu

Có rất nhiều thuộc tính bạn có thể nhận và thiết lập vào một ngày phong cách formatter ... Bạn được khuyến khích, tuy nhiên, không thay đổi các thiết lập cá nhân . Thay vào đó bạn nên chấp nhận các thiết lập mặc định thành lập ngày khởi và xác định định dạng sử dụng setDateStyle :, setTimeStyle:

Đây là đặc biệt quan trọng đối với đầu ra, đó là khác nhau cho mỗi miền địa phương. Theo mặc định, NSDateFormatter sẽ quan sát cài đặt ngôn ngữ của người dùng hiện tại. Vì vậy, cùng một NSD có thể là 22.11.2011 18:33:19 hoặc Nov 22, 2011 6:33:19 PM hoặc 2011-11-22 下午6:33:19 hoặc thậm chí २२-११-२०११ ६:३३:१९ अपराह्, tất cả cho cùng một đầu vào và có cùng mã.

Và mã:

// NSDate *date -> NSString *dateString 

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setDateStyle:NSDateFormatterMediumStyle]; 
[dateFormatter setTimeStyle:NSDateFormatterShortStyle]; 

// Medium style date, short style time => "Nov 23, 1937 3:30pm" 
NSString *dateString = [dateFormatter stringFromDate:date]; 

Hoặc bạn có thể biến nó bằng cách sử dụng phương pháp lớp localizedStringFromDate:dateStyle:timeStyle:

Tôi hy vọng điều này làm rõ vấn đề.

6

[NSDate date] trả về ngày bằng GMT.

Khi bạn nêu:

ngày đó chuyển thành "2011/09/30 22:00:00" vì múi giờ của tôi.

Có phải từ NSLog hoặc NSDateFormatter? Đừng dựa vào [date description] mà NSLog sử dụng, nó sẽ tính đến múi giờ địa phương của bạn, sử dụng NSDateFormatter. NSDateFormatter có phương thức setTimeZone.

Từ docs Apple trên [date description]:

Các đại diện không được bảo đảm duy trì liên tục qua phiên bản khác nhau của hệ điều hành. Để định dạng một ngày, bạn nên sử dụng một đối tượng ngày formatter thay