001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020package org.apache.directory.shared.util;
021
022
023import java.text.SimpleDateFormat;
024import java.util.Calendar;
025import java.util.Date;
026import java.util.TimeZone;
027
028
029/**
030 * Gets the generalized time using the "Z" form of the g-time-zone.
031 * 
032 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
033 */
034public final class DateUtils
035{
036    /** Defines an UTC/GMT time zone */
037    public static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
038
039    /** Defines a default date format with a "yyyyMMddHHmmss'Z'" pattern */
040    public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat( "yyyyMMddHHmmss'Z'" );
041
042    static
043    {
044        DATE_FORMAT.setTimeZone( UTC_TIME_ZONE );
045    }
046
047
048    /**
049     * Private constructor.
050     */
051    private DateUtils()
052    {
053    }
054
055
056   public static Date getDate( String zuluTime )
057    {
058        Calendar cal = Calendar.getInstance( UTC_TIME_ZONE );
059        cal.set( Calendar.YEAR, getYear( zuluTime ) ); 
060        cal.set( Calendar.MONTH, getMonth( zuluTime ) - 1 ); 
061        cal.set( Calendar.DAY_OF_MONTH, getDay( zuluTime ) ); 
062        cal.set( Calendar.HOUR_OF_DAY, getHour( zuluTime ) ); 
063        cal.set( Calendar.MINUTE, getMinutes( zuluTime ) );
064        cal.set( Calendar.SECOND, getSeconds( zuluTime ) );
065        return cal.getTime();
066    }
067
068
069    public static int getYear( String zuluTime )
070    {
071        return Integer.parseInt( zuluTime.substring( 0, 4 ) );
072    }
073    
074    
075    public static int getMonth( String zuluTime )
076    {
077        return Integer.parseInt( zuluTime.substring( 4, 6 ) );
078    }
079    
080    
081    public static int getDay( String zuluTime )
082    {
083        return Integer.parseInt( zuluTime.substring( 6, 8 ) );
084    }
085    
086    
087    public static int getHour( String zuluTime )
088    {
089        return Integer.parseInt( zuluTime.substring( 8, 10 ) );
090    }
091    
092    
093    public static int getMinutes( String zuluTime )
094    {
095        return Integer.parseInt( zuluTime.substring( 10, 12 ) );
096    }
097    
098    
099    public static int getSeconds( String zuluTime )
100    {
101        return Integer.parseInt( zuluTime.substring( 12, 14 ) );
102    }
103    
104    
105    /**
106     * Gets the generalized time using the "Z" form of the g-time-zone described
107     * by [<a href=
108     * "http://ietf.org/internet-drafts/draft-ietf-ldapbis-syntaxes-09.txt">
109     * SYNTAXES</a>] section 3.3.13, included below:
110     * 
111     * <pre>
112     * 
113     *  3.3.13.  Generalized Time
114     * 
115     *  A value of the Generalized Time syntax is a character string
116     *  representing a date and time.  The LDAP-specific encoding of a value
117     *  of this syntax is a restriction of the format defined in [ISO8601],
118     *  and is described by the following ABNF:
119     * 
120     *  century = 2(%x30-39) ; &quot;00&quot; to &quot;99&quot;
121     *  year    = 2(%x30-39) ; &quot;00&quot; to &quot;99&quot;
122     *  month   =   ( %x30 %x31-39 ) ; &quot;01&quot; (January) to &quot;09&quot;
123     *            / ( %x31 %x30-32 ) ; &quot;10&quot; to &quot;12&quot;
124     *  day     =   ( %x30 %x31-39 )    ; &quot;01&quot; to &quot;09&quot;
125     *            / ( %x31-32 %x30-39 ) ; &quot;10&quot; to &quot;29&quot;
126     *            / ( %x33 %x30-31 )    ; &quot;30&quot; to &quot;31&quot;
127     *  hour    = ( %x30-31 %x30-39 ) / ( %x32 %x30-33 ) ; &quot;00&quot; to &quot;23&quot;
128     *  minute  = %x30-35 %x30-39                        ; &quot;00&quot; to &quot;59&quot;
129     *  second  =   ( %x30-35 %x30-39 )  ; &quot;00&quot; to &quot;59&quot;
130     *            / ( %x36 %x30 )        ; &quot;60&quot; (a leap second)
131     * 
132     *  GeneralizedTime = century year month day hour
133     *                       [ minute [ second ] ] [ fraction ]
134     *                       g-time-zone
135     *  fraction        = ( DOT / COMMA ) 1*(%x30-39)
136     *  g-time-zone     = %x5A  ; &quot;Z&quot;
137     *                    / g-differential
138     *  g-differential  = ( MINUS / PLUS ) hour [ minute ]
139     *  MINUS           = %x2D  ; minus sign (&quot;-&quot;)
140     * 
141     *  The &lt;DOT&gt;, &lt;COMMA&gt; and &lt;PLUS&gt; rules are defined in [MODELS].
142     * 
143     *  The time value represents coordinated universal time (equivalent to
144     *  Greenwich Mean Time) if the &quot;Z&quot; form of &lt;g-time-zone&gt; is used,
145     * 
146     *  otherwise the value represents a local time in the time zone
147     *  indicated by &lt;g-differential&gt;.  In the latter case, coordinated
148     *  universal time can be calculated by subtracting the differential from
149     *  the local time.  The &quot;Z&quot; form of &lt;g-time-zone&gt; SHOULD be used in
150     *  preference to &lt;g-differential&gt;.
151     * 
152     *  Examples:
153     *     199412161032Z
154     *     199412160532-0500
155     * 
156     *  Both example values represent the same coordinated universal time:
157     *  10:32 AM, December 16, 1994.
158     * 
159     *  The LDAP definition for the Generalized Time syntax is:
160     * 
161     *  ( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )
162     * 
163     *  This syntax corresponds to the GeneralizedTime ASN.1 type from
164     *  [ASN.1], with the constraint that local time without a differential
165     *  SHALL NOT be used.
166     * </pre>
167     * 
168     * Gets the generalized time right now.
169     * 
170     * @return the generalizedTime right now
171     */
172    public static String getGeneralizedTime()
173    {
174        Date date = new Date();
175
176        synchronized ( DATE_FORMAT )
177        {
178            return DATE_FORMAT.format( date );
179        }
180    }
181
182
183    /**
184     * 
185     * @see #getGeneralizedTime()
186     *
187     * @param date the date to be converted to generalized time string
188     * @return given date in the generalized time string format
189     */
190    public static String getGeneralizedTime( Date date )
191    {
192        synchronized ( DATE_FORMAT )
193        {
194            return DATE_FORMAT.format( date );
195        }
196    }
197
198
199    /**
200     * 
201     * @see #getGeneralizedTime()
202     *
203     * @param time the time value to be converted to generalized time string
204     * @return given time in generalized time string format
205     */
206    public static String getGeneralizedTime( long time )
207    {
208        return getGeneralizedTime( new Date( time ) );
209    }
210    
211}