1   /*
2    * Copyright 2003 - 2013 The eFaps Team
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   * Revision:        $Rev$
17   * Last Changed:    $Date$
18   * Last Changed By: $Author$
19   */
20  
21  package org.efaps.util;
22  
23  import java.sql.ResultSet;
24  import java.sql.SQLException;
25  import java.sql.Statement;
26  import java.sql.Timestamp;
27  import java.util.Date;
28  
29  import org.efaps.admin.EFapsSystemConfiguration;
30  import org.efaps.admin.KernelSettings;
31  import org.efaps.db.Context;
32  import org.efaps.db.transaction.ConnectionResource;
33  import org.joda.time.DateTime;
34  import org.joda.time.DateTimeZone;
35  import org.joda.time.chrono.ISOChronology;
36  import org.joda.time.format.ISODateTimeFormat;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  /**
41   * Date and time utility class to handle the time zone from the eFaps
42   * correctly.
43   *
44   * @author The eFaps Team
45   * @version $Id$
46   */
47  public final class DateTimeUtil
48  {
49      /**
50       * Logging instance used to give logging information of this class.
51       */
52      private static final Logger LOG = LoggerFactory.getLogger(DateTimeUtil.class);
53  
54      /**
55       * Private constructor so that no instance of this utility class could be
56       * created.
57       */
58      private DateTimeUtil()
59      {
60      }
61  
62      /**
63       * Static method to get the current time stamp from the eFaps database.
64       *
65       * @return time stamp containing the current time of the eFaps database
66       * @throws EFapsException on error
67       */
68      public static Timestamp getCurrentTimeFromDB() throws EFapsException
69      {
70          Timestamp now = null;
71          final ConnectionResource rsrc = Context.getThreadContext().getConnectionResource();
72          Statement stmt;
73          try {
74              stmt = rsrc.getConnection().createStatement();
75              final ResultSet resultset = stmt.executeQuery("SELECT " + Context.getDbType().getCurrentTimeStamp());
76              resultset.next();
77              now = resultset.getTimestamp(1);
78              resultset.close();
79              stmt.close();
80              rsrc.commit();
81          } catch (final SQLException e) {
82              DateTimeUtil.LOG.error("could not execute SQL-Statement", e);
83          }
84          return now;
85      }
86  
87      /**
88       * The given DateTime will be normalized to ISO calendar with time zone
89       * from {@link EFapsSystemConfiguration#KERNEL kernel system configuration}
90       * "Admin_Common_DataBaseTimeZone". In case that the
91       * system configuration is missing "UTC" will be used.
92       *
93       * @param _date     date to normalize
94       * @return DateTime normalized for the database
95       * @throws EFapsException on error
96       */
97      public static DateTime normalize(final DateTime _date)
98          throws EFapsException
99      {
100         // reads the Value from "Admin_Common_DataBaseTimeZone"
101         final String timezoneID = EFapsSystemConfiguration.get().getAttributeValue(KernelSettings.DBTIMEZONE);
102         final ISOChronology chron;
103         if (timezoneID != null) {
104             final DateTimeZone timezone = DateTimeZone.forID(timezoneID);
105             chron = ISOChronology.getInstance(timezone);
106         } else {
107             chron = ISOChronology.getInstanceUTC();
108         }
109         return _date.withChronology(chron);
110     }
111 
112     /**
113      * The value that can be set is a Date, a DateTime or a String
114      * yyyy-MM-dd'T'HH:mm:ss.SSSZZ. It will be normalized to ISO Calender with
115      * TimeZone from SystemAttribute Admin_Common_DataBaseTimeZone. In case
116      * that the SystemAttribute is missing UTC will be used.
117      *
118      *
119      * @param _value    value from user interface to translate
120      * @return translated date time
121      * @throws EFapsException on error
122      */
123     public static DateTime translateFromUI(final Object _value)
124         throws EFapsException
125     {
126         final DateTime ret;
127         // reads the Value from "Admin_Common_DataBaseTimeZone"
128         final String timezoneID = EFapsSystemConfiguration.get().getAttributeValue(KernelSettings.DBTIMEZONE);
129         final ISOChronology chron;
130         if (timezoneID != null) {
131             final DateTimeZone timezone = DateTimeZone.forID(timezoneID);
132             chron = ISOChronology.getInstance(timezone);
133         } else {
134             chron = ISOChronology.getInstanceUTC();
135         }
136         if (_value instanceof Date) {
137             ret = new DateTime(_value).withChronology(chron);
138         } else if (_value instanceof DateTime) {
139             ret = ((DateTime) _value).withChronology(chron);
140         } else if (_value instanceof String) {
141             ret = ISODateTimeFormat.dateTime().parseDateTime((String) _value).withChronology(chron);
142         } else  {
143             ret = null;
144         }
145         return ret;
146     }
147 }