Phân biệt Gregorian Calendar và Japanese Calendar
Bài đăng này đã không được cập nhật trong 9 năm
Khi thực hiện chuyển từ chuỗi ký tự sang NSDate
và ngược lại, nếu không lưu ý sẽ có thể phát sinh vấn đê do người sử dụng setting calendar trong máy (đặc biệt với các nước sử dụng lịch riêng như Nhật Bản, Trung Quốc v.vv..).
Chuyển từ chuỗi ký tự sang NSDate
Trước hết chúng ta sẽ chia nhỏ chuỗi ký tự ra và gán giá trị cho NSDateComponents
, sau đó sẽ tạo biến kiểu NSDate
.
NSDateComponents *comps = [[NSDateComponents alloc] init];
NSDate *date;
@try {
[comps setYear: 2012]; // Year
[comps setMonth: 4]; // Month
[comps setDay: 1]; // Day
[comps setHour: 15]; // Hour
[comps setMinute: 0]; // Minute
[comps setSecond: 0]; // Second
}
@catch (NSException *exception) {
NSLog(@"error was cought at NSDateComponents set values");
}
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendar *gregorianCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendar *japaneseCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSJapaneseCalendar];
date = [calendar dateFromComponents:comps]; // currentCalendar
NSLog(@"calendar date[%@]", date);
date = [gregorianCalendar dateFromComponents:comps]; // NSGregorianCalendar
NSLog(@"gregorianCalendar date[%@]", date);
date = [japaneseCalendar dateFromComponents:comps]; // NSJapaneseCalendar
NSLog(@"japaneseCalendar date[%@]", date);
Kết quả như bảng dưới đây:
Gregorian Calendar | Japanese Calendar | |
---|---|---|
currentCalendar | 2012-04-01 06:00:00 +0000 | 2012-04-01 06:00:00 +0000 |
NSGregorianCalendar | 2012-04-01 06:00:00 +0000 | 0024-04-01 06:00:00 +0000 |
NSJapaneseCalendar | 4000-04-01 06:00:00 +0000 | 2012-04-01 06:00:00 +0000 |
Nhìn qua thì thấy có vẻ currentCalendar không có vấn đề gì, nhưng nên nhớ khi setting sử dụng Japanese Calendar thì "năm 2012" ở đây là Bình Thành năm 2012 tương đương với năm 4000 đấy nhé (sohai)
Tóm lại, nếu muốn sử dụng NSJapaneseCalendar
thì phải nhập số năm tương ứng với lịch Nhật, nếu không sẽ xảy ra sai số ngay.
Chuyển từ NSDate
sang chuỗi ký tự
NSDateFormatter *format;
NSString *str;
NSDate *date = [NSDate date]; // lấy current date
format = [[NSDateFormatter alloc]init];
[format setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"ja_JP"]];
[format setDateFormat:@"yyyy-MM-dd"];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendar *japaneseCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSJapaneseCalendar];
[format setCalendar:calendar]; // currentCalendar
str = [format stringFromDate:date];
NSLog(@"currentCalendar date[%@]", str);
[format setCalendar:gregorianCalendar]; // NSGregorianCalendar
str = [format stringFromDate:date];
NSLog(@"NSGregorianCalendar date[%@]", str);
[format setCalendar:japaneseCalendar]; // NSJapaneseCalendar
str = [format stringFromDate:date];
NSLog(@"japaneseCalendar date[%@]", str);
Kết quả như sau:
Gregorian Calendar | Japanese Calendar | |
---|---|---|
currentCalendar | 2012-03-31 | 0024-03-31 |
NSGregorianCalendar | 2012-03-31 | 2012-03-31 |
NSJapaneseCalendar | 0024-03-31 | 0024-03-31 |
Rõ ràng là khi muốn hiển thị cho Gregorian Calendar thì nên sử dụng NSGregorianCalendar
, còn khi muốn hiển thị cho Japanese Calendar thì nên sử dụng NSJapaneseCalendar
.
currentCalendar khi setting sử dụng Gregorian Calendar thì xử lý như NSGregorianCalendar
, khi setting sử dụng Japanese Calendar thì xử lý như NSJapaneseCalendar
, tuy nhiên trong trường hợp app sử dụng Gregorian Calendar mà user lại setting sử dụng Japanese thì sẽ xuất hiện lỗi ngay (năm 4000 chả hạn).
Ở các nước Âu Mỹ thì người dùng có lẽ chả thay đổi lịch bao giờ thì sử dụng như currentCalendar thì ko vấn đề, nhưng cần phải hạn chế lỗi này ở các app dành cho thị trường Nhật Bản, Trung Quốc..
Source: iPhoneで和暦表示設定のとき、日付や曜日がずれる
All rights reserved