This is MiscDateView.m in view mode; [Download] [Up]
// // MiscDateView.m -- a view for dealing with input and display of dates // Written by Hugh Ashton, Copyright (c) 1994 by Hugh Ashton. // Version 1.0 All rights reserved. // This notice may not be removed from this source code. // // This object is included in the MiscKit by permission from the author // and its use is governed by the MiscKit license, found in the file // "LICENSE.rtf" in the MiscKit distribution. Please refer to that file // for a list of all applicable permissions and restrictions. // #include <time.h> #include <libc.h> #include <strings.h> #import "MiscDateView.h" #define CURRENT_VERSION 1 id BundleForStrings = nil; #define MONDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Monday",NULL,zeroth day of week) #define TUESDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Tuesday",NULL,first day of week) #define WEDNESDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Wednesday",NULL,second day of week) #define THURSDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Thursday",NULL,third day of week) #define FRIDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Fri",NULL,fourth day of week) #define SATURDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Sat",NULL,fifth day of week) #define SUNDAY NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Sun",NULL,sixth day of week) #define DATE_ERROR NXLocalizedStringFromTableInBundle (NULL,BundleForStrings,"Date entry error",NULL,error in date entry) @implementation MiscDateView + initialize { if ( self == [MiscDateView class] ) [MiscDateView setVersion:CURRENT_VERSION]; return self; } - decDay:sender { int mm; if(strlen([day stringValue])>0) { [day setIntValue:[day intValue]-1]; } if([day intValue]<1) { [month setIntValue:[month intValue]-1]; if([month intValue]<1) { [month setIntValue:12]; [year setIntValue:[year intValue]-1]; } mm=[month intValue]; if(mm==4 || mm==6 || mm==9 || mm==11) /* 30 days hath September... */ { [day setIntValue:30]; [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; return self; } if(mm==2) { if([self isItaLeapYear:[year intValue]]) /* leap year */ { [day setIntValue:29]; } else { [day setIntValue:28]; } [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; return self; } [day setIntValue:31]; } [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; [self isDateValid:self]; return self; } - decMonth:sender { if(strlen([month stringValue])>0) { [month setIntValue:[month intValue]-1]; } if([month intValue]<1) { [month setIntValue:12]; [year setIntValue:[year intValue]-1]; } [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; [self isDateValid:self]; return self; } - outputDOW:(unsigned int)number { number=number%7; if(number==0) { [dow setStringValue:MONDAY]; return self; } if(number==1) { [dow setStringValue:TUESDAY]; return self; } if(number==2) { [dow setStringValue:WEDNESDAY]; return self; } if(number==3) { [dow setStringValue:THURSDAY]; return self; } if(number==4) { [dow setStringValue:FRIDAY]; return self; } if(number==5) { [dow setStringValue:SATURDAY]; return self; } if(number==6) { [dow setStringValue:SUNDAY]; return self; } return self; } - decYear:sender { if(strlen([year stringValue])>0) { [year setIntValue:[year intValue]-1]; } [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; [self isDateValid:self]; return self; } - checkDay:sender { if((strlen([day stringValue])==0) || (strlen([month stringValue])==0) || (strlen([year stringValue])==0)) { [dow setStringValue:"XXX"]; return self; } [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; [self isDateValid:self]; return self; } - (unsigned int)whatDayIs:(int)theDay :(int)theMonth :(int)theYear /* we take 1 January 1901 as our base Mon=0, Tue=1, etc */ { unsigned int i; unsigned int current_count; current_count=1; /* as it happens, 1/1/1901 was a Tuesday */ if(theYear<1901) { return 00; } for(i=1901;i<theYear;i++) { if([self isItaLeapYear:i]) { current_count=(current_count+=366); } else { current_count=(current_count+=365); } } for(i=1;i<theMonth;i++) { if((i==4) || (i==6) || (i==9) || (i==11)) { current_count+=30; } if((i==2) && ([self isItaLeapYear:theYear])) { current_count+=29; } if((i==2) && (![self isItaLeapYear:theYear])) { current_count+=28; } if((i==1) || (i==3) || (i==5) || (i==7) || (i==8) || (i==10) || (i==12)) { current_count+=31; } } for(i=1;i<theDay;i++) { current_count+=1; } /* fencepost error, hence this kludge current_count=current_count-1; */ return current_count; } - (BOOL)isItaLeapYear:(int)theYear { // Fix from Rod Ragner: return ((!(theYear % 4) && (theYear % 200)) ? YES : NO); // old way is incorrect: // if((theYear/4.0)==(theYear/4)) // { // return YES; // } // else // { // return NO; // } } - getTodaysDate:sender { long currenttime; char dateString[60]=""; int dd; int mm=0; char mmStr[4]=""; int yyyy; char dowStr[4]=""; char timeString[20]=""; currenttime = time(0L); strcpy(dateString,ctime(¤ttime)); sscanf(dateString,"%s %s %d %s %d",dowStr,mmStr,&dd,timeString,&yyyy); [dow setStringValue:dowStr]; [year setIntValue:yyyy]; [day setIntValue:dd]; if(strcmp(mmStr,"Jan")==0) { mm=1; } if((strcmp(mmStr,"Feb"))==0) { mm=2; } if((strcmp(mmStr,"Mar"))==0) { mm=3; } if((strcmp(mmStr,"Apr"))==0) { mm=4; } if((strcmp(mmStr,"May"))==0) { mm=5; } if((strcmp(mmStr,"Jun"))==0) { mm=6; } if((strcmp(mmStr,"Jul"))==0) { mm=7; } if((strcmp(mmStr,"Aug"))==0) { mm=8; } if((strcmp(mmStr,"Sep"))==0) { mm=9; } if((strcmp(mmStr,"Oct"))==0) { mm=10; } if((strcmp(mmStr,"Nov"))==0) { mm=11; } if((strcmp(mmStr,"Dec"))==0) { mm=12; } [month setIntValue:mm]; return self; } - incDay:sender { int mm=0; mm=[month intValue]; if(strlen([day stringValue])>0) { [day setIntValue:[day intValue]+1]; } if((mm==4 || mm==6 || mm==9 || mm==11) && [day intValue]>30) { [month setIntValue:[month intValue]+1]; [day setIntValue:1]; [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; return self; } if((mm==2) && ([day intValue]>28) && (![self isItaLeapYear:[year intValue]])) { [month setIntValue:3]; [day setIntValue:1]; [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; return self; } if((mm==2) && ([day intValue]>29) && ([self isItaLeapYear:[year intValue]])) { [month setIntValue:3]; [day setIntValue:1]; [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; return self; } if([day intValue]>31) { [month setIntValue:[month intValue]+1]; [day setIntValue:1]; if([month intValue]>12) { [month setIntValue:1]; [year setIntValue:[year intValue]+1]; } } [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; [self isDateValid:self]; return self; } - incMonth:sender { if(strlen([month stringValue])>0) { [month setIntValue:[month intValue]+1]; } if([month intValue]>12) { [month setIntValue:1]; [year setIntValue:[year intValue]+1]; } [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; [self isDateValid:self]; return self; } - incYear:sender { if(strlen([year stringValue])>0) { [year setIntValue:[year intValue]+1]; } [self outputDOW:[self whatDayIs:[day intValue] :[month intValue] : [year intValue]]]; [self isDateValid:self]; return self; } - (BOOL)isDateValid:sender { if(([year intValue]>2050) || ([year intValue]<1901)) { NXRunAlertPanel(DATE_ERROR,"Year is outside range 1901 to 2050","OK",NULL,NULL); [year selectText:self]; [dow setStringValue:"XXX"]; return NO; } if(([month intValue]>12) || ([month intValue]<1)) { NXRunAlertPanel(DATE_ERROR,"Month is outside range 1 to 12","OK",NULL,NULL); [month selectText:self]; [dow setStringValue:"XXX"]; return NO; } if(([day intValue]<1) || ([day intValue]>31)) { NXRunAlertPanel(DATE_ERROR,"Day is outside range 1 to 31","OK",NULL,NULL); [day selectText:self]; [dow setStringValue:"XXX"]; return NO; } if(([month intValue]==4 || [month intValue]==6 || [month intValue]==9 || [month intValue]==11) && [day intValue]>30) { NXRunAlertPanel(DATE_ERROR,"Day is outside range for this month (1 to 30)","OK",NULL,NULL); [day selectText:self]; [dow setStringValue:"XXX"]; return NO; } if([month intValue]==2 && ![self isItaLeapYear:[year intValue]] && [day intValue]>28) { NXRunAlertPanel(DATE_ERROR,"Day is outside range for this month (1 to 28). %d is not a leap year","OK",NULL,NULL,[year intValue]); [day selectText:self]; [dow setStringValue:"XXX"]; return NO; } if([month intValue]==2 && [self isItaLeapYear:[year intValue]] && [day intValue]>29) { NXRunAlertPanel(DATE_ERROR,"Day is outside range for this month (1 to 29). %d is a leap year","OK",NULL,NULL,[year intValue]); [day selectText:self]; [dow setStringValue:"XXX"]; return NO; } return YES; } - initFrame:(const NXRect *)frameRect { [super initFrame:frameRect]; return self; } - drawSelf:(const NXRect *)rects :(int)rectCount { PSsetgray(NX_LTGRAY); NXRectFill(&bounds); return self; } - read:(NXTypedStream *)stream { int version; [super read:stream]; version = NXTypedStreamClassVersion(stream, "MiscDateView"); if ( version == CURRENT_VERSION ) { day = NXReadObject(stream); dayDown = NXReadObject(stream); dayUp = NXReadObject(stream); dow = NXReadObject(stream); month = NXReadObject(stream); monthDown = NXReadObject(stream); monthUp = NXReadObject(stream); year = NXReadObject(stream); yearDown = NXReadObject(stream); yearUp = NXReadObject(stream); } else { [self error:"Unknown version!"]; } return self; } - write:(NXTypedStream *)stream { [super write:stream]; NXWriteObject(stream, day); NXWriteObject(stream, dayDown); NXWriteObject(stream, dayUp); NXWriteObject(stream, dow); NXWriteObject(stream, month); NXWriteObject(stream, monthDown); NXWriteObject(stream, monthUp); NXWriteObject(stream, year); NXWriteObject(stream, yearDown); NXWriteObject(stream, yearUp); return self; } - (int)getDay:sender { return [day intValue]; } - (int)getMonth:sender { return [month intValue]; } - (int)getYear:sender { return [year intValue]; } - day:sender { return day; } - month:sender { return month; } - year:sender { return year; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.