View Javadoc
1   /*
2    * Copyright (c) 2012-2023, jcabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.jdbc;
31  
32  import java.sql.PreparedStatement;
33  import java.sql.ResultSet;
34  import java.sql.SQLException;
35  import java.sql.Timestamp;
36  import java.util.Calendar;
37  import java.util.Date;
38  import java.util.SimpleTimeZone;
39  import lombok.EqualsAndHashCode;
40  import lombok.ToString;
41  
42  /**
43   * UTC time zone manipulator.
44   *
45   * <p>When it's necessary to save date/time to the DB in UTC timezone, use
46   * this class:
47   *
48   * <pre> new JdbcSession(source)
49   *   .sql("INSERT INTO payment (amount, date) VALUES (?, ?)")
50   *   .set(500)
51   *   .set(new Utc()) // current date to be set, in UTC timezone
52   *   .insert(Outcome.VOID);</pre>
53   *
54   * <p>This class also helps during date/time retrieval:
55   *
56   * <pre> Date date = new JdbcSession(source)
57   *   .sql("SELECT date FROM payment WHERE id = 555")
58   *   .select(
59   *     new Outcome&lt;Date&gt;() {
60   *       &#64;Override
61   *       public Date handle(final ResultSet rset) throws SQLException {
62   *         return Utc.getTimestamp(rset, 1);
63   *       }
64   *     }
65   *   );</pre>
66   *
67   * <p>{@link Timestamp} is used because {@link java.sql.Date}
68   * supports only dates (without time).
69   *
70   * @since 0.1.8
71   */
72  @ToString
73  @EqualsAndHashCode(of = "date")
74  public final class Utc {
75  
76      /**
77       * The calendar to use.
78       */
79      private static final Calendar CALENDAR =
80          Calendar.getInstance(new SimpleTimeZone(0, "UTC"));
81  
82      /**
83       * The date to work with.
84       */
85      private final transient long date;
86  
87      /**
88       * Public ctor, with current date.
89       */
90      public Utc() {
91          this(new Date());
92      }
93  
94      /**
95       * Public ctor.
96       * @param when The date to use.
97       */
98      public Utc(final Date when) {
99          this.date = when.getTime();
100     }
101 
102     /**
103      * Get date that is encapsulated.
104      * @return The date
105      */
106     public Date getDate() {
107         return new Date(this.date);
108     }
109 
110     /**
111      * Convert date to timestamp and save to the statement.
112      * @param stmt The statement
113      * @param pos Position in the statement
114      * @throws SQLException If some SQL problem inside
115      */
116     public void setTimestamp(final PreparedStatement stmt, final int pos)
117         throws SQLException {
118         stmt.setTimestamp(
119             pos,
120             new Timestamp(this.date),
121             Utc.CALENDAR
122         );
123     }
124 
125     /**
126      * Retrieve timestamp from the result set.
127      * @param rset The result set
128      * @param pos Position in the result set
129      * @return The date
130      * @throws SQLException If some SQL problem inside
131      */
132     @SuppressWarnings("PMD.ProhibitPublicStaticMethods")
133     public static Date getTimestamp(final ResultSet rset, final int pos)
134         throws SQLException {
135         final Timestamp stamp = rset.getTimestamp(pos, Utc.CALENDAR);
136         Date when = null;
137         if (stamp != null) {
138             when = new Date(stamp.getTime());
139         }
140         return when;
141     }
142 
143 }