PBDate.m


max21 Unternehmensgruppe
#import "Aprica.h"
//	Aprica2
//	copyright Pirmin Braun 1997-2007 - pirmin@pirmin.de
//	all Rights reserved;
#define DAYS -1
#define WORKDAYS 0
#define MONTHS 1
#define YEARS 2
#define QUARTERS 3
#define WEEKS 4
#define EXACT -1
#define FIRST 0
#define LAST 1
@implementation PBDate
- (void)erster;
{
    long l = [self dateAsLong]/100;
    l *=100;
    [self setLong:l+1];	//1. des Monats
}
- (void)ensureWorkday;
{
//sa u. so ueberspringen
    if([self weekday]==6){
        [self addDay:2];
        return;
    }
    if([self weekday]==0){
        [self addDay:1];
        return;
    }
}
- (BOOL)isWorkday;
{
    int wd = [self weekday];
    if(wd == 6)return NO;
    if(wd == 0)return NO;
    return (![_APP isFeiertag:[self dateAsDBString]]);
}
- (int)age;
{
// jahre
        PBDate *d1;
        long l;
        d1 = [[PBDate alloc]init];
        [d1 setCurrentDay];
        l = ([d1 dateAsLong]-[self dateAsLong])/10000;
        [d1 release];
        return l;
}
- (int)age_days;
{
// Tage ###
        PBDate *d1;
        long l;
        d1 = [[PBDate alloc]init];
        [d1 setCurrentDay];
        l = ([d1 dateAsLong]-[self dateAsLong])/10000;
        [d1 release];
        return l;
}
- (BOOL)isHistory;
{
        PBDate *d1;
        long l;
        d1 = [[PBDate alloc]init];
        [d1 setCurrentDay];
        l = ([d1 dateAsLong]-[self dateAsLong]);
        [d1 release];
        return l>0;
}
- (BOOL)isFuture;
{
        PBDate *d1;
        long l;
        d1 = [[PBDate alloc]init];
        [d1 setCurrentDay];
        l = ([d1 dateAsLong]-[self dateAsLong]);
        [d1 release];
        return l<0;
}
- init
{
    [super init];
    [self clearDate];
    monthNames = [[NSArray alloc]initWithObjects:
        @"no month",
        @"Jan.",
        @"Feb.",
        @"Mrz.",
        @"Apr.",
        @"Mai ",
        @"Juni",
        @"Juli",
        @"Aug.",
        @"Sep.",
        @"Okt.",
        @"Nov.",
        @"Dez.",
        nil];
    return self;
}
+ (PBDate *)date; //autoreleased PBDate von heute
{
    PBDate *_date = [[[PBDate alloc]init]autorelease];
    [_date setCurrentDay];
    return _date;
}
+ (PBDate *)dateWithFreeString:(NSString *)s; //autoreleased PBDate von freeString
{
    PBDate *_date = [[[PBDate alloc]init]autorelease];
    if([_date setFreeString:s]) return _date;
    return nil;
}
+ (PBDate *)dateWithDBString:(NSString *)s; //autoreleased PBDate von DBString
{
    PBDate *_date;
    s = [s normalizedDate];
    if(![s intValue])return nil;
    _date = [[[PBDate alloc]init]autorelease];
    [_date setDBString:s];
    return _date;
}
+ (NSString *)dbDeltaFrom:(NSString *)date1 to:(NSString *)date2;
{
// liefert sekunden von date1 bis date2; nimmt strings im dbformat entgegen
    NSTimeInterval ti;
    PBDate *d1 = [PBDate date];
    PBDate *d2 = [PBDate date];
    [d1 setDBString:date1];
    [d2 setDBString:date2];
    ti = [[d2 dateAsNSCD] timeIntervalSinceDate:[d1 dateAsNSCD]];
    return [NSSWF @"%0f",ti];
}
- (NSString *)monthNameFor:(int)i;
{
    if(i>0 && i<=12) return [monthNames oai:i];
    return EON;
}
- (NSString *)monthName;
{
    return [monthNames oai:month];
}
- (void)clearDate;
{
    year = 0; month = 0; day = 0; hour = 0; minute = 0; second=0; dyforw = 0; dwofy =0;
}
- (void)setCurrent
{
    [self setNSCD:[NSCalendarDate date]];
}
- (void)setCurrentDay
{
//auf 00:00:00 stellen
    [self setNSCD:[NSCalendarDate date]];
    hour = 0; minute = 0; second=0;
}
- (NSString *) timeStringSec; // hh:mm:ss
{
    return [NSSWF @"%02i:%02i:%02i",hour,minute,second];
}
- (NSString *) timeAsString; // hh:mm
{
    return [NSSWF @"%02i:%02i",hour,minute];
}
- (NSString *)time; // hhmm
{
    return [NSSWF @"%02i%02i",hour,minute];
}
- (NSCalendarDate *)dateAsNSCD
{
    NSCalendarDate *d;
    
    d = [NSCalendarDate dateWithYear:year month:month day:day hour:hour minute:minute second:second timeZone:[NSTimeZone defaultTimeZone]];
    return d;
}
- (NSString *)dateFormatted:(NSString *)dateFormat;
{
    return [[self dateAsNSCD]descriptionWithCalendarFormat:dateFormat];
}
- (void)setNSCD:(NSCalendarDate *)cd;
{
    [self clearDate];
    year = [cd yearOfCommonEra];
    month = [cd monthOfYear];
    day = [cd dayOfMonth];
    hour = [cd hourOfDay];
    minute = [cd minuteOfHour];
    second = [cd secondOfMinute];
}
- (long)dateAsLong;
{
    return year * 10000 + month * 100 + day;
}
- (void)setLong:(long)value
{
    [self clearDate];
    day = value % 100;
    month = (value / 100) % 100;
    year = value / 10000;
}
- (void)setMysqlDBString:(NSString *)value
{
// date u. datetime yyyy-mm-dd[ hh:mm:ss]
    NSArray *dt = [value componentsSeparatedByString:@" "];
    NSArray *substrings = [[dt firstObject] componentsSeparatedByString:@"-"]; //date
    [self clearDate];
    if([substrings count]==3){
        year = [(NSString *)[substrings firstObject]intValue];
        month = [(NSString *)[substrings oai:1]intValue];
        day = [(NSString *)[substrings oai:2]intValue];
    }
    if([dt count]==2){
        substrings = [[dt oai:1] componentsSeparatedByString:@":"];
        hour = [(NSString *)[substrings firstObject]intValue];
        minute = [(NSString *)[substrings oai:1]intValue];
        second = [(NSString *)[substrings oai:2]intValue];
    }
}
- (NSComparisonResult)compare:(PBDate *)otherDate;
{
    long l1,l2;
    if(!otherDate)return NSOrderedDescending;
    l1 = [self dateAsLong];
    l2 = [otherDate dateAsLong];
    if(l1>l2)return NSOrderedDescending;
    if(l2>l1)return NSOrderedAscending;
    if(hour > [otherDate hour])return NSOrderedDescending;
    if([otherDate hour] > hour)return NSOrderedAscending;
    if(minute > [otherDate minute])return NSOrderedDescending;
    if([otherDate minute] > minute)return NSOrderedAscending;
    if(second > [otherDate second])return NSOrderedDescending;
    if([otherDate second] > second)return NSOrderedAscending;
    return NSOrderedSame;
}
- (int)deltaDaysTo:(PBDate *)otherDate;
{
// von self bis otherDate
    NSCalendarDate *d1 = [NSCalendarDate dateWithYear:year month:month day:day hour:0 minute:0 second:0 timeZone:[NSTimeZone defaultTimeZone]];
    NSCalendarDate *d2 = [otherDate dateAsNSCD];
    NSTimeInterval ti;
    ti = [d2 timeIntervalSinceDate:d1];
//     LOGS([NSSWF @"d1:%@ d2:%@ ti:%.0f",[d1 descriptionWithCalendarFormat:@"%Y%m%d"],[d2 descriptionWithCalendarFormat:@"%Y%m%d"],ti]));
    return [[NSSWF @"%.0f",(ti / 86400.0)]intValue];
}
- (int)deltaWorkDaysTo:(PBDate *)otherDate;
{
// von self bis otherDate
    PBDate *d1=[PBDate dateWithDBString:[self dateAsDBString]];
    long l1 = [d1 dateAsLong];
    long l2 = [otherDate dateAsLong];
    int step = (l1<l2)?1:-1;
    int delta = 0;
    if(l1 == l2)return 0;
    if(abs(l2 - l1) > 1000)LOGS(@"deltaWorkDaysTo: mehr als 1000 Tage Differenz");
    while(l1 < l2){
        [d1 addWorkDay:step];
        delta+=step;
        l1 = [d1 dateAsLong];
    }
    return delta;
}
- (NSString *)deltaHrsTo:(PBDate *)otherDate;
{
    NSCalendarDate *d1 = [self dateAsNSCD];
    NSCalendarDate *d2 = [otherDate dateAsNSCD];
    NSTimeInterval ti;
    ti = [d2 timeIntervalSinceDate:d1];
    return [NSSWF @"%.03f",(ti / 3600.0)];
}
- (NSString *)dateAsDBString;
{
    return [NSSWF @"%04i%02i%02i000000", year,month,day];
}
- (NSString *)dateAsDBDTString;
{
    return [NSSWF @"%04i%02i%02i%02i%02i%02i",year,month,day,hour,minute,second];
}
- (void)setDBString:(NSString *)value
{
// date u. datetime yyyymmdd[hhmmss]
    [self setLong:[[value secureSubstringToIndex:8]intValue]];
    if([value length]>8){
        long l = [[value secureSubstringFromIndex:8]intValue];
        second = l % 100;
        minute = (l / 100) % 100;
        hour = l / 10000;
    }
}
- (NSString *)dateAsUIString;
{
    return [NSSWF @"%02i.%02i.%02i",day,month,year];
}
- (NSString *)dateAsUIDTString;
{
    return [NSSWF @"%02i.%02i.%02i %02i:%02i:%02i",day,month,year,hour,minute,second];
}
+ (PBDate *)dateWithYear:(int)y andWeek:(int)week;
{
    PBDate *pbd = [PBDate date];
    [pbd setWeek:week andYear:y];
    return pbd;
}
- (void)setWeek:(int)week andYear:(int)y; // wenn year == 0, current nehmen;
{
    [self clearDate];
    dwofy = week;
    dyforw = y;
    if(!dyforw)dyforw = [[NSCalendarDate date]yearOfCommonEra];
    [self setNSCD:[[self mondayOf1stWeekOfYear:dyforw]dateByAddingYears:0 months:0 days:(week -1)*7 hours:0 minutes:0 seconds:0]];
}
- (BOOL)setFreeString:(NSString *)value;
// t = today; Tagesdatum
//
{
    NSArray *a;
    int	direction;	//1 = Zukunft, -1 = Vergangenheit;
    NSString *absDate,*offset;
    
//n = now
    if([value isEqual:@"n"]){
        [self setCurrent];
        return YES;
    }
//t = today
    if([value iE:@"t"]){
        [self setCurrentDay];
        return YES;
    }
    if([value hasPrefix:@"+"]){
        [self setCurrentDay];
        direction = 1;
        offset = [value substringFromIndex:1];
        return [self applyOffsetString:offset direction:direction];
    }
    if([value hasPrefix:@"-"]){
        [self setCurrentDay];
        direction = -1;
        offset = [value substringFromIndex:1];
        return [self applyOffsetString:offset direction:direction];
    }
    a = [value componentsSeparatedByString:@"+"];
    if([a count]==2){
        absDate = [a firstObject];
        if(![self setFreeStringAbs:absDate]){
            return NO;
        }
        direction = 1;
        offset = [a oai:1];
        return [self applyOffsetString:offset direction:direction];
    }
    a = [value componentsSeparatedByString:@"-"];
    if([a count]==2){
        absDate = [a firstObject];
        if(![self setFreeStringAbs:absDate]){
            return NO;
        }
        direction = -1;
        offset = [a oai:1];
        return [self applyOffsetString:offset direction:direction];
    }
    return [self setFreeStringAbs:value];
}
+ (NSArray *)modes;
{
    static NSArray *a;
    if(!a){
        a = [[NSArray arrayWithObjects:@"f",@"l",nil]retain];
    }
    return a;
}
+ (NSArray *)types;
{
    static NSArray *a;
    if(!a){
        a = [[NSArray arrayWithObjects:@"D",@"m",@"y",@"q",@"w",nil]retain];
    }
    return a;
}
- (BOOL)applyOffsetString:(NSString *)offset direction:(int)direction;
{
// [best.Datum]{+,-}[%i][{D,m,y,q,w}][{f,l}][W]  Tagesdatum mit Offset; %i = anzahl; nix -> 1
//							month,year,quarter,week; nix -> day; D = workdays
//							f = first, l = last; nix -> exakt;
//							W = workday; Ziel auf jeden fall ein workday; default = NO
    NSScanner *sc;
    int n=1,type=DAYS,mode=EXACT;
    long l;
    int m;
    NSString *s;
    BOOL targetWorkday=NO;
    sc = [NSScanner scannerWithString:offset];
    if(![sc scanInt:&n]){
        n=1;
        s = offset;
    }else{
        s = [offset substringFromIndex:[sc scanLocation]];
    }
    if([s length]){
        type = [[PBDate types] indexOfObject:[s substringToIndex:1]];
        if(type!=DAYS)s = [s substringFromIndex:1];
    }
    if([s length]){
        mode = [[PBDate modes] indexOfObject:[s substringToIndex:1]];
        if(mode != EXACT)s = [s substringFromIndex:1];
    }
    if([s length]){
        targetWorkday = [[s substringToIndex:1] iE:@"W"];
    }
    if(type == WORKDAYS)type = DAYS;	//workday not yet implemented;
//offset calculation
    switch(type){
        case DAYS:
            [self addDay:direction * n];
            break;
        case WEEKS:
            [self addWeek:direction * n];
            break;
        case MONTHS:
            [self addMonth:direction * n];
            break;
        case QUARTERS:
            [self addMonth:direction * n * 3];
            break;
        case YEARS:
            [self addYear:direction * n];
            break;
    }
    
//first/last justification
    if(mode != EXACT){
        switch(type){
            case DAYS:	//gibt's nix
                break;
            case WEEKS:	//auf Montag/Sonntag in der Woche;
                [self prevMonday];
                if(mode != FIRST){
                    [self addDay:6];
                }
                break;
            case MONTHS:	//auf 01./letzen im Monat; lezter: 01. des Folgemonats -1 tag;
                l = (([self dateAsLong]/100)*100)+1;
                [self setLong:l];
                if(mode != FIRST){
                    [self addMonth:1];
                    [self addDay:-1];
                }
                break;
            case QUARTERS:	//auf 01.01., 01.04., 01.07., 01.10 bzw. 31.03., 30.06., 30.09., 31.12.
                m = (((([self month]-1)/3)*3)+1);
                l = (([self dateAsLong]/10000)*10000)+m*100+1;
                [self setLong:l];
                if(mode != FIRST){
                    [self addMonth:3];
                    [self addDay:-1];
                }
                break;
            case YEARS:	//auf 01.01./31.12.
                l = (([self dateAsLong]/10000)*10000)+101;
                [self setLong:l];
                if(mode != FIRST){
                    [self addYear:1];
                    [self addDay:-1];
                }
                break;
        }
    }
    
//workday justification
// not yet implemented;
    return YES;
}
- (BOOL)setFreeStringAbs:(NSString *)value;
// String im Format:
// (wenn default-sequence)
// jahr ist immer optional u. kann 2- oder 4-stellig sein
// wenn delimiter drin sind: 						 	DD.MM.YYYY
//                        						 	DD.MM.YY
//                        						 	DD.MM
// wenn keine delimiter drin sind: 				wenn 8 characters 	DDMMYYYY
//								wenn 6 characters 	DDMMYY
//								wenn 4 characters 	DDMM
//								wenn 2 characters 	WW
// Zeitanteil durch space abgetrennt:
// hh
// hhmm
// hhmmss
// hh:mm
// hh:mm:ss
{
    int	tt,mm,jjjj=0;
    NSRange	myRange;
    NSArray *substrings,*a;
    int	l,ssc,ww;
    if(!FILLED(value)){ return NO;};
    [self clearDate];
    a = [value componentsSeparatedByString:@" "];
    value = [a firstObject];
    if([a count]==2){
        NSString *valueT = [a oai:1];
        int hh=0,mmin=0,ss=0;
        myRange = [valueT rangeOfString:@":"];	
        if(myRange.length){		//wir haben delimiters drin
            substrings = [valueT componentsSeparatedByString:@":"];
            ssc = [substrings count];
            if(ssc < 2 || ssc > 3)return NO;
            hh = [[substrings firstObject]intValue];
            mmin = [[substrings oai:1]intValue];
            if(ssc == 3){
                ss = [[substrings oai:2]intValue];
            }
        }else{
            l = [valueT length];
            if(l>6)return NO;
            if(l>=2){
                hh = [[valueT substringToIndex:2] intValue];
            }
            if(l>=4){
                mmin = [[[valueT substringFromIndex:2]substringToIndex:2]intValue];
            }
            if(l==6){
                ss = [[valueT substringFromIndex:4]intValue];
            }
        }
        if(hh < 0 || hh > 23)return NO;
        if(mmin < 0 || mmin > 59)return NO;
        if(ss < 0 || ss > 59)return NO;
        hour = hh;
        minute = mmin;
        second = ss;
    }
    l = [value length];
    myRange = [value rangeOfString:@"."];	
    if(myRange.length){		//wir haben delimiters drin
        substrings = [value componentsSeparatedByString:@"."];
        ssc = [substrings count];
        tt = [[substrings firstObject]intValue];
        mm = [[substrings oai:1]intValue];
        if(ssc==3){
            jjjj = [[substrings oai:2]intValue];
            if(jjjj<100)jjjj=[self addCentury:jjjj];
        }
        if(ssc==2){
            jjjj = [[NSCalendarDate date]yearOfCommonEra];
        }
        if(![self checkDateTT:tt mm:mm jjjj:jjjj])return NO;
        year = jjjj; month = mm; day = tt;
        return YES;				
    }
    if(l==8 || l ==6){
        tt = [[value substringToIndex:2]intValue];
        mm = [[[value substringFromIndex:2]substringToIndex:2]intValue];
        jjjj = [[value substringFromIndex:4]intValue];
        if(jjjj<100)jjjj=[self addCentury:jjjj];
        if(![self checkDateTT:tt mm:mm jjjj:jjjj])return NO;
        year = jjjj; month = mm; day = tt;
        return YES;				
    }
    if((l==4)){
        tt = [[value substringToIndex:2]intValue];
        mm = [[value substringFromIndex:2]intValue];
        jjjj = [[NSCalendarDate date]yearOfCommonEra];
        if(![self checkDateTT:tt mm:mm jjjj:jjjj])return NO;
        year = jjjj; month = mm; day = tt;
        return YES;				
    }
    if(l==2 || l==1){
        int currentWeek;
        int currentYear;
        NSCalendarDate *cd;
        if((ww=[value intValue])>53){ return NO;}
        cd = [NSCalendarDate date];
        currentYear = [cd yearOfCommonEra];
        [self setNSCD:cd];
        currentWeek = [self weekOfYear];
        if(ww < currentWeek)currentYear++; //dann ist woche im naechsten Jahr gemeint
        [self setWeek:ww andYear:currentYear];
        return YES;				
    }
    return NO;
}
- (int) weekOfYear; // 1 <= woche <= 53
{
    if(dwofy)return dwofy;
    [self computeWandyFrom:[self dateAsNSCD]];
    return dwofy;
}
- (int) yearForWeek;
{
    if(dyforw)return dyforw;
    [self computeWandyFrom:[self dateAsNSCD]];
    return dyforw;
}
- (NSString *)weekAndYear;
{
    return [NSSWF @"%02i/%04i",[self weekOfYear], [self yearForWeek]];
}
- (void)dealloc
{
    [monthNames release];
    [super dealloc];
}
- (void)addWeek:(int)value;
{
    NSCalendarDate *d;
    if((d=[self dateAsNSCD])){
        if(hour==0 && minute==0 && second==0){
            [self setNSCD:[d dateByAddingYears:0 months:0 days:7 * value hours:2 minutes:10 seconds:0]]; //wg. Sommerzeit 2 std. dazu
            hour = 0; minute = 0;
        }else{
            [self setNSCD:[d dateByAddingYears:0 months:0 days:7 * value hours:0 minutes:0 seconds:0]]; //exakt
        }
    }
}
- (void)addWorkDay:(int)value;
{
//feiertage u. firmenkalender werden beruecksichtigt
//samstag sonntag gemaess einstellung im config
    int step;
    if(!value)return;
    if(abs(value)>1000){
        LOGS(@"max. 1000 Werktage");
        return;
    }
    if(value <0){
        step=-1;
    }else{
        step=1;
    }
    while(value!=0){
        [self addDay:step];
        if([self isWorkday])value-=step;
    }
}
- (void)addMinute:(int)value;
{
    NSCalendarDate *d;
    if((d=[self dateAsNSCD])){
        [self setNSCD:[d dateByAddingYears:0 months:0 days:0 hours:0 minutes:value seconds:0]]; //exakt
    }
}
- (void)addDay:(int)value;
{
    NSCalendarDate *d;
    if((d=[self dateAsNSCD])){
        if(hour==0 && minute==0 && second==0){
            [self setNSCD:[d dateByAddingYears:0 months:0 days:value hours:2 minutes:10 seconds:0]]; //wg. Sommerzeit 2 std. dazu
            hour = 0; minute = 0;
        }else{
            [self setNSCD:[d dateByAddingYears:0 months:0 days:value hours:0 minutes:0 seconds:0]]; //exakt
        }
    }
}
- (void)addMonth:(int)value;
{
    NSCalendarDate *d;
    if((d=[self dateAsNSCD])){
        if(hour==0 && minute==0 && second==0){
            [self setNSCD:[d dateByAddingYears:0 months:value days:0 hours:2 minutes:10 seconds:0]]; //wg. Sommerzeit 2 std. dazu
            hour = 0; minute = 0;
        }else{
            [self setNSCD:[d dateByAddingYears:0 months:value days:0 hours:0 minutes:0 seconds:0]]; //exakt
        }
    }
}
// weil GNUstep ein problem hat mit dateByAddingYears...
- (void)incMonth;
{
    month++;
    day = 1;
    if(month==13){
        year++;
        month=1;
    }
}
- (void)decMonth;
{
    month--;
    day = 1;
    if(month==0){
        year--;
        month=12;
    }
}
- (void)addYear:(int)value;
{
    year += value;
}
- (int)day;
{
    return day;
}
- (int)month;
{
    return month;
}
- (int)year;
{
    return year;
}
- (int)second;
{
    return second;
}
- (int)minute;
{
    return minute;
}
- (int)hour;
{
    return hour;
}
- (void)setDay:(int)value;
{
    day = value;
}
- (void)setMonth:(int)value;
{
    month = value;
}
- (void)setYear:(int)value;
{
    year = value;
}
- (void)setMinute:(int)value;
{
    minute = value;
}
- (void)setHour:(int)value;
{
    hour = value;
}
- (BOOL)checkDateTT:(int)t mm:(int)m jjjj:(int)j;
{
    static int tage[2][13]=	{
    {0,31,28,31,30,31,30,31,31,30,31,30,31},
    {0,31,29,31,30,31,30,31,31,30,31,30,31}
    };
    int index;
    BOOL	sj;
    if(t < 1 || m < 1 || j < 1){ return NO;}
    if(t > 31 || m > 12){ return NO;}
    sj = ((j%4 == 0) && (j%100 != 0)) || (j%400 == 0);
    index = sj ? 1 : 0;
    if(t > tage[index][m]){return NO;}
    return YES;
}
- (int)addCentury:(int)y;
{
    if(y >= 66){    	// 19 davor
        return 1900 + y;
    }else{							// 20 davor	
        return 2000 + y;
    }
}
- (int)weekday;
{
    return [[self dateAsNSCD] dayOfWeek];
}
- (NSString *)weekdayName;
{
    return [[_APP weekdayNames] oai:[[self dateAsNSCD] dayOfWeek]];
}
- (NSString *)fullWeekdayName;
{
    return [[_APP weekdayFullNames] oai:[[self dateAsNSCD] dayOfWeek]];
}
- (void)prevMonday;
{
    NSCalendarDate	*d = [self dateAsNSCD];
    d = [self prevMonday:d];
    [self setNSCD:d];
}
- (NSCalendarDate *)prevMonday:(NSCalendarDate *)aDate;
{
    int		dayOfWeek = [aDate dayOfWeek];
    if(!dayOfWeek)dayOfWeek=7;	//Sonntag am Ende;
    return [aDate dateByAddingYears:0 months:0 days:-(dayOfWeek-1) hours:0 minutes:0 seconds:0];
}
- (int)_weekOfYearNoSpecialCase: (NSCalendarDate *)aDate
{
    NSCalendarDate	*prevMonday = [self prevMonday:aDate];
    NSTimeInterval i = [prevMonday timeIntervalSinceDate:[self mondayOf1stWeekOfYear:[aDate yearOfCommonEra]]];
    return (int)round0(((i/(3600*24*7))+1));
}
- (NSCalendarDate *)mondayOf1stWeekOfYear:(int)y;
{
    int				currentYear;	//das betroffene jahr
    NSString		*dateAsString;  //tt.mm.yyyy
    NSCalendarDate	*firstJanuary;
    NSCalendarDate	*mondayOfWeek1;
    int				dayOfWeek;
    if (y==0){
        currentYear = [[NSCalendarDate date]yearOfCommonEra];
    }else{
        currentYear = y;
    }
    dateAsString = [NSSWF @"01.01.%04i",currentYear];
    firstJanuary = [NSCalendarDate dateWithString:dateAsString	calendarFormat: @"%d.%m.%Y"];
    dayOfWeek = [firstJanuary dayOfWeek];
    if(!dayOfWeek)dayOfWeek=7;	//Sonntag am Ende;
    
    // Do im alten Jahr: Woche zum alten Jahr
// Do im neuen Jahr: Woche zum neuen Jahr
    if (dayOfWeek <= THURSDAY){		//1.1. in erster Woche des lfd. Jahres
        //-> vorheriger Montag;
        mondayOfWeek1 =
        [self prevMonday:firstJanuary];
    }else{							//1.1. in letzter Woche des Vorjahres
            //-> naechster Montag;
        mondayOfWeek1 =
        [[self prevMonday:firstJanuary] dateByAddingYears:0 months:0 days:7 hours:0 minutes:0 seconds:0];
    }
    return mondayOfWeek1;
}
- (void)computeWandyFrom:(NSCalendarDate *)aDate;
{
    NSCalendarDate	*clutchDay;
    int	currentYear = [aDate yearOfCommonEra];
    int	dayOfWeek = [aDate dayOfWeek];
    int	numDaysDiff;
    if(!dayOfWeek)dayOfWeek=7;	//Sonntag am Ende;
    numDaysDiff = THURSDAY - dayOfWeek;
    //Do der lfd. Woche:
    clutchDay = [aDate dateByAddingYears:0 months:0 days:numDaysDiff hours:0 minutes:0 seconds:0];
    
    //Do im neuen Jahr-> wir sind in Woche 1
    if ([clutchDay yearOfCommonEra] == currentYear+1) {
        dyforw = currentYear + 1;
        dwofy = 1;
        return;
    }
    
    //Do im vorherigen Jahr
    if ([clutchDay yearOfCommonEra] == currentYear - 1) {
        dyforw = currentYear - 1;
        dwofy = [self _weekOfYearNoSpecialCase: clutchDay];
        return;
    }
    
    //Mittwoch im selben Jahr
    dyforw = currentYear;
    dwofy =  [self _weekOfYearNoSpecialCase: clutchDay];
}
/* deprecated
- (NSString *)dateAsMysqlDBDTString; // yyyy-mm-dd hh:mm:ss f. mysql;
{
    return [NSSWF @"%04i-%02i-%02i %02i:%02i:%02i",year,month,day,hour,minute,second];
}
- (void)bankAddMonth:(int)v
{
        static int tage[2][13]=	{
        {0,31,28,31,30,31,30,31,31,30,31,30,31},
        {0,31,29,31,30,31,30,31,31,30,31,30,31}
                                                        };
        int t1,t,m,j,index;
        BOOL	sj;
        long l = [self dateAsLong];
        if(l<0)return;
        t = l%100; m = (l%10000)/100; j = l/10000;
        j = j + ((m + v - 1) / 12);
        m = ((m + v - 1) % 12) + 1;
        sj = ((j%4 == 0) && (j%100 != 0)) || (j%400 == 0);
        index = sj ? 1 : 0;
        t1 = tage[index][m];
        if(t > t1)t = t1;
        [self setLong:j*10000 + m*100 + t];
}
+ (NSArray *)delim;
{
    static NSArray *a;
    if(!a){
        a = [[NSArray arrayWithObjects:@".",@"-",@"/",nil]retain];
    }
    return a;
}
-  (void)mitte
{
    int m,j;
    long l = [self dateAsLong];
    if(l<0)return;
    m = (l%10000)/100; j = l/10000;
    [self setLong:j*10000 + m*100 + 15];
}
-  (void)letzter
{
    static int tage[2][13]=	{
    {0,31,28,31,30,31,30,31,31,30,31,30,31},
    {0,31,29,31,30,31,30,31,31,30,31,30,31}
    };
    int t,m,j,index;
    BOOL	sj;
    long l = [self dateAsLong];
    if(l<0)return;
    m = (l%10000)/100; j = l/10000;
    sj = ((j%4 == 0) && (j%100 != 0)) || (j%400 == 0);
    index = sj ? 1 : 0;
    t = tage[index][m];
    if (t == 31) t = 30;
    [self setLong:j*10000 + m*100 + t];
}
+ (NSString *)freeDeltaFrom:(NSString *)date1 to:(NSString *)date2;
{
// liefert sekunden von date1 bis date2; nimmt strings im Guiformat entgegen
    NSTimeInterval ti;
    NSCalendarDate *d1 = [[PBDate dateWithFreeString:date1]dateAsNSCD];
    NSCalendarDate *d2 = [[PBDate dateWithFreeString:date2]dateAsNSCD];
    if(!(d1 && d2))return @"0";
    ti = [d2 timeIntervalSinceDate:d1];
    return [NSSWF @"%0f",ti];
}
*/
@end
Foto