1 | /* |
2 | * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, |
3 | * and the EPL 1.0 (http://h2database.com/html/license.html). |
4 | * Initial Developer: H2 Group |
5 | */ |
6 | package org.h2.value; |
7 | |
8 | import java.sql.Date; |
9 | import java.sql.PreparedStatement; |
10 | import java.sql.SQLException; |
11 | |
12 | import org.h2.api.ErrorCode; |
13 | import org.h2.message.DbException; |
14 | import org.h2.util.DateTimeUtils; |
15 | import org.h2.util.MathUtils; |
16 | import org.h2.util.StringUtils; |
17 | |
18 | /** |
19 | * Implementation of the DATE data type. |
20 | */ |
21 | public class ValueDate extends Value { |
22 | |
23 | /** |
24 | * The precision in digits. |
25 | */ |
26 | public static final int PRECISION = 8; |
27 | |
28 | /** |
29 | * The display size of the textual representation of a date. |
30 | * Example: 2000-01-02 |
31 | */ |
32 | public static final int DISPLAY_SIZE = 10; |
33 | |
34 | private final long dateValue; |
35 | |
36 | private ValueDate(long dateValue) { |
37 | this.dateValue = dateValue; |
38 | } |
39 | |
40 | /** |
41 | * Get or create a date value for the given date. |
42 | * |
43 | * @param dateValue the date value |
44 | * @return the value |
45 | */ |
46 | public static ValueDate fromDateValue(long dateValue) { |
47 | return (ValueDate) Value.cache(new ValueDate(dateValue)); |
48 | } |
49 | |
50 | /** |
51 | * Get or create a date value for the given date. |
52 | * |
53 | * @param date the date |
54 | * @return the value |
55 | */ |
56 | public static ValueDate get(Date date) { |
57 | return fromDateValue(DateTimeUtils.dateValueFromDate(date.getTime())); |
58 | } |
59 | |
60 | /** |
61 | * Calculate the date value (in the default timezone) from a given time in |
62 | * milliseconds in UTC. |
63 | * |
64 | * @param ms the milliseconds |
65 | * @return the value |
66 | */ |
67 | public static ValueDate fromMillis(long ms) { |
68 | return fromDateValue(DateTimeUtils.dateValueFromDate(ms)); |
69 | } |
70 | |
71 | /** |
72 | * Parse a string to a ValueDate. |
73 | * |
74 | * @param s the string to parse |
75 | * @return the date |
76 | */ |
77 | public static ValueDate parse(String s) { |
78 | try { |
79 | return fromDateValue(DateTimeUtils.parseDateValue(s, 0, s.length())); |
80 | } catch (Exception e) { |
81 | throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2, |
82 | e, "DATE", s); |
83 | } |
84 | } |
85 | |
86 | public long getDateValue() { |
87 | return dateValue; |
88 | } |
89 | |
90 | @Override |
91 | public Date getDate() { |
92 | return DateTimeUtils.convertDateValueToDate(dateValue); |
93 | } |
94 | |
95 | @Override |
96 | public int getType() { |
97 | return Value.DATE; |
98 | } |
99 | |
100 | @Override |
101 | public String getString() { |
102 | StringBuilder buff = new StringBuilder(DISPLAY_SIZE); |
103 | appendDate(buff, dateValue); |
104 | return buff.toString(); |
105 | } |
106 | |
107 | @Override |
108 | public String getSQL() { |
109 | return "DATE '" + getString() + "'"; |
110 | } |
111 | |
112 | @Override |
113 | public long getPrecision() { |
114 | return PRECISION; |
115 | } |
116 | |
117 | @Override |
118 | public int getDisplaySize() { |
119 | return DISPLAY_SIZE; |
120 | } |
121 | |
122 | @Override |
123 | protected int compareSecure(Value o, CompareMode mode) { |
124 | return MathUtils.compareLong(dateValue, ((ValueDate) o).dateValue); |
125 | } |
126 | |
127 | @Override |
128 | public boolean equals(Object other) { |
129 | if (this == other) { |
130 | return true; |
131 | } |
132 | return other instanceof ValueDate |
133 | && dateValue == (((ValueDate) other).dateValue); |
134 | } |
135 | |
136 | @Override |
137 | public int hashCode() { |
138 | return (int) (dateValue ^ (dateValue >>> 32)); |
139 | } |
140 | |
141 | @Override |
142 | public Object getObject() { |
143 | return getDate(); |
144 | } |
145 | |
146 | @Override |
147 | public void set(PreparedStatement prep, int parameterIndex) |
148 | throws SQLException { |
149 | prep.setDate(parameterIndex, getDate()); |
150 | } |
151 | |
152 | /** |
153 | * Append a date to the string builder. |
154 | * |
155 | * @param buff the target string builder |
156 | * @param dateValue the date value |
157 | */ |
158 | static void appendDate(StringBuilder buff, long dateValue) { |
159 | int y = DateTimeUtils.yearFromDateValue(dateValue); |
160 | int m = DateTimeUtils.monthFromDateValue(dateValue); |
161 | int d = DateTimeUtils.dayFromDateValue(dateValue); |
162 | if (y > 0 && y < 10000) { |
163 | StringUtils.appendZeroPadded(buff, 4, y); |
164 | } else { |
165 | buff.append(y); |
166 | } |
167 | buff.append('-'); |
168 | StringUtils.appendZeroPadded(buff, 2, m); |
169 | buff.append('-'); |
170 | StringUtils.appendZeroPadded(buff, 2, d); |
171 | } |
172 | |
173 | } |