PageRenderTime 208ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/jCommon-1.0.16/source/org/jfree/date/SerialDateUtilities.java

https://github.com/ph4r05/WirelessSensorNodeGeolocation
Java | 388 lines | 190 code | 26 blank | 172 comment | 55 complexity | 5556d78070b2052f2468eb1589bfe155 MD5 | raw file
  1. /* ========================================================================
  2. * JCommon : a free general purpose class library for the Java(tm) platform
  3. * ========================================================================
  4. *
  5. * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
  6. *
  7. * Project Info: http://www.jfree.org/jcommon/index.html
  8. *
  9. * This library is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation; either version 2.1 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful, but
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  17. * License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  22. * USA.
  23. *
  24. * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  25. * in the United States and other countries.]
  26. *
  27. * ------------------------
  28. * SerialDateUtilities.java
  29. * ------------------------
  30. * (C) Copyright 2001-2003, by Object Refinery Limited.
  31. *
  32. * Original Author: David Gilbert (for Object Refinery Limited);
  33. * Contributor(s): -;
  34. *
  35. * $Id: SerialDateUtilities.java,v 1.6 2005/11/16 15:58:40 taqua Exp $
  36. *
  37. * Changes (from 26-Oct-2001)
  38. * --------------------------
  39. * 26-Oct-2001 : Changed package to com.jrefinery.date.*;
  40. * 08-Dec-2001 : Dropped isLeapYear() method (DG);
  41. * 04-Mar-2002 : Renamed SerialDates.java --> SerialDateUtilities.java (DG);
  42. * 25-Jun-2002 : Fixed a bug in the dayCountActual() method (DG);
  43. * 03-Oct-2002 : Fixed errors reported by Checkstyle (DG);
  44. *
  45. */
  46. package org.jfree.date;
  47. import java.text.DateFormatSymbols;
  48. import java.util.Calendar;
  49. /**
  50. * A utility class that provides a number of useful methods (some static).
  51. * Many of these are used in the implementation of the day-count convention
  52. * classes. I recognise some limitations in this implementation:
  53. * <p>
  54. * [1] some of the methods assume that the default Calendar is a
  55. * GregorianCalendar (used mostly to determine leap years) - so the code
  56. * won&rsquo;t work if some other Calendar is the default. I'm not sure how
  57. * to handle this properly?
  58. * <p>
  59. * [2] a whole bunch of static methods isn't very object-oriented - but I couldn't think of a good
  60. * way to extend the Date and Calendar classes to add the functions I required,
  61. * so static methods are doing the job for now.
  62. *
  63. * @author David Gilbert
  64. */
  65. public class SerialDateUtilities {
  66. /** The default date format symbols. */
  67. private DateFormatSymbols dateFormatSymbols;
  68. /** Strings representing the weekdays. */
  69. private String[] weekdays;
  70. /** Strings representing the months. */
  71. private String[] months;
  72. /**
  73. * Creates a new utility class for the default locale.
  74. */
  75. public SerialDateUtilities() {
  76. this.dateFormatSymbols = new DateFormatSymbols();
  77. this.weekdays = this.dateFormatSymbols.getWeekdays();
  78. this.months = this.dateFormatSymbols.getMonths();
  79. }
  80. /**
  81. * Returns an array of strings representing the days-of-the-week.
  82. *
  83. * @return an array of strings representing the days-of-the-week.
  84. */
  85. public String[] getWeekdays() {
  86. return this.weekdays;
  87. }
  88. /**
  89. * Returns an array of strings representing the months.
  90. *
  91. * @return an array of strings representing the months.
  92. */
  93. public String[] getMonths() {
  94. return this.months;
  95. }
  96. /**
  97. * Converts the specified string to a weekday, using the default locale.
  98. *
  99. * @param s a string representing the day-of-the-week.
  100. *
  101. * @return an integer representing the day-of-the-week.
  102. */
  103. public int stringToWeekday(final String s) {
  104. if (s.equals(this.weekdays[Calendar.SATURDAY])) {
  105. return SerialDate.SATURDAY;
  106. }
  107. else if (s.equals(this.weekdays[Calendar.SUNDAY])) {
  108. return SerialDate.SUNDAY;
  109. }
  110. else if (s.equals(this.weekdays[Calendar.MONDAY])) {
  111. return SerialDate.MONDAY;
  112. }
  113. else if (s.equals(this.weekdays[Calendar.TUESDAY])) {
  114. return SerialDate.TUESDAY;
  115. }
  116. else if (s.equals(this.weekdays[Calendar.WEDNESDAY])) {
  117. return SerialDate.WEDNESDAY;
  118. }
  119. else if (s.equals(this.weekdays[Calendar.THURSDAY])) {
  120. return SerialDate.THURSDAY;
  121. }
  122. else {
  123. return SerialDate.FRIDAY;
  124. }
  125. }
  126. /**
  127. * Returns the actual number of days between two dates.
  128. *
  129. * @param start the start date.
  130. * @param end the end date.
  131. *
  132. * @return the number of days between the start date and the end date.
  133. */
  134. public static int dayCountActual(final SerialDate start, final SerialDate end) {
  135. return end.compare(start);
  136. }
  137. /**
  138. * Returns the number of days between the specified start and end dates,
  139. * assuming that there are thirty days in every month (that is,
  140. * corresponding to the 30/360 day-count convention).
  141. * <P>
  142. * The method handles cases where the start date is before the end date (by
  143. * switching the dates and returning a negative result).
  144. *
  145. * @param start the start date.
  146. * @param end the end date.
  147. *
  148. * @return the number of days between the two dates, assuming the 30/360 day-count convention.
  149. */
  150. public static int dayCount30(final SerialDate start, final SerialDate end) {
  151. final int d1;
  152. final int m1;
  153. final int y1;
  154. final int d2;
  155. final int m2;
  156. final int y2;
  157. if (start.isBefore(end)) { // check the order of the dates
  158. d1 = start.getDayOfMonth();
  159. m1 = start.getMonth();
  160. y1 = start.getYYYY();
  161. d2 = end.getDayOfMonth();
  162. m2 = end.getMonth();
  163. y2 = end.getYYYY();
  164. return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1);
  165. }
  166. else {
  167. return -dayCount30(end, start);
  168. }
  169. }
  170. /**
  171. * Returns the number of days between the specified start and end dates,
  172. * assuming that there are thirty days in every month, and applying the
  173. * ISDA adjustments (that is, corresponding to the 30/360 (ISDA) day-count
  174. * convention).
  175. * <P>
  176. * The method handles cases where the start date is before the end date (by
  177. * switching the dates around and returning a negative result).
  178. *
  179. * @param start the start date.
  180. * @param end the end date.
  181. *
  182. * @return The number of days between the two dates, assuming the 30/360
  183. * (ISDA) day-count convention.
  184. */
  185. public static int dayCount30ISDA(final SerialDate start, final SerialDate end) {
  186. int d1;
  187. final int m1;
  188. final int y1;
  189. int d2;
  190. final int m2;
  191. final int y2;
  192. if (start.isBefore(end)) {
  193. d1 = start.getDayOfMonth();
  194. m1 = start.getMonth();
  195. y1 = start.getYYYY();
  196. if (d1 == 31) { // first ISDA adjustment
  197. d1 = 30;
  198. }
  199. d2 = end.getDayOfMonth();
  200. m2 = end.getMonth();
  201. y2 = end.getYYYY();
  202. if ((d2 == 31) && (d1 == 30)) { // second ISDA adjustment
  203. d2 = 30;
  204. }
  205. return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1);
  206. }
  207. else if (start.isAfter(end)) {
  208. return -dayCount30ISDA(end, start);
  209. }
  210. else {
  211. return 0;
  212. }
  213. }
  214. /**
  215. * Returns the number of days between the specified start and end dates,
  216. * assuming that there are thirty days in every month, and applying the PSA
  217. * adjustments (that is, corresponding to the 30/360 (PSA) day-count convention).
  218. * The method handles cases where the start date is before the end date (by
  219. * switching the dates around and returning a negative result).
  220. *
  221. * @param start the start date.
  222. * @param end the end date.
  223. *
  224. * @return The number of days between the two dates, assuming the 30/360
  225. * (PSA) day-count convention.
  226. */
  227. public static int dayCount30PSA(final SerialDate start, final SerialDate end) {
  228. int d1;
  229. final int m1;
  230. final int y1;
  231. int d2;
  232. final int m2;
  233. final int y2;
  234. if (start.isOnOrBefore(end)) { // check the order of the dates
  235. d1 = start.getDayOfMonth();
  236. m1 = start.getMonth();
  237. y1 = start.getYYYY();
  238. if (SerialDateUtilities.isLastDayOfFebruary(start)) {
  239. d1 = 30;
  240. }
  241. if ((d1 == 31) || SerialDateUtilities.isLastDayOfFebruary(start)) {
  242. // first PSA adjustment
  243. d1 = 30;
  244. }
  245. d2 = end.getDayOfMonth();
  246. m2 = end.getMonth();
  247. y2 = end.getYYYY();
  248. if ((d2 == 31) && (d1 == 30)) { // second PSA adjustment
  249. d2 = 30;
  250. }
  251. return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1);
  252. }
  253. else {
  254. return -dayCount30PSA(end, start);
  255. }
  256. }
  257. /**
  258. * Returns the number of days between the specified start and end dates,
  259. * assuming that there are thirty days in every month, and applying the
  260. * European adjustment (that is, corresponding to the 30E/360 day-count
  261. * convention).
  262. * <P>
  263. * The method handles cases where the start date is before the end date (by
  264. * switching the dates around and returning a negative result).
  265. *
  266. * @param start the start date.
  267. * @param end the end date.
  268. *
  269. * @return the number of days between the two dates, assuming the 30E/360
  270. * day-count convention.
  271. */
  272. public static int dayCount30E(final SerialDate start, final SerialDate end) {
  273. int d1;
  274. final int m1;
  275. final int y1;
  276. int d2;
  277. final int m2;
  278. final int y2;
  279. if (start.isBefore(end)) {
  280. d1 = start.getDayOfMonth();
  281. m1 = start.getMonth();
  282. y1 = start.getYYYY();
  283. if (d1 == 31) { // first European adjustment
  284. d1 = 30;
  285. }
  286. d2 = end.getDayOfMonth();
  287. m2 = end.getMonth();
  288. y2 = end.getYYYY();
  289. if (d2 == 31) { // first European adjustment
  290. d2 = 30;
  291. }
  292. return 360 * (y2 - y1) + 30 * (m2 - m1) + (d2 - d1);
  293. }
  294. else if (start.isAfter(end)) {
  295. return -dayCount30E(end, start);
  296. }
  297. else {
  298. return 0;
  299. }
  300. }
  301. /**
  302. * Returns true if the specified date is the last day in February (that is, the
  303. * 28th in non-leap years, and the 29th in leap years).
  304. *
  305. * @param d the date to be tested.
  306. *
  307. * @return a boolean that indicates whether or not the specified date is
  308. * the last day of February.
  309. */
  310. public static boolean isLastDayOfFebruary(final SerialDate d) {
  311. final int dom;
  312. if (d.getMonth() == MonthConstants.FEBRUARY) {
  313. dom = d.getDayOfMonth();
  314. if (SerialDate.isLeapYear(d.getYYYY())) {
  315. return (dom == 29);
  316. }
  317. else {
  318. return (dom == 28);
  319. }
  320. }
  321. else { // not even February
  322. return false;
  323. }
  324. }
  325. /**
  326. * Returns the number of times that February 29 falls within the specified
  327. * date range. The result needs to correspond to the ACT/365 (Japanese)
  328. * day-count convention. The difficult cases are where the start or the
  329. * end date is Feb 29 (include or not?). Need to find out how JGBs do this
  330. * (since this is where the ACT/365 (Japanese) convention comes from ...
  331. *
  332. * @param start the start date.
  333. * @param end the end date.
  334. *
  335. * @return the number of times that February 29 occurs within the date
  336. * range.
  337. */
  338. public static int countFeb29s(final SerialDate start, final SerialDate end) {
  339. int count = 0;
  340. SerialDate feb29;
  341. final int y1;
  342. final int y2;
  343. int year;
  344. // check the order of the dates
  345. if (start.isBefore(end)) {
  346. y1 = start.getYYYY();
  347. y2 = end.getYYYY();
  348. for (year = y1; year == y2; year++) {
  349. if (SerialDate.isLeapYear(year)) {
  350. feb29 = SerialDate.createInstance(29, MonthConstants.FEBRUARY, year);
  351. if (feb29.isInRange(start, end, SerialDate.INCLUDE_SECOND)) {
  352. count++;
  353. }
  354. }
  355. }
  356. return count;
  357. }
  358. else {
  359. return countFeb29s(end, start);
  360. }
  361. }
  362. }