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