-[NSDateComponents components:fromDate:toDate] Frage

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • -[NSDateComponents components:fromDate:toDate] Frage

    Hallo,

    was ist mein Denkfehler? Ich würde bei diesem Code am Ende die Ausgabe: "The difference is 1 days" erwarten, bekomme aber "0 days":

    Quellcode

    1. NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];;
    2. NSDate *today = [NSDate dateWithString:@"2011-02-13 00:25:00 +0100"];
    3. NSDate *yesterday = [NSDate dateWithString:@"2011-02-12 23:50:00 +0100"];
    4. components = [gregorian components:NSDayCalendarUnit
    5. fromDate:today
    6. toDate:yesterday options:0];
    7. NSInteger days = [components day];
    8. NSLog (@"The difference is %ld days", days);
    Alles anzeigen


    Sample Projekt hängt an. Hat irgendjemand eine Idee?

    Alex
    The only thing that really worried me was the ether.
  • Erstens sind die Daten falschrum (außer Du wolltest "von heute bis gestern"), zweitens, laß DIr mal die Stunden und die Minuten ausgeben, der rundet ab. Um solche Probleme zu umgehen habe ich in einer meiner Standardkategorien ein "midnight" für NSDate und jag Daten immer erst dadurch, bevor ich sie miteinander vergleiche und ganze Tage erwarte.
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • Verstehe ich jetzt nicht

    vom 12.2.2011 23:50 bis zum 13.2.2011 00:25 sind es nunmal kein Tag, ja nichtmal 1 Stunde. Es sind lediglich 35 Minuten. Jedes andere Ergebnis würde ja ad absurdum führen.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • gritsch schrieb:

    wenn du die tage haben willst, nimm doch einfach die differnez der timeintervalle und dividiere dann.

    so in der art:

    unsigned tage = ceil((time1-time2) / 60 / 60 / 24);
    Funktioniert halt nicht bei der Umstellung von Sommer- auf Winterzeit (da gibt's nen Tag zuviel) oder bei Wechsel von Zeitzonen oder im Oktober 1582 oder wenn andere unvorhergesehene Sachen auftreten.
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • seb2 schrieb:

    gritsch schrieb:

    wenn du die tage haben willst, nimm doch einfach die differnez der timeintervalle und dividiere dann.

    so in der art:

    unsigned tage = ceil((time1-time2) / 60 / 60 / 24);
    Funktioniert halt nicht bei der Umstellung von Sommer- auf Winterzeit (da gibt's nen Tag zuviel) oder bei Wechsel von Zeitzonen oder im Oktober 1582 oder wenn andere unvorhergesehene Sachen auftreten.


    sicher?
  • gritsch schrieb:

    seb2 schrieb:

    gritsch schrieb:

    wenn du die tage haben willst, nimm doch einfach die differnez der timeintervalle und dividiere dann.

    so in der art:

    unsigned tage = ceil((time1-time2) / 60 / 60 / 24);
    Funktioniert halt nicht bei der Umstellung von Sommer- auf Winterzeit (da gibt's nen Tag zuviel) oder bei Wechsel von Zeitzonen oder im Oktober 1582 oder wenn andere unvorhergesehene Sachen auftreten.


    sicher?
    In die Falle mit der Zeitumstellung bin ich höchstpersönlich getappt, in den anderen Fällen wäre es mir das Risiko nicht wert, mich drauf zu verlassen und ich nehme die paar Zeilen extra gerne in Kauf.
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • seb2 schrieb:

    gritsch schrieb:

    seb2 schrieb:

    gritsch schrieb:

    wenn du die tage haben willst, nimm doch einfach die differnez der timeintervalle und dividiere dann.

    so in der art:

    unsigned tage = ceil((time1-time2) / 60 / 60 / 24);
    Funktioniert halt nicht bei der Umstellung von Sommer- auf Winterzeit (da gibt's nen Tag zuviel) oder bei Wechsel von Zeitzonen oder im Oktober 1582 oder wenn andere unvorhergesehene Sachen auftreten.


    sicher?
    In die Falle mit der Zeitumstellung bin ich höchstpersönlich getappt, in den anderen Fällen wäre es mir das Risiko nicht wert, mich drauf zu verlassen und ich nehme die paar Zeilen extra gerne in Kauf.


    es kommt ja immer drauf an für was man den code verwendet und was man überhaupt machen will.
    die frage ist ja auch "was versteht man unter einem tag?"

    ist die differenz vom 27. März 2011 um 0:00 auf den 28. März 20011 um 24:00 genau ein tag? will man das als 1 tag darstllen oder als 1 tag und ein paar zerquetschte (oder eben bisschen weniger als 1 tag... kann grad net so denken...)

    immer wieder sonntag...
  • gritsch schrieb:

    es kommt ja immer drauf an für was man den code verwendet und was man überhaupt machen will.
    die frage ist ja auch "was versteht man unter einem tag?"
    Ungefragt völlig richtig.

    Ich hab es übrigens eben mal ausprobiert, NSCalendar kennt die Umstellung auf den Gregorianischen Kalender weder im Oktober 1582 noch im September 1752. Wahrscheinlich weil ich ihn als Gregorianischen Kalender initialisiert habe und er dann die Daten vor der Umstellung auch schon in seiner Zeitrechnung annimmt.
    Aber ich denke, die wenigsten von uns haben mit Daten in dem Zeitraum zu tun.
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • Also, Sebastian hat wahrscheinlich schon die vollständige Antwort gegeben, aber ich denke ich muss doch erklären, was ich vorhabe:

    Ich will wissen, ob zwei Ereignisse auf dem selben (Tages-)Kalenderblatt liegen.

    Und ich weiss nicht, wie Eure Kalenderblätter so aussehen, aber auch wenn die Ereignisse im Beispiel nur wenige Minuten auseinanderliegen, ist eins am "Samstag" und das andere am "Sonntag". In meiner Logik ist die Differenz daher genau "ein Tag" (o.B.d.A., es kann auch "minus ein Tag" sein).

    Mein Fehler war, dass ich angenommen hatte, NSCalendar würde mit die Komponenten auch in der entsprechenden Auflösung zurückgeben, aber wie Sebastian schon geschrieben hat, es wird abgerundet.

    Das Umrechnen auf Mitternacht scheint eine gute Lösung zu sein, dann kann ich tatsächlich einfach die Differenz der Intervalle vergleichen.

    Aber es wundert mich etwas, dass das Framework wirklich keine Funktion für diese, wie ich finde, ziemlich grundlegende Funktionalität haben sollte. Ist das wirklich so?

    Alex
    The only thing that really worried me was the ether.
  • Wie wärs mit

    Quellcode

    1. -(BOOL)comapreDatesFrom:(NSDate*)fromDate To:(NSDate*)toDate
    2. {
    3. NSDateFormatter *dform=[[NSDateFormatter alloc] init];
    4. [dform setDateFormat:@"dd.mm.yyyy"];
    5. if( [[dform stringFromDate:fromDate] compare:[dform stringFromDate:toDate]]==NSORDEREDSAME)
    6. {
    7. // gleicher Tag
    8. }
    9. [dforn release];
    10. }
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Wie wärs mit

    Quellcode

    1. -(BOOL)comapreDatesFrom:(NSDate*)fromDate To:(NSDate*)toDate
    2. {
    3. NSDateFormatter *dform=[[NSDateFormatter alloc] init];
    4. [dform setDateFormat:@"dd.mm.yyyy"];
    5. if( [[dform stringFromDate:fromDate] compare:[dform stringFromDate:toDate]]==NSORDEREDSAME)
    6. {
    7. // gleicher Tag
    8. }
    9. [dforn release];
    10. }


    wenn man die punkte noch weglässt kann man sich einen integer aus dem string holen und damit vergleichen etc.
  • ich hatte das problem auch schon mal und dann so gelöst ...

    Quellcode

    1. - (BOOL)nsm_isSameDate:(NSDate *)aDate{
    2. NSDateComponents *compsA = [[NSCalendar currentCalendar]
    3. components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:self];
    4. NSDateComponents *compsB = [[NSCalendar currentCalendar]
    5. components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:aDate];
    6. return [compsA year] == [compsB year] &&
    7. [compsA month] == [compsB month] &&
    8. [compsA day] == [compsB day];
    9. }
  • Die Lösung über Components ist ganz sicher die Sauberste:

    1) Rechnen funktioniert offensichtlich nicht, da es auch auf die "Lage" des Zeitabstandes ankommt.

    2) Sowohl diese Lösung als auch andere haben das Problem, dass sie von einem einigermaßen westlichen Zeitkalender ausgehen. Aber wer genau sagt denn, dass eine Stunde 60 Minuten hat usw.?

    3) Mit der Mitternacht habe ich deshalb etwas etwas klitzekleine Probeme (paranoid!), weil IIRC manchmal um Mitternacht vom 31.12. auf den 1.1. gerne mal gefummelt wird. Mittag – oder ganz einfach nur 1 Stunde – scheint mir etwas robuster. (Dürfte aber mutmaßlich völlig scheißegal sein.)
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Amin Negm-Awad schrieb:

    Die Lösung über Components ist ganz sicher die Sauberste:

    1) Rechnen funktioniert offensichtlich nicht, da es auch auf die "Lage" des Zeitabstandes ankommt.

    2) Sowohl diese Lösung als auch andere haben das Problem, dass sie von einem einigermaßen westlichen Zeitkalender ausgehen. Aber wer genau sagt denn, dass eine Stunde 60 Minuten hat usw.?

    3) Mit der Mitternacht habe ich deshalb etwas etwas klitzekleine Probeme (paranoid!), weil IIRC manchmal um Mitternacht vom 31.12. auf den 1.1. gerne mal gefummelt wird. Mittag – oder ganz einfach nur 1 Stunde – scheint mir etwas robuster. (Dürfte aber mutmaßlich völlig scheißegal sein.)


    für das was er will sind die Components wohl nicht das richtige würd ich sagen...
  • gritsch schrieb:

    für das was er will sind die Components wohl nicht das richtige würd ich sagen...
    Wie Amin denke ich auch daß das die sauberste Lösung ist. Die Schaltsekunden vom 31.12. auf den 1.1. werden jedes Jahr nur nach Bedarf eingefügt -- abhängig vom Eiern der Erde um ihr eigene Achse, dieses Jahr beispielsweise überhaupt nicht -- und davon wissen die DateComponents nichts. Aber was er im Endeffekt nutzt ist Alex' Sache, des Rätsels Lösung haben wir lange ergründet und streiten und nur noch darum, wessen Ansatz für einen unterschiedlichen Zweck in wessen Augen besser oder zuverlässiger ist.

    Ach herrlich. :D
    if (!exit(-1)) fprintf(stderr, "exit call failed. Program will continue\n");
  • gritsch schrieb:

    Amin Negm-Awad schrieb:

    Die Lösung über Components ist ganz sicher die Sauberste:

    1) Rechnen funktioniert offensichtlich nicht, da es auch auf die "Lage" des Zeitabstandes ankommt.

    2) Sowohl diese Lösung als auch andere haben das Problem, dass sie von einem einigermaßen westlichen Zeitkalender ausgehen. Aber wer genau sagt denn, dass eine Stunde 60 Minuten hat usw.?

    3) Mit der Mitternacht habe ich deshalb etwas etwas klitzekleine Probeme (paranoid!), weil IIRC manchmal um Mitternacht vom 31.12. auf den 1.1. gerne mal gefummelt wird. Mittag – oder ganz einfach nur 1 Stunde – scheint mir etwas robuster. (Dürfte aber mutmaßlich völlig scheißegal sein.)


    für das was er will sind die Components wohl nicht das richtige würd ich sagen...

    Genau.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?