io.questdb.std.time.DateLocale Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
QuestDB is High Performance Time Series Database
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (c) 2014-2019 Appsicle
* Copyright (c) 2019-2020 QuestDB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package io.questdb.std.time;
import io.questdb.std.*;
import java.text.DateFormatSymbols;
public class DateLocale {
private final IntObjHashMap> months = new IntObjHashMap<>();
private final IntObjHashMap> weekdays = new IntObjHashMap<>();
private final IntObjHashMap> amspms = new IntObjHashMap<>();
private final IntObjHashMap> eras = new IntObjHashMap<>();
private final IntObjHashMap> zones = new IntObjHashMap<>();
private final String[] monthArray;
private final String[] shortMonthArray;
private final String[] weekdayArray;
private final String[] shortWeekdayArray;
private final String[] ampmArray;
private final String[] eraArray;
private final TimeZoneRuleFactory factory;
DateLocale(DateFormatSymbols symbols, TimeZoneRuleFactory timeZoneRuleFactory, @Transient CharSequenceHashSet cache) {
this.factory = timeZoneRuleFactory;
index(monthArray = symbols.getMonths(), months);
index(shortMonthArray = symbols.getShortMonths(), months);
index(weekdayArray = symbols.getWeekdays(), weekdays);
index(shortWeekdayArray = symbols.getShortWeekdays(), weekdays);
index(ampmArray = symbols.getAmPmStrings(), amspms);
index(eraArray = symbols.getEras(), eras);
indexZones(symbols.getZoneStrings(), timeZoneRuleFactory, cache);
}
public String getAMPM(int index) {
return ampmArray[index];
}
private static void defineToken(String token, int pos, IntObjHashMap> map) {
if (token == null || token.length() == 0) {
return;
}
char c0 = Character.toUpperCase(token.charAt(0));
int index = map.keyIndex(c0);
ObjList l;
if (index > -1) {
l = new ObjList<>();
map.putAt(index, c0, l);
} else {
l = map.valueAtQuick(index);
}
l.add(((char) pos) + token.toUpperCase());
l.sort(GenericLexer.COMPARATOR);
}
private static long findToken(CharSequence content, int lo, int hi, IntObjHashMap> map) throws NumericException {
if (lo >= hi) {
throw NumericException.INSTANCE;
}
char c = Character.toUpperCase(content.charAt(lo));
ObjList l = map.get(c);
if (l == null) {
throw NumericException.INSTANCE;
}
for (int i = 0, sz = l.size(); i < sz; i++) {
CharSequence txt = l.get(i);
int n = txt.length() - 1;
boolean match = n <= hi - lo;
if (match) {
for (int k = 1; k < n; k++) {
if (Character.toUpperCase(content.charAt(lo + k)) != txt.charAt(k + 1)) {
match = false;
break;
}
}
}
if (match) {
return Numbers.encodeLowHighInts(txt.charAt(0), n);
}
}
throw NumericException.INSTANCE;
}
public String getEra(int index) {
return eraArray[index];
}
public String getMonth(int index) {
return monthArray[index];
}
public String getShortMonth(int index) {
return shortMonthArray[index];
}
public TimeZoneRules getRules(CharSequence timeZoneName) throws NumericException {
return getZoneRules(Numbers.decodeLowInt(matchZone(timeZoneName, 0, timeZoneName.length())));
}
public String getShortWeekday(int index) {
return shortWeekdayArray[index];
}
public String getWeekday(int index) {
return weekdayArray[index];
}
private static void index(String[] tokens, IntObjHashMap> map) {
for (int i = 0, n = tokens.length; i < n; i++) {
defineToken(tokens[i], i, map);
}
}
public TimeZoneRules getZoneRules(int index) {
return factory.getTimeZoneRulesQuick(index);
}
public long matchAMPM(CharSequence content, int lo, int hi) throws NumericException {
return findToken(content, lo, hi, amspms);
}
public long matchEra(CharSequence content, int lo, int hi) throws NumericException {
return findToken(content, lo, hi, eras);
}
public long matchMonth(CharSequence content, int lo, int hi) throws NumericException {
return findToken(content, lo, hi, months);
}
public long matchWeekday(CharSequence content, int lo, int hi) throws NumericException {
return findToken(content, lo, hi, weekdays);
}
public long matchZone(CharSequence content, int lo, int hi) throws NumericException {
return findToken(content, lo, hi, zones);
}
private void indexZones(String[][] zones, TimeZoneRuleFactory timeZoneRuleFactory, CharSequenceHashSet cache) {
// this is a workaround a problem where UTC timezone comes nearly last
// in this array, which gives way to Antarctica/Troll take its place
if (cache.add("UTC")) {
int index = timeZoneRuleFactory.getTimeZoneRulesIndex("UTC");
if (index != -1) {
defineToken("UTC", index, this.zones);
}
}
// end of workaround
for (int i = 0, n = zones.length; i < n; i++) {
String[] zNames = zones[i];
String key = zNames[0];
int index = timeZoneRuleFactory.getTimeZoneRulesIndex(key);
if (index == -1) {
continue;
}
for (int k = 1, m = zNames.length; k < m; k++) {
String name = zNames[k];
// we already added this name, skip
if (cache.add(name)) {
defineToken(name, index, this.zones);
}
}
}
}
}