Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* ************************************************************************
  #
  #  DivConq
  #
  #  http://divconq.com/
  #
  #  Copyright:
  #    Copyright 2014 eTimeline, LLC. All rights reserved.
  #
 #  License:
 #    See the license.txt file in the project's top-level directory for details.
 #
 #  Authors:
 #    * Andy White
 #
 ************************************************************************ */
 
 /*
  * DateParser.java February 2001
  *
  * Copyright (C) 2001, Niall Gallagher <niallg@users.sf.net>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
  * implied. See the License for the specific language governing 
  * permissions and limitations under the License.
  */
  
 package divconq.www.http.parse;
 
 import static java.util.Calendar.DAY_OF_MONTH;
 import static java.util.Calendar.DAY_OF_WEEK;
 import static java.util.Calendar.HOUR_OF_DAY;
 import static java.util.Calendar.MILLISECOND;
 import static java.util.Calendar.MINUTE;
 import static java.util.Calendar.MONTH;
 import static java.util.Calendar.SECOND;
 import static java.util.Calendar.YEAR;
 
 
This is used to create a Parser for the HTTP date format. This will parse the 3 formats that are acceptable for the HTTP/1.1 date. The three formats that are acceptable for the HTTP-date are
 Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
 Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
 Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
 

This can also parse the date in ms as retrived from the System's System.currentTimeMillis method. This has a parse method for a long which will do the same as the parse(String). Once the date has been parsed there are two methods that allow the date to be represented, the toLong method converts the date to a long and the toString method will convert the date into a String.

This produces the same string as the SimpleDateFormat.format using the pattern "EEE, dd MMM yyyy hh:mm:ss 'GMT'". This will however do the job faster as it does not take arbitrary inputs.

