View Javadoc

1   // Copyright 2006-2007, by the California Institute of Technology.
2   // ALL RIGHTS RESERVED. United States Government Sponsorship acknowledged.
3   // Any commercial use must be negotiated with the Office of Technology Transfer
4   // at the California Institute of Technology.
5   //
6   // This software is subject to U. S. export control laws and regulations
7   // (22 C.F.R. 120-130 and 15 C.F.R. 730-774). To the extent that the software
8   // is subject to U.S. export control laws and regulations, the recipient has
9   // the responsibility to obtain export licenses or other export authority as
10  // may be required before exporting such information to foreign countries or
11  // providing access to foreign nationals.
12  //
13  // $Id$ 
14  //
15  
16  package gov.nasa.pds.tools.label;
17  
18  import java.text.ParseException;
19  import java.text.ParsePosition;
20  import java.text.SimpleDateFormat;
21  import java.util.Calendar;
22  import java.util.Date;
23  import java.util.GregorianCalendar;
24  
25  /***
26   * @author pramirez
27   * @version $Revision$
28   * 
29   */
30  public class DateTimeFormatter {
31      private static SimpleDateFormat year = new SimpleDateFormat("yyyy");
32      private static SimpleDateFormat ym = new SimpleDateFormat("yyyy-MM");
33      private static SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
34      private static SimpleDateFormat doy = new SimpleDateFormat("yyyy-DDD");
35      private static SimpleDateFormat hour = new SimpleDateFormat("HH");
36      private static SimpleDateFormat minute = new SimpleDateFormat(":mm");
37      private static SimpleDateFormat second = new SimpleDateFormat(":ss");
38      
39      static {
40      	year.setLenient(false);
41      	ym.setLenient(false);
42      	ymd.setLenient(false);
43          doy.setLenient(false);
44          hour.setLenient(false);
45          minute.setLenient(false);
46          second.setLenient(false);
47      }
48      
49      public static Date parse(String datetime) throws ParseException {
50      	int previousPosition = 0;
51      	long time = 0;
52          ParsePosition position = new ParsePosition(0);
53          Date workingDate = null;
54          Calendar workingCalendar = Calendar.getInstance();
55          SimpleDateFormat dateFormatter = null;
56          
57          String[] date = datetime.split("T");
58          String currentDate = date[0];
59          String currentTime = null;
60          if (date.length == 2)
61          	currentTime = date[1];
62          
63          if (currentDate.length() == 4)
64          	dateFormatter = year;
65          else if (currentDate.length() == 7)
66          	dateFormatter = ym;
67          else if (currentDate.length() == 10)
68          	dateFormatter = ymd;
69          else if (currentDate.length() == 8)
70          	dateFormatter = doy;
71          else
72          	throw new ParseException("Could not create a date from " + datetime, previousPosition);
73          
74          workingDate = dateFormatter.parse(currentDate, position);
75          if (workingDate == null)
76          	throw new ParseException("Could not create a date from " + datetime, previousPosition);
77          else {
78              workingCalendar.setTime(workingDate);
79              time += workingCalendar.getTimeInMillis();
80          }
81          
82          position.setIndex(0);
83          //Now we should be at the time string if there is any
84          if (currentTime != null) {
85  	        //First will come the hours
86  	        if (position.getIndex() < currentTime.length()) {
87  	            workingDate = hour.parse(currentTime, position);
88  	            if (workingDate == null || position.getIndex() - previousPosition != 2)
89  	                throw new ParseException("Could not create a date from " + datetime, previousPosition);
90  	            else {
91  	                //Date had an hour. Set and move on
92  	                workingCalendar.setTime(workingDate);
93  	                time += workingCalendar.get(Calendar.HOUR_OF_DAY)*60*60*1000;
94  	                previousPosition = position.getIndex();
95  	            }
96  	        }
97  
98  	        //Check for minutes
99  	        if (position.getIndex() < currentTime.length() && currentTime.charAt(position.getIndex()) != 'Z') {
100 	            workingDate = minute.parse(currentTime, position);
101 	            if (workingDate == null || position.getIndex() - previousPosition != 3)
102 	                throw new ParseException("Could not create a date from " + datetime, previousPosition);
103 	            else {
104 	                //Date had minutes. Set and move on
105 	                workingCalendar.setTime(workingDate);
106 	                time += workingCalendar.get(Calendar.MINUTE)*60*1000;
107 	                previousPosition = position.getIndex();
108 	            }
109 	        }
110 
111 	        //Check for seconds
112 	        if (position.getIndex() < currentTime.length() && currentTime.charAt(position.getIndex()) != 'Z') {
113 	            workingDate = second.parse(currentTime, position);
114 	            if (workingDate == null || position.getIndex() - previousPosition != 3)
115 	                throw new ParseException("Could not create a date from " + datetime, previousPosition);
116 	            else {
117 	                //Date had seconds. Set and move on
118 	                workingCalendar.setTime(workingDate);
119 	                time += workingCalendar.get(Calendar.SECOND)*1000;
120 	                previousPosition = position.getIndex();
121 	            }
122 	        }
123 
124 	        //Check for fractional seconds
125 	        if (position.getIndex() < currentTime.length() && currentTime.charAt(position.getIndex()) != 'Z') {
126 	        	String fractional = currentTime.substring(position.getIndex() + 1);
127 	        	if (fractional.charAt(fractional.length() - 1) == 'Z')
128 	        		fractional = fractional.substring(0, fractional.length() -2);
129 	        	
130 	        	if (fractional.length() > 6)
131 	        		throw new ParseException("Could not create a date from " + datetime, previousPosition);
132 	        	
133 	        	//TODO: Update to add milliseconds into time
134 	        	try {
135 	        		Integer.parseInt(fractional);
136 	        	} catch (NumberFormatException nfe) {
137 	        		throw new ParseException("Could not create a date from " + datetime, previousPosition);
138 	        	}
139 	        }
140         }
141         
142         //Date is not actually calculated in a calendar until you make a call to getTime.
143         //Must check that date is fine.
144         GregorianCalendar calendar = new GregorianCalendar();
145         calendar.setTimeInMillis(time);
146         
147         return calendar.getTime();
148     }
149 }