Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
3d253279
提交
3d253279
authored
9 年前
作者:
Noel Grandin
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #222 from plus33/master
Added TO_DATE and TO_TIMESTAMP functionality
上级
0e6a9baa
769aa54b
全部展开
显示空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
907 行增加
和
16 行删除
+907
-16
ErrorCode.java
h2/src/main/org/h2/api/ErrorCode.java
+7
-1
Function.java
h2/src/main/org/h2/expression/Function.java
+15
-11
_messages_cs.prop
h2/src/main/org/h2/res/_messages_cs.prop
+1
-0
_messages_de.prop
h2/src/main/org/h2/res/_messages_de.prop
+1
-0
_messages_en.prop
h2/src/main/org/h2/res/_messages_en.prop
+1
-0
_messages_es.prop
h2/src/main/org/h2/res/_messages_es.prop
+1
-0
_messages_ja.prop
h2/src/main/org/h2/res/_messages_ja.prop
+1
-0
_messages_pl.prop
h2/src/main/org/h2/res/_messages_pl.prop
+1
-0
_messages_pt_br.prop
h2/src/main/org/h2/res/_messages_pt_br.prop
+1
-0
_messages_ru.prop
h2/src/main/org/h2/res/_messages_ru.prop
+1
-0
_messages_zh_cn.prop
h2/src/main/org/h2/res/_messages_zh_cn.prop
+1
-0
DateTimeUtils.java
h2/src/main/org/h2/util/DateTimeUtils.java
+1
-4
ToDate.java
h2/src/main/org/h2/util/ToDate.java
+19
-0
ToDateParser.java
h2/src/main/org/h2/util/ToDateParser.java
+179
-0
ToDateTokenizer.java
h2/src/main/org/h2/util/ToDateTokenizer.java
+494
-0
ToDate.java
h2/src/test/org/h2/samples/ToDate.java
+60
-0
TestFunctions.java
h2/src/test/org/h2/test/db/TestFunctions.java
+123
-0
没有找到文件。
h2/src/main/org/h2/api/ErrorCode.java
浏览文件 @
3d253279
...
@@ -1001,6 +1001,12 @@ public class ErrorCode {
...
@@ -1001,6 +1001,12 @@ public class ErrorCode {
*/
*/
public
static
final
int
UNSUPPORTED_CIPHER
=
90055
;
public
static
final
int
UNSUPPORTED_CIPHER
=
90055
;
/**
* The error with code <code>90056</code> is thrown when trying to format a
* timestamp using TO_DATE and TO_TIMESTAMP with an invalid format.
*/
public
static
final
int
INVALID_TO_DATE_FORMAT
=
90056
;
/**
/**
* The error with code <code>90057</code> is thrown when
* The error with code <code>90057</code> is thrown when
* trying to drop a constraint that does not exist.
* trying to drop a constraint that does not exist.
...
@@ -1923,7 +1929,7 @@ public class ErrorCode {
...
@@ -1923,7 +1929,7 @@ public class ErrorCode {
public
static
final
int
STEP_SIZE_MUST_NOT_BE_ZERO
=
90142
;
public
static
final
int
STEP_SIZE_MUST_NOT_BE_ZERO
=
90142
;
// next are 90
056, 90
110, 90122, 90143
// next are 90110, 90122, 90143
private
ErrorCode
()
{
private
ErrorCode
()
{
// utility class
// utility class
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/Function.java
浏览文件 @
3d253279
...
@@ -44,16 +44,7 @@ import org.h2.table.Table;
...
@@ -44,16 +44,7 @@ import org.h2.table.Table;
import
org.h2.table.TableFilter
;
import
org.h2.table.TableFilter
;
import
org.h2.tools.CompressTool
;
import
org.h2.tools.CompressTool
;
import
org.h2.tools.Csv
;
import
org.h2.tools.Csv
;
import
org.h2.util.AutoCloseInputStream
;
import
org.h2.util.*
;
import
org.h2.util.DateTimeUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.JdbcUtils
;
import
org.h2.util.MathUtils
;
import
org.h2.util.New
;
import
org.h2.util.StatementBuilder
;
import
org.h2.util.StringUtils
;
import
org.h2.util.ToChar
;
import
org.h2.util.Utils
;
import
org.h2.value.DataType
;
import
org.h2.value.DataType
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
import
org.h2.value.ValueArray
;
...
@@ -93,7 +84,8 @@ public class Function extends Expression implements FunctionCall {
...
@@ -93,7 +84,8 @@ public class Function extends Expression implements FunctionCall {
STRINGDECODE
=
80
,
STRINGTOUTF8
=
81
,
UTF8TOSTRING
=
82
,
STRINGDECODE
=
80
,
STRINGTOUTF8
=
81
,
UTF8TOSTRING
=
82
,
XMLATTR
=
83
,
XMLNODE
=
84
,
XMLCOMMENT
=
85
,
XMLCDATA
=
86
,
XMLATTR
=
83
,
XMLNODE
=
84
,
XMLCOMMENT
=
85
,
XMLCDATA
=
86
,
XMLSTARTDOC
=
87
,
XMLTEXT
=
88
,
REGEXP_REPLACE
=
89
,
RPAD
=
90
,
XMLSTARTDOC
=
87
,
XMLTEXT
=
88
,
REGEXP_REPLACE
=
89
,
RPAD
=
90
,
LPAD
=
91
,
CONCAT_WS
=
92
,
TO_CHAR
=
93
,
TRANSLATE
=
94
,
ORA_HASH
=
95
;
LPAD
=
91
,
CONCAT_WS
=
92
,
TO_CHAR
=
93
,
TRANSLATE
=
94
,
ORA_HASH
=
95
,
TO_DATE
=
96
,
TO_TIMESTAMP
=
97
;
public
static
final
int
CURDATE
=
100
,
CURTIME
=
101
,
DATE_ADD
=
102
,
public
static
final
int
CURDATE
=
100
,
CURTIME
=
101
,
DATE_ADD
=
102
,
DATE_DIFF
=
103
,
DAY_NAME
=
104
,
DAY_OF_MONTH
=
105
,
DATE_DIFF
=
103
,
DAY_NAME
=
104
,
DAY_OF_MONTH
=
105
,
...
@@ -306,6 +298,8 @@ public class Function extends Expression implements FunctionCall {
...
@@ -306,6 +298,8 @@ public class Function extends Expression implements FunctionCall {
0
,
Value
.
DATE
);
0
,
Value
.
DATE
);
addFunctionNotDeterministic
(
"CURDATE"
,
CURDATE
,
addFunctionNotDeterministic
(
"CURDATE"
,
CURDATE
,
0
,
Value
.
DATE
);
0
,
Value
.
DATE
);
addFunction
(
"TO_DATE"
,
TO_DATE
,
VAR_ARGS
,
Value
.
STRING
);
addFunction
(
"TO_TIMESTAMP"
,
TO_TIMESTAMP
,
VAR_ARGS
,
Value
.
STRING
);
// alias for MSSQLServer
// alias for MSSQLServer
addFunctionNotDeterministic
(
"GETDATE"
,
CURDATE
,
addFunctionNotDeterministic
(
"GETDATE"
,
CURDATE
,
0
,
Value
.
DATE
);
0
,
Value
.
DATE
);
...
@@ -1429,6 +1423,14 @@ public class Function extends Expression implements FunctionCall {
...
@@ -1429,6 +1423,14 @@ public class Function extends Expression implements FunctionCall {
database
.
getMode
().
treatEmptyStringsAsNull
);
database
.
getMode
().
treatEmptyStringsAsNull
);
}
}
break
;
break
;
case
TO_DATE:
result
=
ValueTimestamp
.
get
(
ToDate
.
TO_DATE
(
v0
.
getString
(),
v1
==
null
?
null
:
v1
.
getString
()));
break
;
case
TO_TIMESTAMP:
result
=
ValueTimestamp
.
get
(
ToDate
.
TO_TIMESTAMP
(
v0
.
getString
(),
v1
==
null
?
null
:
v1
.
getString
()));
break
;
case
TRANSLATE:
{
case
TRANSLATE:
{
String
matching
=
v1
.
getString
();
String
matching
=
v1
.
getString
();
String
replacement
=
v2
.
getString
();
String
replacement
=
v2
.
getString
();
...
@@ -2123,10 +2125,12 @@ public class Function extends Expression implements FunctionCall {
...
@@ -2123,10 +2125,12 @@ public class Function extends Expression implements FunctionCall {
case
ROUND:
case
ROUND:
case
XMLTEXT:
case
XMLTEXT:
case
TRUNCATE:
case
TRUNCATE:
case
TO_TIMESTAMP:
min
=
1
;
min
=
1
;
max
=
2
;
max
=
2
;
break
;
break
;
case
TO_CHAR:
case
TO_CHAR:
case
TO_DATE:
min
=
1
;
min
=
1
;
max
=
3
;
max
=
3
;
break
;
break
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/_messages_cs.prop
浏览文件 @
3d253279
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
90053=Skalárnà vnoÅ™ený dotaz obsahuje vÃce než jeden řádek
90053=Skalárnà vnoÅ™ený dotaz obsahuje vÃce než jeden řádek
90054=Neplatné použità agregátnà funkce {0}
90054=Neplatné použità agregátnà funkce {0}
90055=Nepodporované šifrovánà {0}
90055=Nepodporované šifrovánà {0}
90056=Function {0}: Invalid date format: {1}
90057=Omezenà {0} nenalezeno
90057=Omezenà {0} nenalezeno
90058=Vkládánà nebo vrácenà změn nenà povoleno uvnitř triggeru
90058=Vkládánà nebo vrácenà změn nenà povoleno uvnitř triggeru
90059=Dvojsmyslný název sloupce {0}
90059=Dvojsmyslný název sloupce {0}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/_messages_de.prop
浏览文件 @
3d253279
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
90053=Skalar-Unterabfrage enthält mehr als eine Zeile
90053=Skalar-Unterabfrage enthält mehr als eine Zeile
90054=Ungültige Verwendung der Aggregat Funktion {0}
90054=Ungültige Verwendung der Aggregat Funktion {0}
90055=Chiffre nicht unterstützt: {0}
90055=Chiffre nicht unterstützt: {0}
90056=Funktion {0}: Ungültiges TO_DATE Format: {1}
90057=Bedingung {0} nicht gefunden
90057=Bedingung {0} nicht gefunden
90058=Innerhalb eines Triggers sind Commit und Rollback ist nicht erlaubt
90058=Innerhalb eines Triggers sind Commit und Rollback ist nicht erlaubt
90059=Mehrdeutiger Feldname {0}
90059=Mehrdeutiger Feldname {0}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/_messages_en.prop
浏览文件 @
3d253279
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
90053=Scalar subquery contains more than one row
90053=Scalar subquery contains more than one row
90054=Invalid use of aggregate function {0}
90054=Invalid use of aggregate function {0}
90055=Unsupported cipher {0}
90055=Unsupported cipher {0}
90056=Function {0}: Invalid date format: {1}
90057=Constraint {0} not found
90057=Constraint {0} not found
90058=Commit or rollback is not allowed within a trigger
90058=Commit or rollback is not allowed within a trigger
90059=Ambiguous column name {0}
90059=Ambiguous column name {0}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/_messages_es.prop
浏览文件 @
3d253279
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
90053=El Subquery escalar contiene mas de una fila
90053=El Subquery escalar contiene mas de una fila
90054=Uso Invalido de la función de columna agregada {0}
90054=Uso Invalido de la función de columna agregada {0}
90055=Cipher No soportado {0}
90055=Cipher No soportado {0}
90056=Function {0}: Invalid date format: {1}
90057=Constraint {0} no encontrado
90057=Constraint {0} no encontrado
90058=Commit ó rollback no permitido dentro de un trigger
90058=Commit ó rollback no permitido dentro de un trigger
90059=Nombre de columna ambigua {0}
90059=Nombre de columna ambigua {0}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/_messages_ja.prop
浏览文件 @
3d253279
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
90053=数値サブクエリ�複数�行を�ん����
90053=数値サブクエリ�複数�行を�ん����
90054=集約関数 {0} ã�®ä¸�æ£ã�ªä½¿ç”¨
90054=集約関数 {0} ã�®ä¸�æ£ã�ªä½¿ç”¨
90055={0} �未サ�ート�暗���
90055={0} �未サ�ート�暗���
90056=Function {0}: Invalid date format: {1}
90057=制約 {0} �見��り��ん
90057=制約 {0} �見��り��ん
90058=トリガ内ã�§ã�®ã‚³ãƒŸãƒƒãƒˆã€�ãƒãƒ¼ãƒ«ãƒ�ックã�¯è¨±ã�•れã�¦ã�„ã�¾ã�›ã‚“
90058=トリガ内ã�§ã�®ã‚³ãƒŸãƒƒãƒˆã€�ãƒãƒ¼ãƒ«ãƒ�ックã�¯è¨±ã�•れã�¦ã�„ã�¾ã�›ã‚“
90059=列� {0} �������
90059=列� {0} �������
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/_messages_pl.prop
浏览文件 @
3d253279
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
90053=Skalarna pod-kwerenda zawiera więcej niż jeden wiersz
90053=Skalarna pod-kwerenda zawiera więcej niż jeden wiersz
90054=Nieprawidłowe użycie funkcji agregującej {0}
90054=Nieprawidłowe użycie funkcji agregującej {0}
90055=Nieobsługiwany szyfr {0}
90055=Nieobsługiwany szyfr {0}
90056=Function {0}: Invalid date format: {1}
90057=Ograniczenie {0} nie istnieje
90057=Ograniczenie {0} nie istnieje
90058=Zatwierdzenie lub wycofanie transakcji nie jest dozwolone w wyzwalaczu
90058=Zatwierdzenie lub wycofanie transakcji nie jest dozwolone w wyzwalaczu
90059=Niejednoznaczna nazwa kolumny {0}
90059=Niejednoznaczna nazwa kolumny {0}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/_messages_pt_br.prop
浏览文件 @
3d253279
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
90053=A Subquery contém mais de uma linha
90053=A Subquery contém mais de uma linha
90054=Uso inválido da função {0} agregada
90054=Uso inválido da função {0} agregada
90055=Cipher {0} não é suportado
90055=Cipher {0} não é suportado
90056=Function {0}: Invalid date format: {1}
90057=Restrição {0} não foi encontrada
90057=Restrição {0} não foi encontrada
90058=#Commit or rollback is not allowed within a trigger
90058=#Commit or rollback is not allowed within a trigger
90059=Nome da coluna {0} é ambíguo.
90059=Nome da coluna {0} é ambíguo.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/_messages_ru.prop
浏览文件 @
3d253279
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
90053=Подзапро� выбирает более одной �троки
90053=Подзапро� выбирает более одной �троки
90054=�екорректное и�пользование агрегирующей функции {0}
90054=�екорректное и�пользование агрегирующей функции {0}
90055=Метод шифровани� {0} не поддерживает��
90055=Метод шифровани� {0} не поддерживает��
90056=Function {0}: Invalid date format: {1}
90057=Ограничение {0} не найдено
90057=Ограничение {0} не найдено
90058=Commit или rollback внутри триггера не допу�кает��
90058=Commit или rollback внутри триггера не допу�кает��
90059=�еоднозначное им� �толбца {0}
90059=�еоднозначное им� �толбца {0}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/res/_messages_zh_cn.prop
浏览文件 @
3d253279
...
@@ -83,6 +83,7 @@
...
@@ -83,6 +83,7 @@
90053=æ ‡é‡�å�查询(Scalar subquery)包å�«å¤šäºŽä¸€è¡Œç»“æžœ
90053=æ ‡é‡�å�查询(Scalar subquery)包å�«å¤šäºŽä¸€è¡Œç»“æžœ
90054=�法使用��函数 {0}
90054=�法使用��函数 {0}
90055=ä¸�支æŒ�çš„åŠ å¯†ç®—æ³• {0}
90055=ä¸�支æŒ�çš„åŠ å¯†ç®—æ³• {0}
90056=Function {0}: Invalid date format: {1}
90057=约� {0} 找�到
90057=约� {0} 找�到
90058=�交或回滚�能办函触�器
90058=�交或回滚�能办函触�器
90059=ä¸�æ˜Žç¡®çš„å—æ®µå�� {0}
90059=ä¸�æ˜Žç¡®çš„å—æ®µå�� {0}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
3d253279
...
@@ -11,10 +11,7 @@ import java.sql.Date;
...
@@ -11,10 +11,7 @@ import java.sql.Date;
import
java.sql.Time
;
import
java.sql.Time
;
import
java.sql.Timestamp
;
import
java.sql.Timestamp
;
import
java.text.SimpleDateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.Calendar
;
import
java.util.*
;
import
java.util.GregorianCalendar
;
import
java.util.Locale
;
import
java.util.TimeZone
;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/ToDate.java
0 → 100644
浏览文件 @
3d253279
package
org
.
h2
.
util
;
import
java.sql.Timestamp
;
import
java.util.Date
;
/**
* Emulates Oracle's TO_DATE function.<br>
* Main class
*/
public
class
ToDate
{
public
static
Timestamp
TO_DATE
(
final
String
input
,
final
String
format
)
{
ToDateParser
parser
=
ToDateParser
.
toDate
(
input
,
format
);
return
parser
.
getResultingTimestamp
();
}
public
static
Timestamp
TO_TIMESTAMP
(
final
String
input
,
final
String
format
)
{
ToDateParser
parser
=
ToDateParser
.
toTimestamp
(
input
,
format
);
return
parser
.
getResultingTimestamp
();
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/ToDateParser.java
0 → 100644
浏览文件 @
3d253279
package
org
.
h2
.
util
;
import
static
java
.
lang
.
String
.
format
;
import
java.sql.Timestamp
;
import
java.util.Calendar
;
import
java.util.Date
;
import
java.util.List
;
/**
* Emulates Oracle's TO_DATE function.<br>
* This class holds and handles the input data form the TO_DATE-method
*/
class
ToDateParser
{
private
final
String
unmodifiedInputStr
;
private
final
String
unmodifiedFormatStr
;
private
final
ConfigParam
functionName
;
private
String
inputStr
;
private
String
formatStr
;
private
final
Calendar
resultCalendar
=
(
Calendar
)
Calendar
.
getInstance
().
clone
();
private
Integer
nanos
=
null
;
private
enum
ConfigParam
{
TO_DATE
(
"DD MON YYYY"
),
TO_TIMESTAMP
(
"DD MON YYYY HH:MI:SS"
);
private
final
String
defaultFormatStr
;
ConfigParam
(
final
String
defaultFormatStr
)
{
this
.
defaultFormatStr
=
defaultFormatStr
;
}
String
getDefaultFormatStr
()
{
return
defaultFormatStr
;
}
}
static
ToDateParser
toDate
(
final
String
input
,
final
String
format
)
{
ToDateParser
result
=
new
ToDateParser
(
ConfigParam
.
TO_DATE
,
input
,
format
);
parse
(
result
);
return
result
;
}
static
ToDateParser
toTimestamp
(
final
String
input
,
final
String
format
)
{
ToDateParser
result
=
new
ToDateParser
(
ConfigParam
.
TO_TIMESTAMP
,
input
,
format
);
parse
(
result
);
return
result
;
}
/**
* @param input the input date with the date-time info
* @param format the format of date-time info
* @param functionName one of [TO_DATE, TO_TIMESTAMP] (both share the same code)
*/
ToDateParser
(
final
ConfigParam
functionName
,
final
String
input
,
final
String
format
)
{
// reset calendar - default oracle behaviour
resultCalendar
.
set
(
Calendar
.
YEAR
,
1970
);
resultCalendar
.
set
(
Calendar
.
MONTH
,
Calendar
.
getInstance
().
get
(
Calendar
.
MONTH
));
resultCalendar
.
clear
(
Calendar
.
DAY_OF_YEAR
);
resultCalendar
.
clear
(
Calendar
.
DAY_OF_WEEK
);
resultCalendar
.
clear
(
Calendar
.
DAY_OF_WEEK_IN_MONTH
);
resultCalendar
.
set
(
Calendar
.
DAY_OF_MONTH
,
1
);
resultCalendar
.
set
(
Calendar
.
HOUR
,
0
);
resultCalendar
.
set
(
Calendar
.
HOUR_OF_DAY
,
0
);
resultCalendar
.
set
(
Calendar
.
MINUTE
,
0
);
resultCalendar
.
set
(
Calendar
.
SECOND
,
0
);
resultCalendar
.
set
(
Calendar
.
MILLISECOND
,
0
);
resultCalendar
.
set
(
Calendar
.
AM_PM
,
Calendar
.
AM
);
this
.
functionName
=
functionName
;
inputStr
=
input
.
trim
();
unmodifiedInputStr
=
inputStr
;
// Keep a copy
if
(
format
==
null
||
format
.
isEmpty
())
{
formatStr
=
functionName
.
getDefaultFormatStr
();
// default Oracle format.
}
else
{
formatStr
=
format
.
trim
();
}
unmodifiedFormatStr
=
formatStr
;
// Keep a copy
}
Timestamp
getResultingTimestamp
()
{
Calendar
cal
=
(
Calendar
)
getResultCalendar
().
clone
();
int
nanosToSet
=
nanos
==
null
?
cal
.
get
(
Calendar
.
MILLISECOND
)
*
1000000
:
nanos
.
intValue
();
cal
.
set
(
Calendar
.
MILLISECOND
,
0
);
Timestamp
ts
=
new
Timestamp
(
cal
.
getTimeInMillis
());
ts
.
setNanos
(
nanosToSet
);
return
ts
;
}
Calendar
getResultCalendar
()
{
return
resultCalendar
;
}
String
getInputStr
()
{
return
inputStr
;
}
String
getFormatStr
()
{
return
formatStr
;
}
String
getFunctionName
()
{
return
functionName
.
name
();
}
void
setNanos
(
final
int
nanos
)
{
this
.
nanos
=
nanos
;
}
boolean
hasToParseData
()
{
return
formatStr
.
length
()
>
0
;
}
void
removeFirstChar
()
{
if
(!
formatStr
.
isEmpty
())
{
formatStr
=
formatStr
.
substring
(
1
);
}
if
(!
inputStr
.
isEmpty
())
{
inputStr
=
inputStr
.
substring
(
1
);
}
}
private
static
ToDateParser
parse
(
final
ToDateParser
p
)
{
while
(
p
.
hasToParseData
())
{
List
<
ToDateTokenizer
.
FormatTokenEnum
>
tokenList
=
ToDateTokenizer
.
FormatTokenEnum
.
getTokensInQuestion
(
p
.
getFormatStr
());
if
(
tokenList
.
isEmpty
())
{
p
.
removeFirstChar
();
continue
;
}
boolean
foundAnToken
=
false
;
for
(
ToDateTokenizer
.
FormatTokenEnum
token
:
tokenList
)
{
if
(
token
.
parseFormatStrWithToken
(
p
))
{
foundAnToken
=
true
;
break
;
}
}
if
(!
foundAnToken
)
{
p
.
removeFirstChar
();
continue
;
}
}
return
p
;
}
void
remove
(
final
String
toIgnore
)
{
if
(
toIgnore
!=
null
)
{
int
trimLeng
=
toIgnore
.
length
();
formatStr
=
formatStr
.
substring
(
trimLeng
);
if
(
inputStr
.
length
()
>=
trimLeng
)
{
inputStr
=
inputStr
.
substring
(
trimLeng
);
}
}
}
void
remove
(
final
String
intputFragmentStr
,
final
String
formatFragment
)
{
if
(
intputFragmentStr
!=
null
&&
inputStr
.
length
()
>=
intputFragmentStr
.
length
())
{
inputStr
=
inputStr
.
substring
(
intputFragmentStr
.
length
());
}
if
(
formatFragment
!=
null
&&
formatStr
.
length
()
>=
formatFragment
.
length
())
{
formatStr
=
formatStr
.
substring
(
formatFragment
.
length
());
}
}
@Override
public
String
toString
()
{
int
inputStrLeng
=
inputStr
.
length
();
int
orgInputLeng
=
unmodifiedInputStr
.
length
();
int
currentInputPos
=
orgInputLeng
-
inputStrLeng
;
int
restInputLeng
=
inputStrLeng
<=
0
?
inputStrLeng
:
inputStrLeng
-
1
;
int
orgFormatLeng
=
unmodifiedFormatStr
.
length
();
int
currentFormatPos
=
orgFormatLeng
-
formatStr
.
length
();
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
format
(
"\n %s('%s', '%s')"
,
functionName
,
unmodifiedInputStr
,
unmodifiedFormatStr
));
sb
.
append
(
format
(
"\n %s^%s , %s^ <-- Parsing failed at this point"
,
//
format
(
"%"
+
(
functionName
.
name
().
length
()
+
currentInputPos
)
+
"s"
,
""
),
restInputLeng
<=
0
?
""
:
format
(
"%"
+
restInputLeng
+
"s"
,
""
),
currentFormatPos
<=
0
?
""
:
format
(
"%"
+
currentFormatPos
+
"s"
,
""
)));
return
sb
.
toString
();
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/ToDateTokenizer.java
0 → 100644
浏览文件 @
3d253279
差异被折叠。
点击展开。
h2/src/test/org/h2/samples/ToDate.java
0 → 100644
浏览文件 @
3d253279
/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
samples
;
import
org.h2.tools.DeleteDbFiles
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.ResultSet
;
import
java.sql.Statement
;
import
java.text.DateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.Locale
;
import
java.util.TimeZone
;
/**
* A very simple class that shows how to load the driver, create a database,
* create a table, and insert some data.
*/
public
class
ToDate
{
/**
* Called when ran from command line.
*
* @param args ignored
*/
public
static
void
main
(
String
...
args
)
throws
Exception
{
// delete the database named 'test' in the user home directory
DeleteDbFiles
.
execute
(
"~"
,
"test"
,
true
);
Class
.
forName
(
"org.h2.Driver"
);
Connection
conn
=
DriverManager
.
getConnection
(
"jdbc:h2:~/test"
);
Statement
stat
=
conn
.
createStatement
();
stat
.
execute
(
"create table ToDateTest(id int primary key, start_date datetime, end_date datetime)"
);
stat
.
execute
(
"insert into ToDateTest values(1, TO_DATE('2015-11-13', 'yyyy-MM-DD'), TO_DATE('2015-12-15', 'YYYY-MM-DD'))"
);
stat
.
execute
(
"insert into ToDateTest values(2, TO_DATE('2015-12-12 00:00:00', 'yyyy-MM-DD HH24:MI:ss'), TO_DATE('2015-12-16 15:00:00', 'YYYY-MM-DD HH24:MI:ss'))"
);
stat
.
execute
(
"insert into ToDateTest values(3, TO_DATE('2015-12-12 08:00 A.M.', 'yyyy-MM-DD HH:MI AM'), TO_DATE('2015-12-17 08:00 P.M.', 'YYYY-MM-DD HH:MI AM'))"
);
stat
.
execute
(
"insert into ToDateTest values(4, TO_DATE(substr('2015-12-12 08:00 A.M.', 1, 10), 'yyyy-MM-DD'), TO_DATE('2015-12-17 08:00 P.M.', 'YYYY-MM-DD HH:MI AM'))"
);
ResultSet
rs
=
stat
.
executeQuery
(
"select * from ToDateTest"
);
while
(
rs
.
next
())
{
System
.
out
.
println
(
"Start date: "
+
dateToString
(
rs
.
getTimestamp
(
"start_date"
)));
System
.
out
.
println
(
"End date: "
+
dateToString
(
rs
.
getTimestamp
(
"end_date"
)));
System
.
out
.
println
();
}
stat
.
close
();
conn
.
close
();
}
private
static
String
dateToString
(
Date
date
)
{
return
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
).
format
(
date
);
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/db/TestFunctions.java
浏览文件 @
3d253279
...
@@ -27,6 +27,8 @@ import java.sql.SQLException;
...
@@ -27,6 +27,8 @@ import java.sql.SQLException;
import
java.sql.Statement
;
import
java.sql.Statement
;
import
java.sql.Timestamp
;
import
java.sql.Timestamp
;
import
java.sql.Types
;
import
java.sql.Types
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Calendar
;
import
java.util.Calendar
;
import
java.util.Currency
;
import
java.util.Currency
;
...
@@ -42,6 +44,7 @@ import org.h2.api.AggregateFunction;
...
@@ -42,6 +44,7 @@ import org.h2.api.AggregateFunction;
import
org.h2.api.ErrorCode
;
import
org.h2.api.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Constants
;
import
org.h2.jdbc.JdbcSQLException
;
import
org.h2.jdbc.JdbcSQLException
;
import
org.h2.message.DbException
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
import
org.h2.test.ap.TestAnnotationProcessor
;
import
org.h2.test.ap.TestAnnotationProcessor
;
...
@@ -49,6 +52,7 @@ import org.h2.tools.SimpleResultSet;
...
@@ -49,6 +52,7 @@ import org.h2.tools.SimpleResultSet;
import
org.h2.util.IOUtils
;
import
org.h2.util.IOUtils
;
import
org.h2.util.New
;
import
org.h2.util.New
;
import
org.h2.util.StringUtils
;
import
org.h2.util.StringUtils
;
import
org.h2.util.ToDate
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
/**
/**
...
@@ -72,6 +76,8 @@ public class TestFunctions extends TestBase implements AggregateFunction {
...
@@ -72,6 +76,8 @@ public class TestFunctions extends TestBase implements AggregateFunction {
@Override
@Override
public
void
test
()
throws
Exception
{
public
void
test
()
throws
Exception
{
deleteDb
(
"functions"
);
deleteDb
(
"functions"
);
testToDate
();
testToDateException
();
testDataType
();
testDataType
();
testVersion
();
testVersion
();
testFunctionTable
();
testFunctionTable
();
...
@@ -1275,6 +1281,123 @@ public class TestFunctions extends TestBase implements AggregateFunction {
...
@@ -1275,6 +1281,123 @@ public class TestFunctions extends TestBase implements AggregateFunction {
String
.
format
(
"SELECT ORA_HASH('%s', 0, 0) FROM DUAL"
,
testStr
));
String
.
format
(
"SELECT ORA_HASH('%s', 0, 0) FROM DUAL"
,
testStr
));
}
}
private
void
testToDateException
()
{
try
{
ToDate
.
TO_DATE
(
"1979-ThisWillFail-12"
,
"YYYY-MM-DD"
);
}
catch
(
Exception
e
)
{
assertEquals
(
DbException
.
class
.
getSimpleName
(),
e
.
getClass
().
getSimpleName
());
}
}
private
void
testToDate
()
throws
SQLException
,
ParseException
{
final
int
curMonth
=
Calendar
.
getInstance
().
get
(
Calendar
.
MONTH
);
Date
date
=
null
;
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
"1979-11-12"
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979-11-12"
,
"YYYY-MM-DD"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979/11/12"
,
"YYYY/MM/DD"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979,11,12"
,
"YYYY,MM,DD"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979.11.12"
,
"YYYY.MM.DD"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979;11;12"
,
"YYYY;MM;DD"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979:11:12"
,
"YYYY:MM:DD"
));
date
=
new
SimpleDateFormat
(
"yyyy"
).
parse
(
"1979"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979"
,
"YYYY"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979 AD"
,
"YYYY AD"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979 A.D."
,
"YYYY A.D."
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979 A.D."
,
"YYYY BC"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1979"
,
"IYYY"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"+1979"
,
"SYYYY"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"79"
,
"RRRR"
));
date
=
new
SimpleDateFormat
(
"yyyy-mm"
).
parse
(
"1970-12"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"12"
,
"MI"
));
date
=
new
SimpleDateFormat
(
"yyyy-MM"
).
parse
(
"1970-11"
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"11"
,
"MM"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"11"
,
"Mm"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"11"
,
"mM"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"11"
,
"mm"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"XI"
,
"RM"
));
date
=
new
SimpleDateFormat
(
"yyyy"
).
parse
(
"9"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"9"
,
"Y"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"9"
,
"I"
));
date
=
new
SimpleDateFormat
(
"yyyy"
).
parse
(
"79"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"79"
,
"YY"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"79"
,
"IY"
));
date
=
new
SimpleDateFormat
(
"yyyy"
).
parse
(
"979"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"979"
,
"YYY"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"979"
,
"IYY"
));
// Gregorian calendar does not have a year 0. 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
date
=
new
SimpleDateFormat
(
"yyy"
).
parse
(
"-99"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"0100 BC"
,
"YYYY BC"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"0100 B.C."
,
"YYYY B.C."
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"100 BC"
,
"YYY BC"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"-0100"
,
"SYYYY"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"-0100"
,
"YYYY"
));
// Gregorian calendar does not have a year 0. 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
date
=
new
SimpleDateFormat
(
"y"
).
parse
(
"0"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"01 BC"
,
"YY BC"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"1 BC"
,
"Y BC"
));
date
=
new
SimpleDateFormat
(
"hh:mm:ss"
).
parse
(
"08:12:00"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"08:12 AM"
,
"HH:MI AM"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"08:12 A.M."
,
"HH:MI A.M."
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"08:12"
,
"HH24:MI"
));
date
=
new
SimpleDateFormat
(
"hh:mm:ss"
).
parse
(
"08:12:00"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"08:12"
,
"HH:MI"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"08:12"
,
"HH12:MI"
));
date
=
new
SimpleDateFormat
(
"hh:mm:ss"
).
parse
(
"08:12:34"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"08:12:34"
,
"HH:MI:SS"
));
date
=
new
SimpleDateFormat
(
"ss"
).
parse
(
"34"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"34"
,
"SS"
));
date
=
new
SimpleDateFormat
(
"yyyy hh:mm:ss"
).
parse
(
"1970 08:12:34"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"29554"
,
"SSSSS"
));
date
=
new
SimpleDateFormat
(
"yyyy hh:mm:ss SSS"
).
parse
(
"1970 08:12:34 550"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"08:12:34 550"
,
"HH:MI:SS FF"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"08:12:34 55"
,
"HH:MI:SS FF2"
));
date
=
new
SimpleDateFormat
(
"hh:mm:ss"
).
parse
(
"14:04:00"
);
date
.
setMonth
(
curMonth
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"02:04 P.M."
,
"HH:MI p.M."
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"02:04 PM"
,
"HH:MI PM"
));
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
"1970-12-12"
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"12"
,
"DD"
));
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
"1970-11-12"
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"316"
,
"DDD"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"316"
,
"DdD"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"316"
,
"dDD"
));
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"316"
,
"ddd"
));
date
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
"2013-01-29"
);
assertEquals
(
date
,
ToDate
.
TO_DATE
(
"113029"
,
"J"
));
}
private
void
testToCharFromDateTime
()
throws
SQLException
{
private
void
testToCharFromDateTime
()
throws
SQLException
{
deleteDb
(
"functions"
);
deleteDb
(
"functions"
);
Connection
conn
=
getConnection
(
"functions"
);
Connection
conn
=
getConnection
(
"functions"
);
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论