1/* 2* Conditions Of Use 3* 4* This software was developed by employees of the National Institute of 5* Standards and Technology (NIST), an agency of the Federal Government. 6* Pursuant to title 15 Untied States Code Section 105, works of NIST 7* employees are not subject to copyright protection in the United States 8* and are considered to be in the public domain. As a result, a formal 9* license is not needed to use the software. 10* 11* This software is provided by NIST as a service and is expressly 12* provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15* AND DATA ACCURACY. NIST does not warrant or make any representations 16* regarding the use of the software or the results thereof, including but 17* not limited to the correctness, accuracy, reliability or usefulness of 18* the software. 19* 20* Permission to use this software is contingent upon your acceptance 21* of the terms of this agreement 22* 23* . 24* 25*/ 26/******************************************************************************* 27* Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * 28*******************************************************************************/ 29package gov.nist.javax.sip.header; 30import gov.nist.core.*; 31import java.util.Calendar; 32import java.util.TimeZone; 33import java.util.Locale; 34import java.util.GregorianCalendar; 35import java.io.Serializable; 36import java.lang.IllegalArgumentException; 37 38/** 39* Implements a parser class for tracking expiration time 40* when specified as a Date value. 41*<pre> 42* From the HTTP 1.1 spec 43*14.18 Date 44* 45* The Date general-header field represents the date and time at which 46* the message was originated, having the same semantics as orig-date in 47* RFC 822. The field value is an HTTP-date, as described in section 48* 3.3.1; it MUST be sent in RFC 1123 [8]-date format. 49 50* Date = "Date" ":" HTTP-date 51* 52* An example is 53* 54* Date: Tue, 15 Nov 1994 08:12:31 GMT 55*</pre> 56* 57*@version 1.2 $Revision: 1.9 $ $Date: 2009/10/18 13:46:33 $ 58* 59*@author M. Ranganathan <br/> 60* 61* 62* 63* 64*/ 65 66public class SIPDate implements Cloneable,Serializable { 67 /** 68 * Comment for <code>serialVersionUID</code> 69 */ 70 private static final long serialVersionUID = 8544101899928346909L; 71 public static final String GMT = "GMT"; 72 public static final String MON = "Mon"; 73 public static final String TUE = "Tue"; 74 public static final String WED = "Wed"; 75 public static final String THU = "Thu"; 76 public static final String FRI = "Fri"; 77 public static final String SAT = "Sat"; 78 public static final String SUN = "Sun"; 79 public static final String JAN = "Jan"; 80 public static final String FEB = "Feb"; 81 public static final String MAR = "Mar"; 82 public static final String APR = "Apr"; 83 public static final String MAY = "May"; 84 public static final String JUN = "Jun"; 85 public static final String JUL = "Jul"; 86 public static final String AUG = "Aug"; 87 public static final String SEP = "Sep"; 88 public static final String OCT = "Oct"; 89 public static final String NOV = "Nov"; 90 public static final String DEC = "Dec"; 91 92 /** sipWkDay member 93 */ 94 protected String sipWkDay; 95 96 /** sipMonth member 97 */ 98 protected String sipMonth; 99 100 /** wkday member 101 */ 102 protected int wkday; 103 104 /** day member 105 */ 106 protected int day; 107 108 /** month member 109 */ 110 protected int month; 111 112 /** year member 113 */ 114 protected int year; 115 116 /** hour member 117 */ 118 protected int hour; 119 120 /** minute member 121 */ 122 protected int minute; 123 124 /** second member 125 */ 126 protected int second; 127 128 /** javaCal member 129 */ 130 private java.util.Calendar javaCal; 131 132 /** equality check. 133 * 134 *@return true if the two date fields are equals 135 */ 136 public boolean equals(Object that){ 137 if (that.getClass() != this.getClass())return false; 138 SIPDate other = (SIPDate)that; 139 return this.wkday == other.wkday && 140 this.day == other.day && 141 this.month == other.month && 142 this.year == other.year && 143 this.hour == other.hour && 144 this.minute == other.minute && 145 this.second == other.second; 146 } 147 148 /** 149 * Initializer, sets all the fields to invalid values. 150 */ 151 public SIPDate() { 152 wkday = -1; 153 day = -1; 154 month = -1; 155 year = -1; 156 hour = -1; 157 minute = -1; 158 second = -1; 159 javaCal = null; 160 } 161 162 /** 163 * Construct a SIP date from the time offset given in miliseconds 164 * @param timeMillis long to set 165 */ 166 public SIPDate(long timeMillis) { 167 javaCal = 168 new GregorianCalendar( 169 TimeZone.getTimeZone("GMT:0"), 170 Locale.getDefault()); 171 java.util.Date date = new java.util.Date(timeMillis); 172 javaCal.setTime(date); 173 wkday = javaCal.get(Calendar.DAY_OF_WEEK); 174 switch (wkday) { 175 case Calendar.MONDAY : 176 sipWkDay = MON; 177 break; 178 case Calendar.TUESDAY : 179 sipWkDay = TUE; 180 break; 181 case Calendar.WEDNESDAY : 182 sipWkDay = WED; 183 break; 184 case Calendar.THURSDAY : 185 sipWkDay = THU; 186 break; 187 case Calendar.FRIDAY : 188 sipWkDay = FRI; 189 break; 190 case Calendar.SATURDAY : 191 sipWkDay = SAT; 192 break; 193 case Calendar.SUNDAY : 194 sipWkDay = SUN; 195 break; 196 default : 197 InternalErrorHandler.handleException( 198 "No date map for wkday " + wkday); 199 } 200 201 day = javaCal.get(Calendar.DAY_OF_MONTH); 202 month = javaCal.get(Calendar.MONTH); 203 switch (month) { 204 case Calendar.JANUARY : 205 sipMonth = JAN; 206 break; 207 case Calendar.FEBRUARY : 208 sipMonth = FEB; 209 break; 210 case Calendar.MARCH : 211 sipMonth = MAR; 212 break; 213 case Calendar.APRIL : 214 sipMonth = APR; 215 break; 216 case Calendar.MAY : 217 sipMonth = MAY; 218 break; 219 case Calendar.JUNE : 220 sipMonth = JUN; 221 break; 222 case Calendar.JULY : 223 sipMonth = JUL; 224 break; 225 case Calendar.AUGUST : 226 sipMonth = AUG; 227 break; 228 case Calendar.SEPTEMBER : 229 sipMonth = SEP; 230 break; 231 case Calendar.OCTOBER : 232 sipMonth = OCT; 233 break; 234 case Calendar.NOVEMBER : 235 sipMonth = NOV; 236 break; 237 case Calendar.DECEMBER : 238 sipMonth = DEC; 239 break; 240 default : 241 InternalErrorHandler.handleException( 242 "No date map for month " + month); 243 } 244 year = javaCal.get(Calendar.YEAR); 245 // Bug report by Bruno Konik 246 hour = javaCal.get(Calendar.HOUR_OF_DAY); 247 minute = javaCal.get(Calendar.MINUTE); 248 second = javaCal.get(Calendar.SECOND); 249 } 250 251 /** 252 * Get canonical string representation. 253 * @return String 254 */ 255 public String encode() { 256 257 String dayString; 258 if (day < 10) { 259 dayString = "0" + day; 260 } else 261 dayString = "" + day; 262 263 String hourString; 264 if (hour < 10) { 265 hourString = "0" + hour; 266 } else 267 hourString = "" + hour; 268 269 String minuteString; 270 if (minute < 10) { 271 minuteString = "0" + minute; 272 } else 273 minuteString = "" + minute; 274 275 String secondString; 276 if (second < 10) { 277 secondString = "0" + second; 278 } else 279 secondString = "" + second; 280 281 String encoding = ""; 282 283 if (sipWkDay != null) 284 encoding += sipWkDay + Separators.COMMA + Separators.SP; 285 286 encoding += dayString + Separators.SP; 287 288 if (sipMonth != null) 289 encoding += sipMonth + Separators.SP; 290 291 encoding += year 292 + Separators.SP 293 + hourString 294 + Separators.COLON 295 + minuteString 296 + Separators.COLON 297 + secondString 298 + Separators.SP 299 + GMT; 300 301 return encoding; 302 } 303 304 /** 305 * The only accessor we allow is to the java calendar record. 306 * All other fields are for this package only. 307 * @return Calendar 308 */ 309 public java.util.Calendar getJavaCal() { 310 if (javaCal == null) 311 setJavaCal(); 312 return javaCal; 313 } 314 315 /** get the WkDay field 316 * @return String 317 */ 318 public String getWkday() { 319 return sipWkDay; 320 } 321 322 /** get the month 323 * @return String 324 */ 325 public String getMonth() { 326 return sipMonth; 327 } 328 329 /** get the hour 330 * @return int 331 */ 332 public int getHour() { 333 return hour; 334 } 335 336 /** get the minute 337 * @return int 338 */ 339 public int getMinute() { 340 return minute; 341 } 342 343 /** get the second 344 * @return int 345 */ 346 public int getSecond() { 347 return second; 348 } 349 350 /** 351 * convert the SIP Date of this structure to a Java Date. 352 * SIP Dates are forced to be GMT. Stores the converted time 353 * as a java Calendar class. 354 */ 355 private void setJavaCal() { 356 javaCal = 357 new GregorianCalendar( 358 TimeZone.getTimeZone("GMT:0"), 359 Locale.getDefault()); 360 if (year != -1) 361 javaCal.set(Calendar.YEAR, year); 362 if (day != -1) 363 javaCal.set(Calendar.DAY_OF_MONTH, day); 364 if (month != -1) 365 javaCal.set(Calendar.MONTH, month); 366 if (wkday != -1) 367 javaCal.set(Calendar.DAY_OF_WEEK, wkday); 368 if (hour != -1) 369 javaCal.set(Calendar.HOUR, hour); 370 if (minute != -1) 371 javaCal.set(Calendar.MINUTE, minute); 372 if (second != -1) 373 javaCal.set(Calendar.SECOND, second); 374 } 375 376 /** 377 * Set the wkday member 378 * @param w String to set 379 * @throws IllegalArgumentException if w is not a valid day. 380 */ 381 public void setWkday(String w) throws IllegalArgumentException { 382 sipWkDay = w; 383 if (sipWkDay.compareToIgnoreCase(MON) == 0) { 384 wkday = Calendar.MONDAY; 385 } else if (sipWkDay.compareToIgnoreCase(TUE) == 0) { 386 wkday = Calendar.TUESDAY; 387 } else if (sipWkDay.compareToIgnoreCase(WED) == 0) { 388 wkday = Calendar.WEDNESDAY; 389 } else if (sipWkDay.compareToIgnoreCase(THU) == 0) { 390 wkday = Calendar.THURSDAY; 391 } else if (sipWkDay.compareToIgnoreCase(FRI) == 0) { 392 wkday = Calendar.FRIDAY; 393 } else if (sipWkDay.compareToIgnoreCase(SAT) == 0) { 394 wkday = Calendar.SATURDAY; 395 } else if (sipWkDay.compareToIgnoreCase(SUN) == 0) { 396 wkday = Calendar.SUNDAY; 397 } else { 398 throw new IllegalArgumentException("Illegal Week day :" + w); 399 } 400 } 401 402 /** 403 * Set the day member 404 * @param d int to set 405 * @throws IllegalArgumentException if d is not a valid day 406 */ 407 public void setDay(int d) throws IllegalArgumentException { 408 if (d < 1 || d > 31) 409 throw new IllegalArgumentException( 410 "Illegal Day of the month " + Integer.toString(d)); 411 day = d; 412 } 413 414 /** 415 * Set the month member 416 * @param m String to set. 417 * @throws IllegalArgumentException if m is not a valid month 418 */ 419 public void setMonth(String m) throws IllegalArgumentException { 420 sipMonth = m; 421 if (sipMonth.compareToIgnoreCase(JAN) == 0) { 422 month = Calendar.JANUARY; 423 } else if (sipMonth.compareToIgnoreCase(FEB) == 0) { 424 month = Calendar.FEBRUARY; 425 } else if (sipMonth.compareToIgnoreCase(MAR) == 0) { 426 month = Calendar.MARCH; 427 } else if (sipMonth.compareToIgnoreCase(APR) == 0) { 428 month = Calendar.APRIL; 429 } else if (sipMonth.compareToIgnoreCase(MAY) == 0) { 430 month = Calendar.MAY; 431 } else if (sipMonth.compareToIgnoreCase(JUN) == 0) { 432 month = Calendar.JUNE; 433 } else if (sipMonth.compareToIgnoreCase(JUL) == 0) { 434 month = Calendar.JULY; 435 } else if (sipMonth.compareToIgnoreCase(AUG) == 0) { 436 month = Calendar.AUGUST; 437 } else if (sipMonth.compareToIgnoreCase(SEP) == 0) { 438 month = Calendar.SEPTEMBER; 439 } else if (sipMonth.compareToIgnoreCase(OCT) == 0) { 440 month = Calendar.OCTOBER; 441 } else if (sipMonth.compareToIgnoreCase(NOV) == 0) { 442 month = Calendar.NOVEMBER; 443 } else if (sipMonth.compareToIgnoreCase(DEC) == 0) { 444 month = Calendar.DECEMBER; 445 } else { 446 throw new IllegalArgumentException("Illegal Month :" + m); 447 } 448 } 449 450 /** 451 * Set the year member 452 * @param y int to set 453 * @throws IllegalArgumentException if y is not a valid year. 454 */ 455 public void setYear(int y) throws IllegalArgumentException { 456 if (y < 0) 457 throw new IllegalArgumentException("Illegal year : " + y); 458 javaCal = null; 459 year = y; 460 } 461 462 /** 463 * Get the year member. 464 */ 465 public int getYear() { 466 return year; 467 } 468 469 /** 470 * Set the hour member 471 * @param h int to set 472 * @throws IllegalArgumentException if h is not a valid hour. 473 */ 474 public void setHour(int h) throws IllegalArgumentException { 475 if (h < 0 || h > 24) 476 throw new IllegalArgumentException("Illegal hour : " + h); 477 javaCal = null; 478 hour = h; 479 } 480 481 /** 482 * Set the minute member 483 * @param m int to set 484 * @throws IllegalArgumentException if m is not a valid minute 485 */ 486 public void setMinute(int m) throws IllegalArgumentException { 487 if (m < 0 || m >= 60) 488 throw new IllegalArgumentException( 489 "Illegal minute : " + (Integer.toString(m))); 490 javaCal = null; 491 minute = m; 492 } 493 494 /** 495 * Set the second member 496 * @param s int to set 497 * @throws IllegalArgumentException if s is not a valid second 498 */ 499 public void setSecond(int s) throws IllegalArgumentException { 500 if (s < 0 || s >= 60) 501 throw new IllegalArgumentException( 502 "Illegal second : " + Integer.toString(s)); 503 javaCal = null; 504 second = s; 505 } 506 507 /** Get the time offset from the current time. 508 * 509 *@return offset from the current time. 510 */ 511 public int getDeltaSeconds() { 512 // long ctime = this.getJavaCal().getTimeInMillis(); 513 long ctime = this.getJavaCal().getTime().getTime(); 514 return (int) (ctime - System.currentTimeMillis()) / 1000; 515 } 516 517 public Object clone() { 518 SIPDate retval; 519 try { 520 retval = (SIPDate) super.clone(); 521 } catch (CloneNotSupportedException e) { 522 throw new RuntimeException("Internal error"); 523 } 524 if (javaCal != null) 525 retval.javaCal = (java.util.Calendar) javaCal.clone(); 526 return retval; 527 } 528} 529/* 530 * $Log: SIPDate.java,v $ 531 * Revision 1.9 2009/10/18 13:46:33 deruelle_jean 532 * FindBugs Fixes (Category Performance Warnings) 533 * 534 * Issue number: 535 * Obtained from: 536 * Submitted by: Jean Deruelle 537 * Reviewed by: 538 * 539 * Revision 1.8 2009/07/17 18:57:37 emcho 540 * Converts indentation tabs to spaces so that we have a uniform indentation policy in the whole project. 541 * 542 * Revision 1.7 2006/07/13 09:01:16 mranga 543 * Issue number: 544 * Obtained from: 545 * Submitted by: jeroen van bemmel 546 * Reviewed by: mranga 547 * Moved some changes from jain-sip-1.2 to java.net 548 * 549 * CVS: ---------------------------------------------------------------------- 550 * CVS: Issue number: 551 * CVS: If this change addresses one or more issues, 552 * CVS: then enter the issue number(s) here. 553 * CVS: Obtained from: 554 * CVS: If this change has been taken from another system, 555 * CVS: then name the system in this line, otherwise delete it. 556 * CVS: Submitted by: 557 * CVS: If this code has been contributed to the project by someone else; i.e., 558 * CVS: they sent us a patch or a set of diffs, then include their name/email 559 * CVS: address here. If this is your work then delete this line. 560 * CVS: Reviewed by: 561 * CVS: If we are doing pre-commit code reviews and someone else has 562 * CVS: reviewed your changes, include their name(s) here. 563 * CVS: If you have not had it reviewed then delete this line. 564 * 565 * Revision 1.3 2006/06/19 06:47:26 mranga 566 * javadoc fixups 567 * 568 * Revision 1.2 2006/06/16 15:26:28 mranga 569 * Added NIST disclaimer to all public domain files. Clean up some javadoc. Fixed a leak 570 * 571 * Revision 1.1.1.1 2005/10/04 17:12:35 mranga 572 * 573 * Import 574 * 575 * 576 * Revision 1.5 2005/04/16 20:35:10 dmuresan 577 * SIPDate made cloneable. 578 * 579 * Revision 1.4 2004/07/28 14:41:53 mranga 580 * Submitted by: mranga 581 * 582 * fixed equality check for SIPDate. 583 * 584 * Revision 1.3 2004/04/05 21:46:08 mranga 585 * Submitted by: Bruno Konik 586 * Reviewed by: mranga 587 * 588 * Revision 1.2 2004/01/22 13:26:29 sverker 589 * Issue number: 590 * Obtained from: 591 * Submitted by: sverker 592 * Reviewed by: mranga 593 * 594 * Major reformat of code to conform with style guide. Resolved compiler and javadoc warnings. Added CVS tags. 595 * 596 * CVS: ---------------------------------------------------------------------- 597 * CVS: Issue number: 598 * CVS: If this change addresses one or more issues, 599 * CVS: then enter the issue number(s) here. 600 * CVS: Obtained from: 601 * CVS: If this change has been taken from another system, 602 * CVS: then name the system in this line, otherwise delete it. 603 * CVS: Submitted by: 604 * CVS: If this code has been contributed to the project by someone else; i.e., 605 * CVS: they sent us a patch or a set of diffs, then include their name/email 606 * CVS: address here. If this is your work then delete this line. 607 * CVS: Reviewed by: 608 * CVS: If we are doing pre-commit code reviews and someone else has 609 * CVS: reviewed your changes, include their name(s) here. 610 * CVS: If you have not had it reviewed then delete this line. 611 * 612 */ 613