Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ISO8601DateParser |
|
| 1.3333333333333333;1.333 |
1 | /* | |
2 | * Copyright 1999,2006 The Apache Software Foundation. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | package org.apache.commons.feedparser.tools; | |
18 | ||
19 | import java.text.SimpleDateFormat; | |
20 | import java.util.Date; | |
21 | import java.util.Locale; | |
22 | import java.util.TimeZone; | |
23 | ||
24 | /** | |
25 | * ISO 8601 date parsing utility. Designed for parsing the ISO subset used in | |
26 | * Dublin Core, RSS 1.0, and Atom. | |
27 | * | |
28 | * @author <a href="mailto:burton@apache.org">Kevin A. Burton (burtonator)</a> | |
29 | * @version $Id: ISO8601DateParser.java 373572 2006-01-30 19:28:41Z mvdb $ | |
30 | */ | |
31 | 0 | public class ISO8601DateParser { |
32 | ||
33 | // 2004-06-14T19:GMT20:30Z | |
34 | // 2004-06-20T06:GMT22:01Z | |
35 | ||
36 | 0 | private static SimpleDateFormat df |
37 | = new SimpleDateFormat( "yyyy-MM-dd'T'hh:mm:ssz", Locale.ENGLISH ); | |
38 | ||
39 | // http://www.cl.cam.ac.uk/~mgk25/iso-time.html | |
40 | // | |
41 | // http://www.intertwingly.net/wiki/pie/DateTime | |
42 | // | |
43 | // http://www.w3.org/TR/NOTE-datetime | |
44 | // | |
45 | // Different standards may need different levels of granularity in the date and | |
46 | // time, so this profile defines six levels. Standards that reference this | |
47 | // profile should specify one or more of these granularities. If a given | |
48 | // standard allows more than one granularity, it should specify the meaning of | |
49 | // the dates and times with reduced precision, for example, the result of | |
50 | // comparing two dates with different precisions. | |
51 | ||
52 | // The formats are as follows. Exactly the components shown here must be | |
53 | // present, with exactly this punctuation. Note that the "T" appears literally | |
54 | // in the string, to indicate the beginning of the time element, as specified in | |
55 | // ISO 8601. | |
56 | ||
57 | // Year: | |
58 | // YYYY (eg 1997) | |
59 | // Year and month: | |
60 | // YYYY-MM (eg 1997-07) | |
61 | // Complete date: | |
62 | // YYYY-MM-DD (eg 1997-07-16) | |
63 | // Complete date plus hours and minutes: | |
64 | // YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00) | |
65 | // Complete date plus hours, minutes and seconds: | |
66 | // YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00) | |
67 | // Complete date plus hours, minutes, seconds and a decimal fraction of a | |
68 | // second | |
69 | // YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00) | |
70 | ||
71 | // where: | |
72 | ||
73 | // YYYY = four-digit year | |
74 | // MM = two-digit month (01=January, etc.) | |
75 | // DD = two-digit day of month (01 through 31) | |
76 | // hh = two digits of hour (00 through 23) (am/pm NOT allowed) | |
77 | // mm = two digits of minute (00 through 59) | |
78 | // ss = two digits of second (00 through 59) | |
79 | // s = one or more digits representing a decimal fraction of a second | |
80 | // TZD = time zone designator (Z or +hh:mm or -hh:mm) | |
81 | public static Date parse( String input ) throws java.text.ParseException { | |
82 | ||
83 | //NOTE: SimpleDateFormat uses GMT[-+]hh:mm for the TZ which breaks | |
84 | //things a bit. Before we go on we have to repair this. | |
85 | ||
86 | //this is zero time so we need to add that TZ indicator for | |
87 | 0 | if ( input.endsWith( "Z" ) ) { |
88 | 0 | input = input.substring( 0, input.length() - 1) + "GMT-00:00"; |
89 | } else { | |
90 | 0 | int inset = 6; |
91 | ||
92 | 0 | String s0 = input.substring( 0, input.length() - inset ); |
93 | 0 | String s1 = input.substring( input.length() - inset, input.length() ); |
94 | ||
95 | 0 | input = s0 + "GMT" + s1; |
96 | } | |
97 | ||
98 | 0 | return df.parse( input ); |
99 | ||
100 | } | |
101 | ||
102 | public static String toString( Date date ) { | |
103 | ||
104 | 0 | TimeZone tz = TimeZone.getTimeZone( "UTC" ); |
105 | ||
106 | 0 | df.setTimeZone( tz ); |
107 | ||
108 | 0 | String output = df.format( date ); |
109 | ||
110 | 0 | int inset0 = 9; |
111 | 0 | int inset1 = 6; |
112 | ||
113 | 0 | String s0 = output.substring( 0, output.length() - inset0 ); |
114 | 0 | String s1 = output.substring( output.length() - inset1, output.length() ); |
115 | ||
116 | 0 | String result = s0 + s1; |
117 | ||
118 | 0 | result = result.replaceAll( "UTC", "+00:00" ); |
119 | ||
120 | 0 | return result; |
121 | ||
122 | } | |
123 | ||
124 | public static void main( String[] args ) throws Exception { | |
125 | ||
126 | 0 | System.out.println( parse( "2004-05-31T09:19:31-06:00" ) ); |
127 | 0 | System.out.println( parse( "2004-06-23T17:25:31-00:00" ) ); |
128 | 0 | System.out.println( parse( "2004-06-23T17:25:31Z" ) ); |
129 | ||
130 | //2002-10-02T10:00:00-05:00 | |
131 | 0 | System.out.println( "v: " + toString( new Date( System.currentTimeMillis() ) ) ); |
132 | ||
133 | 0 | } |
134 | ||
135 | } | |
136 |