Author(s):
Niall Gallagher
 
 public class DateParser extends Parser {

   
Ensure that the time zone for dates if set to GMT.
 
    private static final TimeZone ZONE = TimeZone.getTimeZone("GMT");

   
Contains the possible days of the week for RFC 1123.
 
    private static final String WKDAYS[] = { "Mon""Tue""Wed""Thu""Fri""Sat""Sun" };

   
Contains the possible days of the week for RFC 850.
 
    private static final String WEEKDAYS[] = { "Monday""Tuesday""Wednesday""Thursday""Friday""Saturday""Sunday" };

   
Contains the possible months in the year for HTTP-date.
 
    private static final String MONTHS[] = { "Jan""Feb""Mar""Apr""May""Jun""Jul""Aug""Sep""Oct""Nov""Dec" };
  
   
Used as an index into the months array to get the month.
   private int month;
      
   
Represents the decimal value of the date such as 1977.
   private int year;
   
   
Represents the decimal value of the date such as 18.
   private int day;
   
   
Used as an index into the weekdays array to get the weekday.
   private int weekday;
   
   
Represents the decimal value of the hour such as 24.
   private int hour;

   
Represents the decimal value of the minute.
   private int mins;
   
   
Represents the decimal value for the second.
   private int secs;

   
The parser contains this method so that the a date does not have to be parsed from System.currentTimeMillis. This returns a date using a DataParser.parse(long) method invocation.

Returns:
this returns a RFC 1123 date for the current time
   public static String getDate() {
      long time = System.currentTimeMillis();
      return new DateParser(time).toString();
   }

   
The default constructor will create a parser that can parse Strings that contain dates in the form of RFC 1123, RFC 850 or asctime. If the dates that are to be parsed are not in the form of one of these date encodings the results of this parser will be random.
   public DateParser(){
      this.init();         
   }  
 
   
This constructor will conveniently parse the long argument in the constructor. This can also be done by first calling the no-arg constructor and then using the parse method.

This will then set this object to one that uses the RFC 1123 format for a date.

Parameters:
date the date to be parsed
 
   public DateParser(long date){
      this();
      parse(date);
   }

   
This constructor will conveniently parse the String argument in the constructor. This can also be done by first calling the no-arg constructor and then using the parse method.

This will then set this object to one that uses the RFC 1123 format for a date.

Parameters:
date the date to be parsed
   
   public DateParser(String date)  {      
      this();
      parse(date);
   } 

   
This is used to extract the date from a long. If this method is given the value of the date as a long it will construct the RFC 1123 date as required by RFC 2616 sec 3.3.

This saves time on parsing a String that is encoded in the HTTP-date format. The date given must be positive, if the date given is not a positive 'long' then the results of this method is random/unknown.

Parameters:
date the date to be parsed
   
   public void parse(long date){
      Calendar calendar = Calendar.getInstance();
      calendar.setTimeInMillis(date); 
      
       = calendar.get();
       = calendar.get();
       = calendar.get();
       = calendar.get();
       = calendar.get();
       = calendar.get();
       = calendar.get();
       =  > 11 ? 11: ;
       = (+5) % 7;
   }
   
   
Convenience method used to convert the specified HTTP date in to a long representing the time. This is used when a single method is required to convert a HTTP date format to a usable long value for use in creating Date objects.

Parameters:
date the date specified in on of the HTTP date formats
Returns:
the date value as a long value in milliseconds
   public long convert(String date) {
      parse(date);
      return toLong();
      
   }
   
   
Convenience method used to convert the specified long date in to a HTTP date format. This is used when a single method is required to convert a long data value in milliseconds to a HTTP date value.

Parameters:
date the date specified as a long of milliseconds
Returns:
the date represented in the HTTP date format RFC 1123
   public String convert(long date) {
      parse(date);
      return toString();
   }

   
This is used to reset the date and the buffer variables for this DateParser. Every in is set to the value of 0.
   protected void init() {
       =  =  = 
       =  =  = 
       =  = 0;
   }

   
This is used to parse the contents of the buf. This checks the fourth char of the buffer to see what it contains. Invariably a date format belonging to RFC 1123 will have a ',' character in position 4, a date format belonging to asctime will have a ' ' character in position 4 and if neither of these characters are found at position 4 then it is assumed that the date is in the RFC 850 fromat, however it may not be.
   protected void parse(){
      if(.<4)return;
      if([3]==','){
         rfc1123();
      }else if([3]==' '){
         asctime();
      }else{
         rfc850();
      } 
   }

   
This will parse a date that is in the form of an RFC 1123 date. This date format is the date format that is to be used with all applications that are HTTP/1.1 compliant. The RFC 1123 date format is
 rfc1123 = 'wkday "," SP date1 SP time SP GMT'. 
 date1 = '2DIGIT SP month SP 4DIGIT' and finally
 time = '2DIGIT ":" 2DIGIT ":" 2DIGIT'. 
 
   private void rfc1123(){
      wkday();
      +=2;
      date1();
      ++;
      time();      
   }  
 
   
This will parse a date that is in the form of an RFC 850 date. This date format is the date format that is to be used with some applications that are HTTP/1.0 compliant. The RFC 1123 date format is
 rfc850 = 'weekday "," SP date2 SP time SP GMT'. 
 date2 = '2DIGIT "-" month "-" 2DIGIT' and finally
 time = '2DIGIT ":" 2DIGIT ":" 2DIGIT'. 
 
   private void rfc850() {
      weekday();
      +=2;
      date2();
      ++;
      time();
   }

   
This will parse a date that is in the form of an asctime date. This date format is the date format that is to be used with some applications that are HTTP/1.0 compliant. The RFC 1123 date format is
 asctime = 'weekday SP date3 SP time SP 4DIGIT'. 
 date3 = 'month SP (2DIGIT | (SP 1DIGIT))' and 
 time = '2DIGIT ":" 2DIGIT ":" 2DIGIT'. 
 
   private void asctime(){
      wkday();
      ++;
      date3();
      ++;
      time();
      ++;
      year4();
   }

   
This is the date1 format of a date that is used by the RFC 1123 date format. This date is
 date1 = '2DIGIT SP month SP 4DIGIT'.
 example '02 Jun 1982'.
 
   private void date1(){
      day();
      ++;
      month();
      ++;
      year4();
   }

   
This is the date2 format of a date that is used by the RFC 850 date format. This date is
 date2 = '2DIGIT "-" month "-" 2DIGIT'
 example '02-Jun-82'.
 
   
   private void date2(){
      day();
      ++;
      month();
      ++;
      year2();
   }

   
This is the date3 format of a date that is used by the asctime date format. This date is
 date3 = 'month SP (2DIGIT | (SP 1DIGIT))' 
 example 'Jun  2'.
 
 
   private void date3(){
      month();
      ++;
      day();
   }

   
This is used to parse a consecutive set of digit characters to create the day of the week. This will tolerate a space on front of the digits thiswill allow all date formats including asctime to use this to get the day. This may parse more than 2 digits, however if there are more than 2 digits the date format is incorrect anyway.
   private void day(){
      if(space([])){
         ++;
      }
      while( < ){
         if(!digit([])){
            break;
         }
          *= 10;
          += [];
          -= '0';
         ++;
      }    
   }

   
This is used to get the year from a set of digit characters. This is used to parse years that are of the form of 2 digits (e.g 82) however this will assume that any dates that are in 2 digit format are dates for the 2000 th milleneum so 01 will be 2001.

This may parse more than 2 digits but if there are more than 2 digits in a row then the date format is incorrect anyway.

   private void year2(){      
      int mill = 2000;  /* milleneum */
      int cent = 0;   /* century */
      while( < ){
         if(!digit([])){            
            break;
         }
         cent *= 10;
         cent += [];
         cent -= '0';
         ++;
      }  
      mill+cent/* result 4 digits*/
   }

   
This is used to get the year from a set of digit characters. This is used to parse years that are of the form of 4 digits (e.g 1982).

This may parse more than 4 digits but if there are more than 2 digits in a row then the date format is incorrect anyway.

   private void year4() {
      while( < ){
         if(!digit([])){
            break;
         }
          *= 10;
          += [];
          -= '0';
         ++;
      }      
   }

   
This is used to parse the time for a HTTP-date. The time for a HTTP-date is in the form 00:00:00 that is
 time = '2DIGIT ":" 2DIGIT ":" 2DIGIT' so this will
 read only a time of that form, although this will
 parse time = '2DIGIT CHAR 2DIGIT CHAR 2DIGIT'.
 
   private void time(){
      hours();
      ++;
      mins();
      ++;
      secs();
   }

   
This is used to initialize the hour. This will read a consecutive sequence of digit characters and convert them into a decimal number to represent the hour that this date represents.

This may parse more than 2 digits but if there are more than 2 digits the date is already incorrect.

   private void hours(){
      while( < ){
         if(!digit([])){
            break;
         }
          *= 10;
          += [];
          -= '0';
         ++;
      }
   }

   
This is used to initialize the mins. This will read a consecutive sequence of digit characters and convert them into a decimal number to represent the mins that this date represents.

This may parse more than 2 digits but if there are more than 2 digits the date is already incorrect.

   private void mins(){
      while( < ){
         if(!digit([])){
            break;
         }
          *= 10;
          += [];
          -= '0';
         ++;
      }
   }

   
This is used to initialize the secs. This will read a consecutive sequence of digit characters and convert them into a decimal number to represent the secs that this date represents.

This may parse more than 2 digits but if there are more than 2 digits the date is already incorrect

   private void secs(){
      while( < ){
         if(!digit([])){
            break;
         }
          *= 10;
          += [];
          -= '0';
         ++;
      }
   }

   
This is used to read the week day of HTTP-date. The shorthand day (e.g Mon for Monday) is used by the RFC 1123 and asctime date formats. This will simply try to read each day from the buffer, when the day is read successfully then the index of that day is saved.
    
   private void wkday(){
      for(int i =0; i < .;i++){
         if(skip([i])){
             = i;
            return;
         }      
      }
   }

   
This is used to read the week day of HTTP-date. This format is used by the RFC 850 date format. This will simply try to read each day from the buffer, when the day is read successfully then the index of that day is saved.
 
   private void weekday(){
      for(int i =0; i < .;i++){
         if(skip([i])){
             = i;
            return;
         }      
      }     
   }

   
This is used to read the month of HTTP-date. This will simply try to read each month from the buffer, when the month is read successfully then the index of that month is saved.
   private void month(){
      for(int i =0; i < .;i++){
         if(skip([i])){
             = i;
            return;
         }      
      } 
   }
   
   
This is used to append the date in RFC 1123 format to the given string builder. This will append the date and a trailing space character to the buffer. Dates like the following are appended.
 Tue, 02 Jun 1982 
 
. For performance reasons a string builder is used. This avoids an unneeded synchronization caused by the string buffers.

Parameters:
builder this is the builder to append the date to
   private void date(StringBuilder builder) {
      builder.append([]);
      builder.append(", ");
      
      if( <= 9) {
         builder.append('0');
      }
      builder.append();
      builder.append(' ');
      builder.append([]);
      builder.append(' ');
      builder.append();
      builder.append(' ');
   }
   
   
This is used to append the time in RFC 1123 format to the given string builder. This will append the time and a trailing space character to the buffer. Times like the following are appended.
 23:59:59
 
. For performance reasons a string builder is used. This avoids an unneeded synchronization caused by the string buffers.

Parameters:
builder this is the builder to write the time to
   private void time(StringBuilder builder) {
      if( <= 9) {
         builder.append('0');
      }
      builder.append();
      builder.append(':');
      
      if( <= 9) {
         builder.append('0');
      }
      builder.append();
      builder.append(':');
      
      if( <= 9) {
         builder.append('0');
      }
      builder.append();
      builder.append(' ');
   }
   
   
This is used to append the time zone to the provided appender. For HTTP the dates should always be in GMT format. So this will simply append the "GMT" string to the end of the builder.

Parameters:
builder this builder to append the time zone to
   private void zone(StringBuilder builder) {
      builder.append("GMT");
   }

   
This returns the date in as a long, given the exact time this will use the java.util.Date to parse this date into a long. The GregorianCalendar uses the method getTime which produces the Date object from this the getTime returns the long

Returns:
the date parsed as a long
   public long toLong() {
      Calendar calendar = Calendar.getInstance(); /* GMT*/
      calendar.set(,);
      calendar.set(, 0);
      return calendar.getTime().getTime();   
   }

   
This prints the date in the format of a RFC 1123 date. Example
 Tue, 02 Jun 1982 23:59:59 GMT
 
. This uses a StringBuffer to accumulate the various Strings/ints to form the resulting date value. The resulting date value is the one required by RFC 2616.

The HTTP date must be in the form of RFC 1123. The hours, minutes and seconds are appended with the 0 character if they are less than 9 i.e. if they do not have two digits.

Returns:
the date in RFC 1123 format
   public String toString(){
      StringBuilder builder = new StringBuilder(30);
      
      date(builder);
      time(builder);
      zone(builder);
      
      return builder.toString();
   }
New to GrepCode? Check out our FAQ X