Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
0c7d6634
提交
0c7d6634
authored
12月 22, 2015
作者:
Patrick Brielmayer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added TO_DATE and TO_TIMESTAMP functionality
上级
990e81ce
全部展开
显示空白字符变更
内嵌
并排
正在显示
17 个修改的文件
包含
1019 行增加
和
16 行删除
+1019
-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
+55
-4
ToDate.java
h2/src/main/org/h2/util/ToDate.java
+63
-0
ToDateParams.java
h2/src/main/org/h2/util/ToDateParams.java
+139
-0
ToDateTokenizer.java
h2/src/main/org/h2/util/ToDateTokenizer.java
+548
-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
浏览文件 @
0c7d6634
...
...
@@ -1001,6 +1001,12 @@ public class ErrorCode {
*/
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
* trying to drop a constraint that does not exist.
...
...
@@ -1923,7 +1929,7 @@ public class ErrorCode {
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
()
{
// utility class
...
...
h2/src/main/org/h2/expression/Function.java
浏览文件 @
0c7d6634
...
...
@@ -44,16 +44,7 @@ import org.h2.table.Table;
import
org.h2.table.TableFilter
;
import
org.h2.tools.CompressTool
;
import
org.h2.tools.Csv
;
import
org.h2.util.AutoCloseInputStream
;
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.util.*
;
import
org.h2.value.DataType
;
import
org.h2.value.Value
;
import
org.h2.value.ValueArray
;
...
...
@@ -93,7 +84,8 @@ public class Function extends Expression implements FunctionCall {
STRINGDECODE
=
80
,
STRINGTOUTF8
=
81
,
UTF8TOSTRING
=
82
,
XMLATTR
=
83
,
XMLNODE
=
84
,
XMLCOMMENT
=
85
,
XMLCDATA
=
86
,
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
,
DATE_DIFF
=
103
,
DAY_NAME
=
104
,
DAY_OF_MONTH
=
105
,
...
...
@@ -306,6 +298,8 @@ public class Function extends Expression implements FunctionCall {
0
,
Value
.
DATE
);
addFunctionNotDeterministic
(
"CURDATE"
,
CURDATE
,
0
,
Value
.
DATE
);
addFunction
(
"TO_DATE"
,
TO_DATE
,
VAR_ARGS
,
Value
.
STRING
);
addFunction
(
"TO_TIMESTAMP"
,
TO_TIMESTAMP
,
VAR_ARGS
,
Value
.
STRING
);
// alias for MSSQLServer
addFunctionNotDeterministic
(
"GETDATE"
,
CURDATE
,
0
,
Value
.
DATE
);
...
...
@@ -1429,6 +1423,14 @@ public class Function extends Expression implements FunctionCall {
database
.
getMode
().
treatEmptyStringsAsNull
);
}
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:
{
String
matching
=
v1
.
getString
();
String
replacement
=
v2
.
getString
();
...
...
@@ -2123,10 +2125,12 @@ public class Function extends Expression implements FunctionCall {
case
ROUND:
case
XMLTEXT:
case
TRUNCATE:
case
TO_TIMESTAMP:
min
=
1
;
max
=
2
;
break
;
case
TO_CHAR:
case
TO_DATE:
min
=
1
;
max
=
3
;
break
;
...
...
h2/src/main/org/h2/res/_messages_cs.prop
浏览文件 @
0c7d6634
...
...
@@ -83,6 +83,7 @@
90053=Skalárnà vnoÅ™ený dotaz obsahuje vÃce než jeden řádek
90054=Neplatné použità agregátnà funkce {0}
90055=Nepodporované šifrovánà {0}
90056=Function {0}: Invalid date format: {1}
90057=Omezenà {0} nenalezeno
90058=Vkládánà nebo vrácenà změn nenà povoleno uvnitř triggeru
90059=Dvojsmyslný název sloupce {0}
...
...
h2/src/main/org/h2/res/_messages_de.prop
浏览文件 @
0c7d6634
...
...
@@ -83,6 +83,7 @@
90053=Skalar-Unterabfrage enthält mehr als eine Zeile
90054=Ungültige Verwendung der Aggregat Funktion {0}
90055=Chiffre nicht unterstützt: {0}
90056=Funktion {0}: Ungültiges TO_DATE Format: {1}
90057=Bedingung {0} nicht gefunden
90058=Innerhalb eines Triggers sind Commit und Rollback ist nicht erlaubt
90059=Mehrdeutiger Feldname {0}
...
...
h2/src/main/org/h2/res/_messages_en.prop
浏览文件 @
0c7d6634
...
...
@@ -83,6 +83,7 @@
90053=Scalar subquery contains more than one row
90054=Invalid use of aggregate function {0}
90055=Unsupported cipher {0}
90056=Function {0}: Invalid date format: {1}
90057=Constraint {0} not found
90058=Commit or rollback is not allowed within a trigger
90059=Ambiguous column name {0}
...
...
h2/src/main/org/h2/res/_messages_es.prop
浏览文件 @
0c7d6634
...
...
@@ -83,6 +83,7 @@
90053=El Subquery escalar contiene mas de una fila
90054=Uso Invalido de la función de columna agregada {0}
90055=Cipher No soportado {0}
90056=Function {0}: Invalid date format: {1}
90057=Constraint {0} no encontrado
90058=Commit ó rollback no permitido dentro de un trigger
90059=Nombre de columna ambigua {0}
...
...
h2/src/main/org/h2/res/_messages_ja.prop
浏览文件 @
0c7d6634
...
...
@@ -83,6 +83,7 @@
90053=数値サブクエリ�複数�行を�ん����
90054=集約関数 {0} ã�®ä¸�æ£ã�ªä½¿ç”¨
90055={0} �未サ�ート�暗���
90056=Function {0}: Invalid date format: {1}
90057=制約 {0} �見��り��ん
90058=トリガ内ã�§ã�®ã‚³ãƒŸãƒƒãƒˆã€�ãƒãƒ¼ãƒ«ãƒ�ックã�¯è¨±ã�•ã‚Œã�¦ã�„ã�¾ã�›ã‚“
90059=列� {0} �������
...
...
h2/src/main/org/h2/res/_messages_pl.prop
浏览文件 @
0c7d6634
...
...
@@ -83,6 +83,7 @@
90053=Skalarna pod-kwerenda zawiera więcej niż jeden wiersz
90054=Nieprawidłowe użycie funkcji agregującej {0}
90055=Nieobsługiwany szyfr {0}
90056=Function {0}: Invalid date format: {1}
90057=Ograniczenie {0} nie istnieje
90058=Zatwierdzenie lub wycofanie transakcji nie jest dozwolone w wyzwalaczu
90059=Niejednoznaczna nazwa kolumny {0}
...
...
h2/src/main/org/h2/res/_messages_pt_br.prop
浏览文件 @
0c7d6634
...
...
@@ -83,6 +83,7 @@
90053=A Subquery contém mais de uma linha
90054=Uso inválido da função {0} agregada
90055=Cipher {0} não é suportado
90056=Function {0}: Invalid date format: {1}
90057=Restrição {0} não foi encontrada
90058=#Commit or rollback is not allowed within a trigger
90059=Nome da coluna {0} é ambíguo.
...
...
h2/src/main/org/h2/res/_messages_ru.prop
浏览文件 @
0c7d6634
...
...
@@ -83,6 +83,7 @@
90053=Подзапро� выбирает более одной �троки
90054=�екорректное и�пользование агрегирующей функции {0}
90055=Метод шифровани� {0} не поддерживает��
90056=Function {0}: Invalid date format: {1}
90057=Ограничение {0} не найдено
90058=Commit или rollback внутри триггера не допу�кает��
90059=�еоднозначное им� �толбца {0}
...
...
h2/src/main/org/h2/res/_messages_zh_cn.prop
浏览文件 @
0c7d6634
...
...
@@ -83,6 +83,7 @@
90053=æ ‡é‡�å�查询(Scalar subquery)包å�«å¤šäºŽä¸€è¡Œç»“æžœ
90054=�法使用��函数 {0}
90055=ä¸�支æŒ�çš„åŠ å¯†ç®—æ³• {0}
90056=Function {0}: Invalid date format: {1}
90057=约� {0} 找�到
90058=�交或回滚�能办函触�器
90059=ä¸�明确的å—段å�� {0}
...
...
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
0c7d6634
...
...
@@ -10,11 +10,9 @@ package org.h2.util;
import
java.sql.Date
;
import
java.sql.Time
;
import
java.sql.Timestamp
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.Calendar
;
import
java.util.GregorianCalendar
;
import
java.util.Locale
;
import
java.util.TimeZone
;
import
java.util.*
;
import
org.h2.api.ErrorCode
;
import
org.h2.message.DbException
;
...
...
@@ -583,6 +581,59 @@ public class DateTimeUtils {
}
}
@SuppressWarnings
(
"serial"
)
private
static
final
Map
<
String
,
String
>
DATE_FORMAT_REGEXPS
=
new
HashMap
<
String
,
String
>()
{
{
put
(
"^\\d{8}[^\\d]*"
,
"yyyyMMdd"
);
put
(
"^\\d{1,2}\\.\\d{1,2}\\.\\d{4}[^\\d]*"
,
"dd.MM.yyyy"
);
put
(
"^\\d{4}\\.\\d{1,2}\\.\\d{1,2}[^\\d]*"
,
"yyyy.MM.dd"
);
put
(
"^\\d{4}-\\d{1,2}-\\d{1,2}[^\\d]*"
,
"yyyy-MM-dd"
);
put
(
"^\\d{1,2}-\\d{1,2}-\\d{4}[^\\d]*"
,
"dd-MM-yyyy"
);
put
(
"^\\d{1,2}/\\d{1,2}/\\d{4}[^\\d]*"
,
"dd/MM/yyyy"
);
put
(
"^\\d{4}/\\d{1,2}/\\d{1,2}[^\\d]*"
,
"yyyy/MM/dd"
);
put
(
"^\\d{1,2}/\\d{1,2}/\\d{4}[^\\d]*"
,
"dd/MM/yyyy"
);
put
(
"^\\d{1,2}-[^\\d]{3}-\\d{4}[^\\d]*"
,
"dd-MMM-yyyy"
);
put
(
"^\\d{4}-[^\\d]{3}-\\d{1,2}[^\\d]*"
,
"yyyy-MMM-dd"
);
put
(
"^.{2}\\s.{3}\\s\\d{1,2}\\s\\d{1,2}\\:\\d{1,2}\\:\\d{1,2}\\s.{3}\\s\\d{4}$"
,
"EEE MMM dd hh:mm:ss z yyyy"
);
}
};
/**
* Determine SimpleDateFormat pattern matching with the given date string. Returns null if format is unknown. You can
* simply extend DateUtil with more formats if needed.
*
* @param dateString
* The date string to determine the SimpleDateFormat pattern for.
* @return The matching SimpleDateFormat pattern, or null if format is unknown.
*/
private
static
String
determineDateFormat
(
final
String
dateString
)
{
for
(
String
regexp
:
DATE_FORMAT_REGEXPS
.
keySet
())
{
if
(
dateString
.
toLowerCase
().
matches
(
regexp
))
{
return
DATE_FORMAT_REGEXPS
.
get
(
regexp
);
}
}
return
null
;
// Unknown format.
}
/**
* Parse date-string in "Best Effort" (BE) manner.
* Uses a predefined list of date patterns to parse a string into a date.
*/
public
static
java
.
util
.
Date
parseDateBestEffort
(
final
String
dateStr
)
{
String
dateFormat
=
determineDateFormat
(
dateStr
);
if
(
dateFormat
==
null
)
{
// The source does not contain a date that can be parsed.
throw
DbException
.
get
(
ErrorCode
.
PARSE_ERROR_1
,
"Invalid date. "
+
dateStr
);
}
SimpleDateFormat
formatter
=
new
SimpleDateFormat
(
dateFormat
);
try
{
return
formatter
.
parse
(
dateStr
);
}
catch
(
ParseException
e
)
{
throw
DbException
.
get
(
ErrorCode
.
PARSE_ERROR_1
,
e
,
"Invalid date. "
+
dateStr
);
}
}
/**
* Parses a date using a format string.
*
...
...
h2/src/main/org/h2/util/ToDate.java
0 → 100644
浏览文件 @
0c7d6634
package
org
.
h2
.
util
;
import
java.sql.Timestamp
;
import
java.util.List
;
import
org.h2.util.ToDateTokenizer.FormatTokenEnum
;
/**
* Emulates Oracle's TO_DATE function.<br>
* Main class
*/
public
class
ToDate
{
public
enum
ToDateFunctionName
{
TO_DATE
(
"DD MON YYYY"
),
TO_TIMESTAMP
(
"DD MON YYYY HH:MI:SS"
);
private
final
String
defaultFormatStr
;
ToDateFunctionName
(
final
String
defaultFormatStr
)
{
this
.
defaultFormatStr
=
defaultFormatStr
;
}
String
getDefaultFormatStr
()
{
return
defaultFormatStr
;
}
};
public
static
Timestamp
TO_DATE
(
final
String
input
,
final
String
format
)
{
ToDateParams
parsed
=
parse
(
new
ToDateParams
(
ToDateFunctionName
.
TO_DATE
,
input
,
format
));
return
parsed
.
getResultingTimestamp
();
}
public
static
Timestamp
TO_TIMESTAMP
(
final
String
input
,
final
String
format
)
{
ToDateParams
parsed
=
parse
(
new
ToDateParams
(
ToDateFunctionName
.
TO_TIMESTAMP
,
input
,
format
));
return
parsed
.
getResultingTimestamp
();
}
/**
* Parse the format-string with passed token of {@link FormatTokenEnum}}.<br>
* if token matches return true otherwise false.
*/
private
static
ToDateParams
parse
(
final
ToDateParams
p
)
{
while
(
p
.
hasToParseData
())
{
List
<
FormatTokenEnum
>
tokenList
=
FormatTokenEnum
.
getTokensInQuestion
(
p
);
if
(
tokenList
.
isEmpty
())
{
p
.
removeFirstChar
();
continue
;
}
boolean
foundAnToken
=
false
;
for
(
FormatTokenEnum
token
:
tokenList
)
{
if
(
token
.
parseFormatStrWithToken
(
p
))
{
foundAnToken
=
true
;
break
;
}
}
if
(!
foundAnToken
)
{
p
.
removeFirstChar
();
continue
;
}
}
return
p
;
}
}
\ No newline at end of file
h2/src/main/org/h2/util/ToDateParams.java
0 → 100644
浏览文件 @
0c7d6634
package
org
.
h2
.
util
;
import
static
java
.
lang
.
String
.
format
;
import
java.sql.Date
;
import
java.sql.Timestamp
;
import
java.util.Calendar
;
import
org.h2.util.ToDate.ToDateFunctionName
;
/**
* Emulates Oracle's TO_DATE function.<br>
* This class holds and handles the input data form the TO_DATE-method
*/
class
ToDateParams
{
private
final
String
unmodifiedInputStr
;
private
final
String
unmodifiedFormatStr
;
private
final
ToDateFunctionName
functionName
;
private
String
inputStr
;
private
String
formatStr
;
private
final
Calendar
resultCalendar
=
(
Calendar
)
Calendar
.
getInstance
().
clone
();
private
Integer
nanos
=
null
;
/**
* @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)
*/
ToDateParams
(
final
ToDateFunctionName
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
}
Date
getResultingDate
()
{
return
new
Date
(
getResultCalendar
().
getTimeInMillis
());
}
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
;
}
ToDateFunctionName
getFunctionName
()
{
return
functionName
;
}
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
);
}
}
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
h2/src/main/org/h2/util/ToDateTokenizer.java
0 → 100644
浏览文件 @
0c7d6634
差异被折叠。
点击展开。
h2/src/test/org/h2/samples/ToDate.java
0 → 100644
浏览文件 @
0c7d6634
/*
* 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
);
}
}
h2/src/test/org/h2/test/db/TestFunctions.java
浏览文件 @
0c7d6634
...
...
@@ -27,6 +27,8 @@ import java.sql.SQLException;
import
java.sql.Statement
;
import
java.sql.Timestamp
;
import
java.sql.Types
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.Calendar
;
import
java.util.Currency
;
...
...
@@ -42,6 +44,7 @@ import org.h2.api.AggregateFunction;
import
org.h2.api.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.jdbc.JdbcSQLException
;
import
org.h2.message.DbException
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.test.TestBase
;
import
org.h2.test.ap.TestAnnotationProcessor
;
...
...
@@ -49,6 +52,7 @@ import org.h2.tools.SimpleResultSet;
import
org.h2.util.IOUtils
;
import
org.h2.util.New
;
import
org.h2.util.StringUtils
;
import
org.h2.util.ToDate
;
import
org.h2.value.Value
;
/**
...
...
@@ -72,6 +76,8 @@ public class TestFunctions extends TestBase implements AggregateFunction {
@Override
public
void
test
()
throws
Exception
{
deleteDb
(
"functions"
);
testToDate
();
testToDateException
();
testDataType
();
testVersion
();
testFunctionTable
();
...
...
@@ -1275,6 +1281,123 @@ public class TestFunctions extends TestBase implements AggregateFunction {
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
{
deleteDb
(
"functions"
);
Connection
conn
=
getConnection
(
"functions"
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论