PageRenderTime 19ms CodeModel.GetById 2ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/core/date.d

http://github.com/wilkie/djehuty
D | 244 lines | 202 code | 32 blank | 10 comment | 43 complexity | f61a689895a20d63b1020ccfce90db51 MD5 | raw file
  1/*
  2 * date.d
  3 *
  4 * This module implements Date related functions.
  5 *
  6 */
  7
  8module core.date;
  9
 10enum Month {
 11	January,
 12	February,
 13	March,
 14	April,
 15	May,
 16	June,
 17	July,
 18	August,
 19	September,
 20	October,
 21	November,
 22	December
 23}
 24
 25enum Day {
 26	Sunday,
 27	Monday,
 28	Tuesday,
 29	Wednesday,
 30	Thursday,
 31	Friday,
 32	Saturday
 33}
 34
 35import scaffold.time;
 36
 37import core.string;
 38import core.time;
 39import core.timezone;
 40import core.definitions;
 41import core.locale;
 42
 43import core.timezone;
 44
 45class Date {
 46
 47	this() {
 48		DateGet(_month, _day, _year);
 49	}
 50
 51	this(Month month, uint day, uint year) {
 52		_month = month;
 53		_day = day;
 54		_year = year;
 55	}
 56
 57	bool isLeapYear() {
 58		if (_year % 400 == 0) {
 59			return true;
 60		}
 61		else if (_year % 100 == 0) {
 62			return false;
 63		}
 64		else if (_year % 4 == 0) {
 65			return true;
 66		}
 67		return false;
 68	}
 69
 70	Day dayOfWeek() {
 71		// magicNum is a number manipulated in order to determine the day of the week as part of the Gregorian calendar algorithm
 72		int yearNum = -1;
 73		
 74		// there's gotta be a better way to do this.
 75		if( (_year >= 1700 && _year <= 1799) || (_year >= 2100 && _year <= 2199) || (_year >= 2500 && _year <= 2599) ) {
 76			yearNum = 4;
 77		}
 78		else if( (_year >= 1800 && _year <= 1899) || (_year >= 2200 && _year <= 2299) || (_year >= 2600 && _year <= 2699) ) {
 79			yearNum = 2;
 80		}
 81		else if( (_year >= 1900 && _year <= 1999) || (_year >= 2300 && _year <= 2399) ){
 82			yearNum = 0;
 83		}
 84		else if( (_year >= 2000 && _year <= 2099) || (_year >= 2400 && _year <= 2499) ){
 85			yearNum = 6;
 86		}
 87		else {
 88			// year with unknown value
 89		}
 90		
 91		int yearDigitNum = (_year%100);
 92		int leapYearNum = yearDigitNum/4;
 93		int monthNum = -1;
 94		
 95		switch(_month){
 96			case Month.January:
 97			case Month.October:
 98			 	monthNum = 0;
 99				break;
100			case Month.February:
101			case Month.March:
102			case Month.November:
103				monthNum = 3;
104				break;
105			case Month.April:
106			case Month.July:
107				monthNum = 6;
108				break;
109			case Month.May:
110				monthNum = 1;
111				break;
112			case Month.June:
113				monthNum = 4;
114				break;
115			case Month.August:
116				monthNum = 2;
117				break;
118			case Month.September:
119			case Month.December:
120				monthNum = 5;
121				break;
122			default: 
123				break;
124		}
125
126		int dayNum = (yearNum + yearDigitNum + leapYearNum + monthNum + _day)%7;
127
128		switch(dayNum){
129			case 0:
130				return Day.Sunday;
131			case 1:
132				return Day.Monday;
133			case 2:
134				return Day.Tuesday;
135			case 3:
136				return Day.Wednesday;
137			case 4:
138				return Day.Thursday;
139			case 5:
140				return Day.Friday;
141			case 6:
142				return Day.Saturday;
143			default:
144				break;
145		}
146
147		assert(0, "Error: Unable to determine the day of week");
148	}
149
150	Month month() {
151		return _month;
152	}
153
154	void month(Month value) {
155		_month = value;
156	}
157
158	uint day() {
159		return _day;
160	}
161
162	void day(uint value) {
163		_day = value;
164	}
165
166	uint year() {
167		return _year;
168	}
169
170	void year(uint value) {
171		_year = value;
172	}
173
174	static Date Now() {
175		return new Date();
176	}
177
178	static Date Local(TimeZone localTZ = null) {
179		Date ret = new Date();
180
181		if (localTZ is null) {
182			localTZ = new TimeZone();
183		}
184
185		Time time = Time.Now();
186		long micros = time.microseconds;
187		micros += localTZ.utcOffset;
188		if (micros < 0) {
189			// subtract a day
190			if (ret._day == 1) {
191				if (ret._month == Month.January) {
192					ret._year--;
193					ret._month = Month.December;
194				}
195				else {
196					ret._month--;
197				}
198				switch (ret._month) {
199					case Month.January:
200					case Month.March:
201					case Month.May:
202					case Month.July:
203					case Month.August:
204					case Month.October:
205					case Month.December:
206						ret._day = 31;
207						break;
208					case Month.February:
209						if (ret.isLeapYear) {
210							ret._day = 29;
211						}
212						else {
213							ret._day = 28;
214						}
215						break;
216					default:
217						ret._day = 30;
218						break;
219				}
220			}
221			else {
222				ret._day--;
223			}
224		}
225		return ret;
226	}
227
228	string toString() {
229		return Locale.formatDate(this);
230	}
231
232private:
233
234	Month _month;
235	uint _day;
236	uint _year;
237
238	class _Now : Date {
239		this() {
240		}
241	}
242
243	static _Now _now;
244}