0f3a44a2eb0bc503e4771ddc0e8919170ca59b5e
[vxquery.git] / vxquery-core / src / main / java / org / apache / vxquery / datamodel / accessors / atomic / XSDateTimePointable.java
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.vxquery.datamodel.accessors.atomic;
18
19 import java.util.Calendar;
20 import java.util.TimeZone;
21
22 import org.apache.vxquery.datamodel.api.IDate;
23 import org.apache.vxquery.datamodel.api.ITime;
24 import org.apache.vxquery.datamodel.api.ITimezone;
25 import org.apache.vxquery.datamodel.util.DateTime;
26
27 import org.apache.hyracks.api.dataflow.value.ITypeTraits;
28 import org.apache.hyracks.data.std.api.AbstractPointable;
29 import org.apache.hyracks.data.std.api.IPointable;
30 import org.apache.hyracks.data.std.api.IPointableFactory;
31 import org.apache.hyracks.data.std.primitive.BytePointable;
32 import org.apache.hyracks.data.std.primitive.IntegerPointable;
33 import org.apache.hyracks.data.std.primitive.ShortPointable;
34
35 /**
36 * The datetime is split up into eight sections. Due to leap year, we have decided to keep the
37 * storage simple by saving each datetime section separately. For calculations you can access
38 * YearMonth (months) and DayTime (milliseconds) values.
39 */
40 public class XSDateTimePointable extends AbstractPointable implements IDate, ITime, ITimezone {
41 public static final int YEAR_OFFSET = 0;
42 public static final int MONTH_OFFSET = 2;
43 public static final int DAY_OFFSET = 3;
44 public static final int HOUR_OFFSET = 4;
45 public static final int MINUTE_OFFSET = 5;
46 public static final int MILLISECOND_OFFSET = 6;
47 public static final int TIMEZONE_HOUR_OFFSET = 10;
48 public static final int TIMEZONE_MINUTE_OFFSET = 11;
49
50 public static final ITypeTraits TYPE_TRAITS = new ITypeTraits() {
51 private static final long serialVersionUID = 1L;
52
53 @Override
54 public boolean isFixedLength() {
55 return true;
56 }
57
58 @Override
59 public int getFixedLength() {
60 return 12;
61 }
62 };
63
64 public static final IPointableFactory FACTORY = new IPointableFactory() {
65 private static final long serialVersionUID = 1L;
66
67 @Override
68 public IPointable createPointable() {
69 return new XSDateTimePointable();
70 }
71
72 @Override
73 public ITypeTraits getTypeTraits() {
74 return TYPE_TRAITS;
75 }
76 };
77
78 public void setCurrentDateTime() {
79 Calendar cal = Calendar.getInstance();
80 TimeZone tz = cal.getTimeZone();
81 int year = cal.get(Calendar.YEAR);
82 int month = cal.get(Calendar.MONTH);
83 int day = cal.get(Calendar.DAY_OF_MONTH);
84 int ms = cal.get(Calendar.MILLISECOND);
85 int tzOffsetInMs = tz.getOffset(cal.get(Calendar.ERA), year, month, day, cal.get(Calendar.DAY_OF_WEEK), ms);
86 int tzOffsetInMin = tzOffsetInMs / 1000 / 60;
87 setDateTime(year, month + 1L, day, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE),
88 cal.get(Calendar.SECOND) * 1000L + ms, tzOffsetInMin / 60L, tzOffsetInMin % 60);
89 }
90
91 public void setDateTime(long year, long month, long day, long hour, long minute, long milliSecond,
92 long timezoneHour, long timezoneMinute) {
93 setDateTime(bytes, start, year, month, day, hour, minute, milliSecond, timezoneHour, timezoneMinute);
94 }
95
96 public static void setDateTime(byte[] bytes, int start, long year, long month, long day, long hour, long minute,
97 long milliSecond, long timezoneHour, long timezoneMinute) {
98 ShortPointable.setShort(bytes, start + YEAR_OFFSET, (short) year);
99 BytePointable.setByte(bytes, start + MONTH_OFFSET, (byte) month);
100 BytePointable.setByte(bytes, start + DAY_OFFSET, (byte) day);
101 BytePointable.setByte(bytes, start + HOUR_OFFSET, (byte) hour);
102 BytePointable.setByte(bytes, start + MINUTE_OFFSET, (byte) minute);
103 IntegerPointable.setInteger(bytes, start + MILLISECOND_OFFSET, (int) milliSecond);
104 BytePointable.setByte(bytes, start + TIMEZONE_HOUR_OFFSET, (byte) timezoneHour);
105 BytePointable.setByte(bytes, start + TIMEZONE_MINUTE_OFFSET, (byte) timezoneMinute);
106 }
107
108 @Override
109 public long getYear() {
110 return getYear(bytes, start);
111 }
112
113 public static long getYear(byte[] bytes, int start) {
114 return (long) ShortPointable.getShort(bytes, start + YEAR_OFFSET);
115 }
116
117 @Override
118 public long getMonth() {
119 return getMonth(bytes, start);
120 }
121
122 public static long getMonth(byte[] bytes, int start) {
123 return (long) BytePointable.getByte(bytes, start + MONTH_OFFSET);
124 }
125
126 @Override
127 public long getDay() {
128 return getDay(bytes, start);
129 }
130
131 public static long getDay(byte[] bytes, int start) {
132 return (long) BytePointable.getByte(bytes, start + DAY_OFFSET);
133 }
134
135 @Override
136 public long getHour() {
137 return getHour(bytes, start);
138 }
139
140 public static long getHour(byte[] bytes, int start) {
141 return (long) BytePointable.getByte(bytes, start + HOUR_OFFSET);
142 }
143
144 @Override
145 public long getMinute() {
146 return getMinute(bytes, start);
147 }
148
149 public static long getMinute(byte[] bytes, int start) {
150 return (long) BytePointable.getByte(bytes, start + MINUTE_OFFSET);
151 }
152
153 @Override
154 public long getMilliSecond() {
155 return getMilliSecond(bytes, start);
156 }
157
158 public static long getMilliSecond(byte[] bytes, int start) {
159 return (long) IntegerPointable.getInteger(bytes, start + MILLISECOND_OFFSET);
160 }
161
162 @Override
163 public long getTimezoneHour() {
164 return getTimezoneHour(bytes, start);
165 }
166
167 public static long getTimezoneHour(byte[] bytes, int start) {
168 return (long) BytePointable.getByte(bytes, start + TIMEZONE_HOUR_OFFSET);
169 }
170
171 @Override
172 public long getTimezoneMinute() {
173 return getTimezoneMinute(bytes, start);
174 }
175
176 public static long getTimezoneMinute(byte[] bytes, int start) {
177 return (long) BytePointable.getByte(bytes, start + TIMEZONE_MINUTE_OFFSET);
178 }
179
180 @Override
181 public long getTimezone() {
182 return getTimezone(bytes, start);
183 }
184
185 public static long getTimezone(byte[] bytes, int start) {
186 return getTimezoneHour(bytes, start) * 60 + getTimezoneMinute(bytes, start);
187 }
188
189 @Override
190 public long getYearMonth() {
191 return getYearMonth(bytes, start);
192 }
193
194 public static long getYearMonth(byte[] bytes, int start) {
195 return getYear(bytes, start) * 12 + getMonth(bytes, start);
196 }
197
198 @Override
199 public long getDayTime() {
200 return getDayTime(bytes, start);
201 }
202
203 public static long getDayTime(byte[] bytes, int start) {
204 return getDay(bytes, start) * DateTime.CHRONON_OF_DAY + getHour(bytes, start) * DateTime.CHRONON_OF_HOUR
205 + getMinute(bytes, start) * DateTime.CHRONON_OF_MINUTE + getMilliSecond(bytes, start);
206 }
207
208 @Override
209 public String toString() {
210 return toString(bytes, start);
211 }
212
213 public static String toString(byte[] bytes, int start) {
214 final long millis = getMilliSecond(bytes, start);
215 String timezone = "";
216 if (getTimezoneHour(bytes, start) != DateTime.TIMEZONE_HOUR_NULL
217 && getTimezoneMinute(bytes, start) != DateTime.TIMEZONE_MINUTE_NULL) {
218 timezone = (getTimezoneHour(bytes, start) < 0 || getTimezoneMinute(bytes, start) < 0 ? "" : "+")
219 + getTimezoneHour(bytes, start) + ":" + getTimezoneMinute(bytes, start);
220 }
221 return getYear(bytes, start) + "-" + getMonth(bytes, start) + "-" + getDay(bytes, start) + "T"
222 + getHour(bytes, start) + ":" + getMinute(bytes, start) + ":" + millis / 1000 + "." + millis % 1000
223 + timezone;
224 }
225
226 }

Copyright 2016, The Apache Software Foundation.