3

意味がないように見える、本当にイライラする問題があります。2つの日付の間の年数を取得しようとしています。これが私のコードです。

// Initialize variable to store calendar
NSCalendar *gregorian = [[NSCalendar alloc]  initWithCalendarIdentifier:NSGregorianCalendar];

// Break out date to year component
NSDateComponents *Components = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit
                                            fromDate:startDate
                                              toDate:endDate
                                             options:0];

// Debugging code
NSLog(@"Debug start date = %@",startDate);
NSLog(@"Debug end date = %@", endDate);
NSLog(@"Debug year = %d",[Components year]);
NSLog(@"Debug month = %d",[Components month]);
NSLog(@"Debug day = %d", [Components day]);
NSLog(@"Debug hours = %d",[Components hour]);
NSLog(@"Debug minutes = %d", [Components minute]);
NSLog(@"Debug seconds = %d", [Components second]);

[gregorian release];

// Check which component to extract and return value accordingly
// Defaults to month for now
if ([datecomponent isEqualToString:@"year"]) {
    return [Components year];
}
else {
    return [Components month];
}

開始日と終了日は、別の場所で UIDatePickers によって設定されます。彼らはデフォルトで10年離れています。終了日を制御する UIDatePicker に戻り、それを最大 1 年前に移動します。問題が発生し始めます。これは、終了日を元の日付に戻した後に表示される NSLog の例です。他の場所では 10 年と 0 が表示されるはずですが、時間が 1 秒ありません。

Debug start date = 2011-08-15 15:55:07 +0000
Debug end date = 2021-08-15 15:55:07 +0000
Debug year = 9
Debug month = 11
Debug day = 30
Debug hours = 23
Debug minutes = 59
Debug seconds = 59

開始日と終了日は、それらの間の 10 年間保存されているように見えますが、何らかの理由で 1 秒遅れています。誰かが理由を知っていますか?

前もって感謝します!

追加した

これが、2つの日付を初期化して保存した方法です。

開始日は viewWillAppear メソッドにあります。

- (void)viewWillAppear:(BOOL)animated {
    if ([managedObject valueForKeyPath:self.keypath] != nil)
        [self.datePicker setDate:[managedObject
                                  valueForKeyPath:keypath] animated:YES];
    else
        [self.datePicker setDate:[NSDate date] animated:YES];
    [self.tableView reloadData];

    [super viewWillAppear:animated];

}

同じクラスが終了日にも使用されますが、NSManagedObject のカスタム サブクラスに次のコードも追加しました。

- (void)awakeFromInsert {
    [super awakeFromInsert];

    // Set default date of registration to be today's date
    self.startdate = [NSDate date];

    NSDate *today = [[NSDate alloc] init]; // I also tried to equate this to self.startdate but there is no difference
    NSCalendar *gregorian = [[NSCalendar alloc]     initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
    [offsetComponents setYear:10];
    self.enddate = [gregorian dateByAddingComponents:offsetComponents toDate:today     options:0];

}

これは何か問題を引き起こしたでしょうか?はいの場合、デバッグで開始日と終了日が時間を含めてまったく同じに表示されるのはなぜですか?

4

3 に答える 3

1

1 つの ViewController に 2 つの UIDatePickers を持つ単純なプロジェクトを作成しました。各 UIDatePicker を参照日付に初期化し、アクション メソッドを設定して、2 つの UIDatePicker のいずれかが変更されるたびに日付の差を計算します。コードをそのメソッドに挿入し、iPhone シミュレーターでテストしました。その結果、コードは正確に 10 年を出力します。

2011-08-15 11:18:44.225 test[1004:b303] Debug start date = 2001-01-01 00:00:00 +0000
2011-08-15 11:18:44.225 test[1004:b303] Debug end date = 2011-01-01 00:00:00 +0000
2011-08-15 11:18:44.226 test[1004:b303] Debug year = 10
2011-08-15 11:18:44.226 test[1004:b303] Debug month = 0
2011-08-15 11:18:44.227 test[1004:b303] Debug day = 0
2011-08-15 11:18:44.227 test[1004:b303] Debug hours = 0
2011-08-15 11:18:44.227 test[1004:b303] Debug minutes = 0
2011-08-15 11:18:44.228 test[1004:b303] Debug seconds = 0

それらを使用する前に UIDatePickers を同時に初期化しましたか? デフォルトでは、UIDatePicker は作成された日付に初期化されます (ピッカーに年、月、日しか表示されていない場合でも、これには時間、分、秒などが含まれます)。

この不一致を別の方法で導入している可能性はありますか? おそらく、日付に対して他の計算や操作を行っていますか?

編集:

追加したコードでは、別の日付オブジェクトからではなく、startdate から enddate を参照する必要があります。違いはないとあなたが言ったことは知っていますが、今日と開始日が同じ値になると仮定するよりも、開始日を使用する方が良い形式です。

考慮すべきもう1つのことは、あなたsetStartDate:setEndDate:方法です。これらのセッター メソッドでは、必要のない精度を 0 に丸めることをお勧めします。ユーザーが日よりも正確なものを設定することを許可しない場合は、より高い精度を 0 に設定します。これにより、2 つの日付の間に時間、分、または秒が残されることはありません。

于 2011-08-15T17:57:03.397 に答える
0

さまざまなシナリオをかなりいじった後、これが私が問題を解決した方法です。

1)日付の違いを見つけるコードは、いくつかの独立した関係者によって問題なくチェックアウトされるため、問題の原因としてそれを排除しました。

2) アプリ内の日付を変更しようとするコードを削除しましたが、最初はそこにあるはずではありませんでした。

3) 開始日と終了日を作成するときに時間も初期化して、データベースにエントリを作成するときに基づいて恣意的な時間にならないようにします。

開始日を初期化するコード スニペットを次に示します。

NSDate *now = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *settomidnight = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:now];
[settomidnight setHour:0];
[settomidnight setMinute:0];
[settomidnight setSecond:0];
startdate = [calendar dateFromComponents:settomidnight];

これにより、NSLog から、時間が 16:00 +0000 に設定されていることがわかります (タイムゾーンに変換した後の真夜中です)。問題は解消され、1 秒も失うことはなくなりました。

私を正しい道に導いてくれたすべての人に感謝します!

于 2011-08-19T06:33:18.620 に答える