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.