1x mal im Halbjahr if ausführen

  • Eine Instanz von NSDate gibt /immer/ einen /Zeitpunkt/ an, niemals einen Zeitraum (Tag). Wen einen Die Tageszeit nicht interessiert, setzt man sie auf 0. Das wäre der 24.10.2012 00:00.

    -description von NSDate gibt die Zeit als UTC aus. UTC verhält sich zu unserer Zeit - 2h.

    Mit anderen Worten: Was da steht /ist/ 24.10.2012, 00:00 /MEZ/
    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"?
  • Um ein NSDate für den Anfang des gleichen Tages zu erhalten kannst Du die NSCalendar Methode rangeOfUnit:startDate:interval:forDate: mit der Unit NSDayCalendarUnit verwenden.

    Um zu testen ob der aktuelle Tag der letzte Tag eines Monats ist, wäre folgendes denkbar:

    Quellcode

    1. @implementation NSCalendar (LastDayOfMonth)
    2. - (BOOL)date:(NSDate*) isLastDayOfMonth:(NSInteger)month
    3. {
    4. NSDateComponents * comps = [self components:(NSDayCalendarUnit | NSMonthCalendarUnit)
    5. fromDate:date];
    6. if ([comps month] != month)
    7. return NO;
    8. NSRange * daysInMonthRange = [self rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date]
    9. return ([comps day] == NSMaxRange(daysInMonthRange) - 1U )
    10. }
    11. @end
    Alles anzeigen
  • Mit einem einfachen || solltest Du dir dass aber dann doch selbst zusammenbauen können. Eine entsprechende Methode zu NSCalendar hinzuzufügen macht aber definitiv keinen Sinn, da der Begriff Halbjahr in einigen Kalendern schon keinen Sinn macht.

    Aber selbst wenn Du es als eigene Methode oder Funktion haben willst ist das ganze doch trivial durch Modifikation des ersten ifs zu ändern.

    @Amin: Bei deiner Methode zum entfernen der Uhrzeit hab ich dann doch Bauchschmerzen. Wo nimmt denn das dateFromComponents die Era, die Zeitzone und Co. her? Ich vermute ja, dass es die einfach von [NSDate date] ableitet und das ist nicht OK.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Snoxxi ()

  • Snoxxi schrieb:

    @Amin: Bei deiner Methode zum entfernen der Uhrzeit hab ich dann doch Bauchschmerzen. Wo nimmt denn das dateFromComponents die Era, die Zeitzone und Co. her? Ich vermute ja, dass es die einfach von [NSDate date] ableitet und das ist nicht OK.


    Er hat JEHOVA gesagt!!!

    SCNR

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Ich habs jetzt so gemacht und es funktioniert:

    Quellcode

    1. unsigned uhrzeitsetzen = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
    2. NSDateComponents *compbeginn = [gregorian components:uhrzeitsetzen fromDate:beginn];
    3. [compbeginn setSecond:0];
    4. [compbeginn setMinute:0];
    5. [compbeginn setHour:0];
    6. beginn = [gregorian dateFromComponents:compbeginn];
    7. NSDateComponents *compende = [gregorian components:uhrzeitsetzen fromDate:ende];
    8. [compende setSecond:0];
    9. [compende setMinute:0];
    10. [compende setHour:0];
    11. ende = [gregorian dateFromComponents:compende];
    Alles anzeigen
    Ich bin gegen Signaturen!!!
  • Sorry, die Antwort kommt etwas spät, aber:

    Ist das die Zinssache aus dem letzten Post? Dann würde die Daten gar nicht vergleichen, sondern in einer äußeren Schleife (bzw. Methode) die Halbjahre durchlaufen und in einer inneren Schleife (bzw. Methode) die Tage innerhalb des Halbjahres. So musst Du nicht mehr jeden Tag vergleichen, es wird nur noch das Nötige gemacht und es ist sehr übersichtlich.
    Multigrad - 360°-Produktfotografie für den Mac
  • Solange wie Du mit Daten aus der gleichen Zeitzone arbeitest - und dein Program zur Berechnung der Verzugszinsen dürfte das tun - ist der Code vollkommen OK. Nur wenn Du z.B. mit Daten aus verschieden Zeitzonen arbeitest wird es kritisch. Nur mal so zum Spass könntest Du ja mal testen was deine Routine bei einem Vergleich von beginn = 1.1.2012 23:02 UTC (+0000) und ende = 2.1.2012 00:02 MEZ(+0001) liefert. Wenn dein Code korrekt ist, dann sollten beginn und ende am gleichen Tag liegen.

    Nach einem bisschen Nachdenken, muss ich mich korrigieren. NSDate selbst kennt gar keine Zeitzone, die kommt erst durch den NSCalendar hinzu, wenn man für beide den gleichen Calendar inkl. Zeitzone verwendet, dann sollte alles Stimmen. Nichts desto trotz empfielt Apple ein anderes vorgehen sieh z.B. Listing 13.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Snoxxi ()

  • Snoxxi schrieb:

    Mit einem einfachen || solltest Du dir dass aber dann doch selbst zusammenbauen können. Eine entsprechende Methode zu NSCalendar hinzuzufügen macht aber definitiv keinen Sinn, da der Begriff Halbjahr in einigen Kalendern schon keinen Sinn macht.

    Aber selbst wenn Du es als eigene Methode oder Funktion haben willst ist das ganze doch trivial durch Modifikation des ersten ifs zu ändern.

    @Amin: Bei deiner Methode zum entfernen der Uhrzeit hab ich dann doch Bauchschmerzen. Wo nimmt denn das dateFromComponents die Era, die Zeitzone und Co. her? Ich vermute ja, dass es die einfach von [NSDate date] ableitet und das ist nicht OK.

    1. Deine Methode ist ein Convenience-Methode, die nichts anderes macht.
    2. Die Era kannst du ja genau so übernehmen wie alles andere. Wir hatten hier aber schon eingeschränkt, dass wir uns im Diesseits der Zeit bewegen. Aber wer will, kann es ja machen.
    3. Ein Date hat keine Zeitzone. Wie sollte es die haben und wieso sollte es die haben? Daher wird die auch nicht von NSDate abgeleitet. In meinem Beispiel wird die Zeitzone nicht verändert. Man kan aber auch die beliebig setzen, wenn man will. Will der OP aber sicherlich nicht.
    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"?
  • Snoxxi schrieb:

    Solange wie Du mit Daten aus der gleichen Zeitzone arbeitest - und dein Program zur Berechnung der Verzugszinsen dürfte das tun - ist der Code vollkommen OK. Nur wenn Du z.B. mit Daten aus verschieden Zeitzonen arbeitest wird es kritisch. Nur mal so zum Spass könntest Du ja mal testen was deine Routine bei einem Vergleich von beginn = 1.1.2012 23:02 UTC (+0000) und ende = 2.1.2012 00:02 MEZ(+0001) liefert. Wenn dein Code korrekt ist, dann sollten beginn und ende am gleichen Tag liegen.

    Die Zeitzone ist eine Eigenschaft des Kalenders, nicht das Dates. (Siehe oben: Wieso sollte das eine EIgenschaft des Dates sein? Ein Zeitpunkt in verschiedenen Ländern ist immer noch ein Zeitpunkt. Er wird nur dort anders benannt.)
    Er benutzt zwei Kalender (genau genommen 4, aber jeweils 2 Mal denselben.) Wenn er Zeitzonen berücksichtigen will, muss er nichts anderes machen, als die Zeitzone zu setzen. Und das klingt ebenso nachvollziehbar wie richtig.
    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"?
  • beage schrieb:

    Ich habs jetzt so gemacht und es funktioniert:

    Quellcode

    1. unsigned uhrzeitsetzen = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
    2. NSDateComponents *compbeginn = [gregorian components:uhrzeitsetzen fromDate:beginn];
    3. [compbeginn setSecond:0];
    4. [compbeginn setMinute:0];
    5. [compbeginn setHour:0];
    6. beginn = [gregorian dateFromComponents:compbeginn];
    7. NSDateComponents *compende = [gregorian components:uhrzeitsetzen fromDate:ende];
    8. [compende setSecond:0];
    9. [compende setMinute:0];
    10. [compende setHour:0];
    11. ende = [gregorian dateFromComponents:compende];
    Alles anzeigen

    Du kannst dir nicht nur das Setzen auf 0 sparen, du solltest es dir sparen. Mutmaßlich funktioniert es aber bei dir.
    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:

    Ein Date hat keine Zeitzone. Wie sollte es die haben und wieso sollte es die haben? Daher wird die auch nicht von NSDate abgeleitet. In meinem Beispiel wird die Zeitzone nicht verändert. Man kan aber auch die beliebig setzen, wenn man will. Will der OP aber sicherlich nicht.


    Sofern es um das Programm zur Berechnung der Verzugszinsen geht würde ich im aber dazu Raten die Zeitzone zu berücksichtigen. Den die Zinsen hängen ja nicht vom Aufenthaltsort des Rechners ab. Ein, in Deutschland, gesetztes Startdatum 1.1.2012 soll ja auch in England noch der 1.1.2012 sein und nicht der 31.12.2011.
  • @Snoxxi: Das ist doch aber völlig irrelevant. Das Datum wird ja vom User eingebeben. Der Verzug beginnt an dem Tag, an dem die Rechnung überfällig wird, also am Tag danach und endet am eingegebenen Datum, im Normalfall der Zahlungstag. Da ist es doch völlig egal, ob der User in Deutschland, England oder Timbuktu wohnt, oder? Es kann auch sein, dass ich mich irre, aber wenn ich explizit das eingegebene Datum zum rechnen nehme und die Uhrzeit auf 00:00:00 setze, was soll dann in England anders sein?
    Ich bin gegen Signaturen!!!
  • Snoxxi schrieb:

    Amin Negm-Awad schrieb:

    Ein Date hat keine Zeitzone. Wie sollte es die haben und wieso sollte es die haben? Daher wird die auch nicht von NSDate abgeleitet. In meinem Beispiel wird die Zeitzone nicht verändert. Man kan aber auch die beliebig setzen, wenn man will. Will der OP aber sicherlich nicht.


    Sofern es um das Programm zur Berechnung der Verzugszinsen geht würde ich im aber dazu Raten die Zeitzone zu berücksichtigen. Den die Zinsen hängen ja nicht vom Aufenthaltsort des Rechners ab. Ein, in Deutschland, gesetztes Startdatum 1.1.2012 soll ja auch in England noch der 1.1.2012 sein und nicht der 31.12.2011.

    Für Zinsen ist das eigentlich ziemlich gleichgültig, da diese aus einer Differenz berechnet werden. Sind beide Daten normiert – und sei es auf 17:52:41 –, so ist es immer eine ganztägige Differenz.

    Aber wie dem auch sei: Mein Ansatz hat nicht das geringste damit zu tun, ob man Zeitzonen berücksichtigen will oder nicht. Er kann es machen, er kann es lassen, wie er will. Denn Zeitzonen sind immer noch keine Eigenschaften von Dates.

    Er muss dazu nur die Zeitzone wie gewünscht setzen.

    Mit GMT:

    Quellcode

    1. NSDate *now = [NSDate date];
    2. NSLog( @"%@", now);
    3. NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    4. gregorian.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
    5. NSDateComponents *components = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:now];
    6. NSDate *today = [gregorian dateFromComponents:components];
    7. NSLog( @"%@", today );
    Alles anzeigen

    2012-10-25 20:33:31.812 TimeKiller[760:403] 2012-10-25 18:33:31 +0000
    2012-10-25 20:33:31.813 TimeKiller[760:403] 2012-10-25 00:00:00 +0000 // Das ist nicht die lokale Zeitdarstellung, sondern die UTC für 25.10.2012 00.00 Uhr (GMT)

    Mit EST:

    Quellcode

    1. NSDate *now = [NSDate date];
    2. NSLog( @"%@", now);
    3. NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    4. gregorian.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"EST"];
    5. NSDateComponents *components = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:now];
    6. NSDate *today = [gregorian dateFromComponents:components];
    7. NSLog( @"%@", today );
    Alles anzeigen

    2012-10-25 20:35:20.002 TimeKiller[775:403] 2012-10-25 18:35:19 +0000
    2012-10-25 20:35:20.006 TimeKiller[775:403] 2012-10-25 04:00:00 +0000 // Das ist nicht die lokale Zeitdarstellung, sondern die UTC für 25.10.2012 00.00 Uhr (EST)

    Und so weiter,

    und so fort.

    Und genau so ist das gedacht: Die Timezone ist eine Eigenschaft des Kalenders und nicht der Ziet. Ist ist auch logisch richtig und von Apple mit Mac OS X 10.4 richtig erkannt worden.
    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"?
  • Gilt das Auch für Verzugszinsen?

    Soweit ich das kenne müssen Verzugszinsen Tagesgenau - das geht ohne Zeitzone - berechnet werden, allerdings gibt es für die Zinssätze Stichtage jeweils zum 1.1 und zum 1.7 eines Jahres können selbige von der Bundesbank geändert werden. Deshalb ja vermutlich auch die Frage nach dem einmal im Halbjahr

    Jetzt mal als Beispiel: Der Starttag der Verzinsung ist der 1.1.2012. Dieser wird unter Nutzung der Deutschen Zeitzone MEZ eigegeben wobei die Stunden auf Uhrzeit auf 00:00:00 gesetzt wird. Das zugehörige NSDate wird dass dann als 31.12.2011 23:00 GMT gespeichert, da ja NSDate keinerlei Infos zur Zeitzone enthält. Wenn ich jetzt in England Urlaub mache und die Zeitzone angepasst wird, dann wird das Programm das Datum korrekt als 31.12.2011 anzeigen und diesen Tag bei der Berechnung mit dem Zinssatz vom 1.7.2011 verzinsen und nicht den Zinssatz vom 1.1.2012 nehmen. Sollten die Daten jetzt noch mal "korrigiert auf 0:00:00 Uhr" gespeichert werden, dann wandert der ganze Block bei der Rückkehr einen Tag nach vorne.

    Wenn natürlich keine Stichtagseffekte vorhanden sind, dann kann man die Zeitzone ignorieren. Das gleich geilt, wenn man die Daten nicht speichert auch dann gibt es kein Problem.