Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
e0619d3a
Unverified
提交
e0619d3a
authored
7 年前
作者:
Noel Grandin
提交者:
GitHub
7 年前
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #855 from katzyn/datetime
Reimplement DATEADD without a Calendar and fix some incompatibilities
上级
547dfcbd
eb46908e
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
250 行增加
和
62 行删除
+250
-62
help.csv
h2/src/docsrc/help/help.csv
+7
-4
Function.java
h2/src/main/org/h2/expression/Function.java
+71
-36
DateTimeUtils.java
h2/src/main/org/h2/util/DateTimeUtils.java
+89
-17
dateadd.sql
...est/org/h2/test/scripts/functions/timeanddate/dateadd.sql
+34
-1
datediff.sql
...st/org/h2/test/scripts/functions/timeanddate/datediff.sql
+31
-0
testScript.sql
h2/src/test/org/h2/test/scripts/testScript.sql
+3
-3
TestDateTimeUtils.java
h2/src/test/org/h2/test/unit/TestDateTimeUtils.java
+15
-1
没有找到文件。
h2/src/docsrc/help/help.csv
浏览文件 @
e0619d3a
...
...
@@ -3668,12 +3668,14 @@ CURRENT_TIMESTAMP()
"Functions (Time and Date)","DATEADD","
{ DATEADD| TIMESTAMPADD } (unitString, addIntLong, timestamp)
","
Adds units to a
timestamp
. The string indicates the unit.
Adds units to a
date-time value
. The string indicates the unit.
Use negative values to subtract units.
addIntLong may be a long value when manipulating milliseconds,
otherwise it's range is restricted to int.
The same units as in the EXTRACT function are supported.
DATEADD method returns a timestamp. TIMESTAMPADD method returns a long.
This method returns a value with the same type as specified value if unit is compatible with this value.
If specified unit is a HOUR, MINUTE, SECOND, MILLISECOND, etc and value is a DATE value DATEADD returns combined TIMESTAMP.
Units DAY, MONTH, YEAR, WEEK, etc are not allowed for TIME values.
","
DATEADD('MONTH', 1, DATE '2001-01-31')
"
...
...
@@ -3723,8 +3725,9 @@ DAY_OF_YEAR(CREATED)
"
"Functions (Time and Date)","EXTRACT","
EXTRACT ( { YEAR | YY | MONTH | MM | WEEK | ISO_WEEK | DAY | DD | DAY_OF_YEAR
| DOY | HOUR | HH | MINUTE | MI | SECOND | SS | MILLISECOND | MS }
EXTRACT ( { YEAR | YY | MONTH | MM | QUARTER | WEEK | ISO_WEEK
| DAY | DD | DAY_OF_YEAR | DOY
| HOUR | HH | MINUTE | MI | SECOND | SS | MILLISECOND | MS }
FROM timestamp )
","
Returns a specific value from a timestamps.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/expression/Function.java
浏览文件 @
e0619d3a
...
...
@@ -14,7 +14,6 @@ import java.nio.charset.StandardCharsets;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.SQLException
;
import
java.sql.Timestamp
;
import
java.text.SimpleDateFormat
;
import
java.util.ArrayList
;
import
java.util.Calendar
;
...
...
@@ -171,6 +170,7 @@ public class Function extends Expression implements FunctionCall {
DATE_PART
.
put
(
"MONTH"
,
MONTH
);
DATE_PART
.
put
(
"MM"
,
MONTH
);
DATE_PART
.
put
(
"M"
,
MONTH
);
DATE_PART
.
put
(
"QUARTER"
,
QUARTER
);
DATE_PART
.
put
(
"SQL_TSI_WEEK"
,
WEEK
);
DATE_PART
.
put
(
"WW"
,
WEEK
);
DATE_PART
.
put
(
"WK"
,
WEEK
);
...
...
@@ -348,7 +348,7 @@ public class Function extends Expression implements FunctionCall {
addFunction
(
"DATEADD"
,
DATE_ADD
,
3
,
Value
.
TIMESTAMP
);
addFunction
(
"TIMESTAMPADD"
,
DATE_ADD
,
3
,
Value
.
LONG
);
3
,
Value
.
TIMESTAMP
);
addFunction
(
"DATEDIFF"
,
DATE_DIFF
,
3
,
Value
.
LONG
);
addFunction
(
"TIMESTAMPDIFF"
,
DATE_DIFF
,
...
...
@@ -1486,8 +1486,7 @@ public class Function extends Expression implements FunctionCall {
database
.
getMode
().
treatEmptyStringsAsNull
);
break
;
case
DATE_ADD:
result
=
ValueTimestamp
.
get
(
dateadd
(
v0
.
getString
(),
v1
.
getLong
(),
v2
.
getTimestamp
()));
result
=
dateadd
(
v0
.
getString
(),
v1
.
getLong
(),
v2
);
break
;
case
DATE_DIFF:
result
=
ValueLong
.
get
(
datediff
(
v0
.
getString
(),
v1
,
v2
));
...
...
@@ -1806,53 +1805,85 @@ public class Function extends Expression implements FunctionCall {
return
p
.
intValue
();
}
private
static
Timestamp
dateadd
(
String
part
,
long
count
,
Timestamp
d
)
{
private
static
Value
dateadd
(
String
part
,
long
count
,
Value
v
)
{
int
field
=
getDatePart
(
part
);
//v = v.convertTo(Value.TIMESTAMP);
if
(
field
!=
MILLISECOND
&&
(
count
>
Integer
.
MAX_VALUE
||
count
<
Integer
.
MIN_VALUE
))
{
throw
DbException
.
getInvalidValueException
(
"DATEADD count"
,
count
);
}
boolean
withDate
=
!(
v
instanceof
ValueTime
);
boolean
withTime
=
!(
v
instanceof
ValueDate
);
boolean
forceTimestamp
=
false
;
long
[]
a
=
DateTimeUtils
.
dateAndTimeFromValue
(
v
);
long
dateValue
=
a
[
0
];
long
timeNanos
=
a
[
1
];
switch
(
field
)
{
case
QUARTER:
count
*=
3
;
//$FALL-THROUGH$
case
YEAR:
field
=
Calendar
.
YEAR
;
break
;
case
MONTH:
field
=
Calendar
.
MONTH
;
break
;
case
MONTH:
{
if
(!
withDate
)
{
throw
DbException
.
getInvalidValueException
(
"DATEADD time part"
,
part
);
}
long
year
=
DateTimeUtils
.
yearFromDateValue
(
dateValue
);
long
month
=
DateTimeUtils
.
monthFromDateValue
(
dateValue
);
int
day
=
DateTimeUtils
.
dayFromDateValue
(
dateValue
);
if
(
field
==
YEAR
)
{
year
+=
count
;
}
else
{
month
+=
count
;
}
dateValue
=
DateTimeUtils
.
dateValueFromDenormalizedDate
(
year
,
month
,
day
);
return
DateTimeUtils
.
dateTimeToValue
(
v
,
dateValue
,
timeNanos
,
forceTimestamp
);
}
case
WEEK:
case
ISO_WEEK:
count
*=
7
;
//$FALL-THROUGH$
case
DAY_OF_WEEK:
case
DAY_OF_MONTH:
field
=
Calendar
.
DAY_OF_MONTH
;
break
;
case
DAY_OF_YEAR:
field
=
Calendar
.
DAY_OF_YEAR
;
break
;
case
WEEK:
field
=
Calendar
.
WEEK_OF_YEAR
;
break
;
if
(!
withDate
)
{
throw
DbException
.
getInvalidValueException
(
"DATEADD time part"
,
part
);
}
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
DateTimeUtils
.
absoluteDayFromDateValue
(
dateValue
)
+
count
);
return
DateTimeUtils
.
dateTimeToValue
(
v
,
dateValue
,
timeNanos
,
forceTimestamp
);
case
HOUR:
field
=
Calendar
.
HOUR_OF_DAY
;
count
*=
3_600_000_000_000L
;
break
;
case
MINUTE:
field
=
Calendar
.
MINUTE
;
count
*=
60_000_000_000L
;
break
;
case
SECOND:
field
=
Calendar
.
SECOND
;
count
*=
1_000_000_000
;
break
;
case
MILLISECOND:
count
*=
1_000_000
;
break
;
case
MILLISECOND:
{
Timestamp
ts
=
new
Timestamp
(
d
.
getTime
()
+
count
);
ts
.
setNanos
(
ts
.
getNanos
()
+
(
d
.
getNanos
()
%
1000000
));
return
ts
;
}
default
:
throw
DbException
.
getUnsupportedException
(
"DATEADD "
+
part
);
}
// We allow long for manipulating the millisecond component,
// for the rest we only allow int.
if
(
count
>
Integer
.
MAX_VALUE
)
{
throw
DbException
.
getInvalidValueException
(
"DATEADD count"
,
count
);
if
(!
withTime
)
{
// Treat date as timestamp at the start of this date
forceTimestamp
=
true
;
}
Calendar
calendar
=
DateTimeUtils
.
createGregorianCalendar
();
int
nanos
=
d
.
getNanos
()
%
1000000
;
calendar
.
setTime
(
d
);
calendar
.
add
(
field
,
(
int
)
count
);
Timestamp
ts
=
new
Timestamp
(
calendar
.
getTimeInMillis
());
ts
.
setNanos
(
ts
.
getNanos
()
+
nanos
);
return
ts
;
timeNanos
+=
count
;
if
(
timeNanos
>
DateTimeUtils
.
NANOS_PER_DAY
||
timeNanos
<
0
)
{
long
d
;
if
(
timeNanos
>
DateTimeUtils
.
NANOS_PER_DAY
)
{
d
=
timeNanos
/
DateTimeUtils
.
NANOS_PER_DAY
;
}
else
{
d
=
(
timeNanos
-
DateTimeUtils
.
NANOS_PER_DAY
+
1
)
/
DateTimeUtils
.
NANOS_PER_DAY
;
}
timeNanos
-=
d
*
DateTimeUtils
.
NANOS_PER_DAY
;
return
DateTimeUtils
.
dateTimeToValue
(
v
,
DateTimeUtils
.
dateValueFromAbsoluteDay
(
DateTimeUtils
.
absoluteDayFromDateValue
(
dateValue
)
+
d
),
timeNanos
,
forceTimestamp
);
}
return
DateTimeUtils
.
dateTimeToValue
(
v
,
dateValue
,
timeNanos
,
forceTimestamp
);
}
/**
...
...
@@ -1908,6 +1939,10 @@ public class Function extends Expression implements FunctionCall {
case
MONTH:
return
(
DateTimeUtils
.
yearFromDateValue
(
dateValue2
)
-
DateTimeUtils
.
yearFromDateValue
(
dateValue1
))
*
12
+
DateTimeUtils
.
monthFromDateValue
(
dateValue2
)
-
DateTimeUtils
.
monthFromDateValue
(
dateValue1
);
case
QUARTER:
return
(
DateTimeUtils
.
yearFromDateValue
(
dateValue2
)
-
DateTimeUtils
.
yearFromDateValue
(
dateValue1
))
*
4
+
(
DateTimeUtils
.
monthFromDateValue
(
dateValue2
)
-
1
)
/
3
-
(
DateTimeUtils
.
monthFromDateValue
(
dateValue1
)
-
1
)
/
3
;
case
YEAR:
return
DateTimeUtils
.
yearFromDateValue
(
dateValue2
)
-
DateTimeUtils
.
yearFromDateValue
(
dateValue1
);
default
:
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/util/DateTimeUtils.java
浏览文件 @
e0619d3a
...
...
@@ -24,7 +24,6 @@ import org.h2.value.ValueTime;
import
org.h2.value.ValueTimestamp
;
import
org.h2.value.ValueTimestampTimeZone
;
/**
* This utility class contains time conversion functions.
* <p>
...
...
@@ -590,6 +589,40 @@ public class DateTimeUtils {
return
new
long
[]
{
dateValue
,
timeNanos
};
}
/**
* Creates a new date-time value with the same type as original value. If
* original value is a ValueTimestampTimeZone, returned value will have the same
* time zone offset as original value.
*
* @param original
* original value
* @param dateValue
* date value for the returned value
* @param timeNanos
* nanos of day for the returned value
* @param forceTimestamp
* if {@code true} return ValueTimestamp if original argument is
* ValueDate or ValueTime
* @return new value with specified date value and nanos of day
*/
public
static
Value
dateTimeToValue
(
Value
original
,
long
dateValue
,
long
timeNanos
,
boolean
forceTimestamp
)
{
if
(!(
original
instanceof
ValueTimestamp
))
{
if
(!
forceTimestamp
)
{
if
(
original
instanceof
ValueDate
)
{
return
ValueDate
.
fromDateValue
(
dateValue
);
}
if
(
original
instanceof
ValueTime
)
{
return
ValueTime
.
fromNanos
(
timeNanos
);
}
}
if
(
original
instanceof
ValueTimestampTimeZone
)
{
return
ValueTimestampTimeZone
.
fromDateValueAndNanos
(
dateValue
,
timeNanos
,
((
ValueTimestampTimeZone
)
original
).
getTimeZoneOffsetMins
());
}
}
return
ValueTimestamp
.
fromDateValueAndNanos
(
dateValue
,
timeNanos
);
}
/**
* Get the year (positive or negative) from a calendar.
*
...
...
@@ -830,6 +863,26 @@ public class DateTimeUtils {
}
}
/**
* Returns number of days in month.
*
* @param year the year
* @param month the month
* @return number of days in the specified month
*/
public
static
int
getDaysInMonth
(
int
year
,
int
month
)
{
if
(
month
!=
2
)
{
return
NORMAL_DAYS_PER_MONTH
[
month
];
}
// All leap years divisible by 4
return
(
year
&
3
)
==
0
// All such years before 1582 are Julian and leap
&&
(
year
<
1582
// Otherwise check Gregorian conditions
||
year
%
100
!=
0
||
year
%
400
==
0
)
?
29
:
28
;
}
/**
* Verify if the specified date is valid.
*
...
...
@@ -842,24 +895,11 @@ public class DateTimeUtils {
if
(
month
<
1
||
month
>
12
||
day
<
1
)
{
return
false
;
}
if
(
year
>
1582
)
{
// Gregorian calendar
if
(
month
!=
2
)
{
return
day
<=
NORMAL_DAYS_PER_MONTH
[
month
];
}
// February
if
((
year
&
3
)
!=
0
)
{
return
day
<=
28
;
}
return
day
<=
((
year
%
100
!=
0
)
||
(
year
%
400
==
0
)
?
29
:
28
);
}
else
if
(
year
==
1582
&&
month
==
10
)
{
if
(
year
==
1582
&&
month
==
10
)
{
// special case: days 1582-10-05 .. 1582-10-14 don't exist
return
day
<=
31
&&
(
day
<
5
||
day
>
14
);
}
if
(
month
!=
2
&&
day
<=
NORMAL_DAYS_PER_MONTH
[
month
])
{
return
true
;
return
day
<
5
||
(
day
>
14
&&
day
<=
31
);
}
return
day
<=
((
year
&
3
)
!=
0
?
28
:
29
);
return
day
<=
getDaysInMonth
(
year
,
month
);
}
/**
...
...
@@ -985,6 +1025,38 @@ public class DateTimeUtils {
return
(
year
<<
SHIFT_YEAR
)
|
(
month
<<
SHIFT_MONTH
)
|
day
;
}
/**
* Get the date value from a given denormalized date with possible out of range
* values of month and/or day. Used after addition or subtraction month or years
* to (from) it to get a valid date.
*
* @param year
* the year
* @param month
* the month, if out of range month and year will be normalized
* @param day
* the day of the month, if out of range it will be saturated
* @return the date value
*/
public
static
long
dateValueFromDenormalizedDate
(
long
year
,
long
month
,
int
day
)
{
long
mm1
=
month
-
1
;
long
yd
=
mm1
/
12
;
if
(
mm1
<
0
&&
yd
*
12
!=
mm1
)
{
yd
--;
}
int
y
=
(
int
)
(
year
+
yd
);
int
m
=
(
int
)
(
month
-
yd
*
12
);
if
(
day
<
1
)
{
day
=
1
;
}
else
{
int
max
=
getDaysInMonth
(
y
,
m
);
if
(
day
>
max
)
{
day
=
max
;
}
}
return
dateValue
(
y
,
m
,
day
);
}
/**
* Convert a UTC datetime in millis to an encoded date in the default
* timezone.
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/timeanddate/dateadd.sql
浏览文件 @
e0619d3a
...
...
@@ -81,7 +81,7 @@ select d + t, t + d - t x from test;
select
1
+
d
+
1
,
d
-
1
,
2
+
ts
+
2
,
ts
-
2
from
test
;
>
DATEADD
(
'DAY'
,
1
,
DATEADD
(
'DAY'
,
1
,
D
))
DATEADD
(
'DAY'
,
-
1
,
D
)
DATEADD
(
'DAY'
,
2
,
DATEADD
(
'DAY'
,
2
,
TS
))
DATEADD
(
'DAY'
,
-
2
,
TS
)
>
--------------------------------------- --------------------- ---------------------------------------- ----------------------
>
2001
-
01
-
03
00
:
00
:
00
.
0
2000
-
12
-
31
00
:
00
:
00
.
0
2010
-
01
-
05
00
:
00
:
00
.
0
2009
-
12
-
30
00
:
00
:
00
.
0
>
2001
-
01
-
03
2000
-
12
-
31
2010
-
01
-
05
00
:
00
:
00
.
0
2009
-
12
-
30
00
:
00
:
00
.
0
>
rows
:
1
select
1
+
d
+
t
+
1
from
test
;
...
...
@@ -104,3 +104,36 @@ call dateadd('MS', 1, TIMESTAMP '2001-02-03 04:05:06.789001');
>
--------------------------------------
>
2001
-
02
-
03
04
:
05
:
06
.
790001
>
rows
:
1
SELECT
DATEADD
(
'HOUR'
,
1
,
DATE
'2010-01-20'
);
>
TIMESTAMP
'2010-01-20 01:00:00.0'
>
---------------------------------
>
2010
-
01
-
20
01
:
00
:
00
.
0
>
rows
:
1
SELECT
DATEADD
(
'MINUTE'
,
30
,
TIME
'12:30:55'
);
>
TIME
'13:00:55'
>
---------------
>
13
:
00
:
55
>
rows
:
1
SELECT
DATEADD
(
'DAY'
,
1
,
TIME
'12:30:55'
);
>
exception
SELECT
DATEADD
(
'QUARTER'
,
1
,
DATE
'2010-11-16'
);
>
DATE
'2011-02-16'
>
-----------------
>
2011
-
02
-
16
>
rows
:
1
SELECT
DATEADD
(
'DAY'
,
10
,
TIMESTAMP
WITH
TIME
ZONE
'2000-01-05 15:00:30.123456789-10'
);
>
TIMESTAMP
WITH
TIME
ZONE
'2000-01-15 15:00:30.123456789-10'
>
-----------------------------------------------------------
>
2000
-
01
-
15
15
:
00
:
30
.
123456789
-
10
>
rows
:
1
SELECT
TIMESTAMPADD
(
'DAY'
,
10
,
TIMESTAMP
'2000-01-05 15:00:30.123456789'
);
>
TIMESTAMP
'2000-01-15 15:00:30.123456789'
>
-----------------------------------------
>
2000
-
01
-
15
15
:
00
:
30
.
123456789
>
rows
:
1
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/functions/timeanddate/datediff.sql
浏览文件 @
e0619d3a
...
...
@@ -194,3 +194,34 @@ SELECT DATEDIFF('WEEK', DATE '1969-12-28', DATE '1969-12-29'), DATEDIFF('ISO_WEE
>
-
-
>
0
1
>
rows
:
1
SELECT
DATEDIFF
(
'QUARTER'
,
DATE
'2009-12-30'
,
DATE
'2009-12-31'
);
>
0
>
-
>
0
>
rows
:
1
SELECT
DATEDIFF
(
'QUARTER'
,
DATE
'2010-01-01'
,
DATE
'2009-12-31'
);
>
-
1
>
--
>
-
1
>
rows
:
1
SELECT
DATEDIFF
(
'QUARTER'
,
DATE
'2010-01-01'
,
DATE
'2010-01-02'
);
>
0
>
-
>
0
>
rows
:
1
SELECT
DATEDIFF
(
'QUARTER'
,
DATE
'2010-01-01'
,
DATE
'2010-03-31'
);
>
0
>
-
>
0
>
rows
:
1
SELECT
DATEDIFF
(
'QUARTER'
,
DATE
'-1000-01-01'
,
DATE
'2000-01-01'
);
>
12000
>
-----
>
12000
>
rows
:
1
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/scripts/testScript.sql
浏览文件 @
e0619d3a
...
...
@@ -7586,9 +7586,9 @@ SELECT * FROM TEST;
SELECT
XD
+
1
,
XD
-
1
,
XD
-
XD
FROM
TEST
;
>
DATEADD
(
'DAY'
,
1
,
XD
)
DATEADD
(
'DAY'
,
-
1
,
XD
)
DATEDIFF
(
'DAY'
,
XD
,
XD
)
>
--------------------- ---------------------- -----------------------
>
0001
-
02
-
04
00
:
00
:
00
.
0
0001
-
02
-
02
00
:
00
:
00
.
0
0
>
0004
-
05
-
07
00
:
00
:
00
.
0
0004
-
05
-
05
00
:
00
:
00
.
0
0
>
2000
-
01
-
01
00
:
00
:
00
.
0
1999
-
12
-
30
00
:
00
:
00
.
0
0
>
0001
-
02
-
04
0001
-
02
-
02
0
>
0004
-
05
-
07
0004
-
05
-
05
0
>
2000
-
01
-
01
1999
-
12
-
30
0
>
null
null
null
>
rows
:
4
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/unit/TestDateTimeUtils.java
浏览文件 @
e0619d3a
...
...
@@ -11,6 +11,8 @@ import java.util.GregorianCalendar;
import
org.h2.test.TestBase
;
import
org.h2.util.DateTimeUtils
;
import
static
org
.
h2
.
util
.
DateTimeUtils
.
dateValue
;
/**
* Unit tests for the DateTimeUtils class
*/
...
...
@@ -30,6 +32,7 @@ public class TestDateTimeUtils extends TestBase {
testParseTimeNanosDB2Format
();
testDayOfWeek
();
testWeekOfYear
();
testDateValueFromDenormalizedDate
();
}
private
void
testParseTimeNanosDB2Format
()
{
...
...
@@ -53,7 +56,7 @@ public class TestDateTimeUtils extends TestBase {
if
(
gc
.
get
(
Calendar
.
ERA
)
==
GregorianCalendar
.
BC
)
{
year
=
1
-
year
;
}
long
expectedDateValue
=
DateTimeUtils
.
dateValue
(
year
,
gc
.
get
(
Calendar
.
MONTH
)
+
1
,
long
expectedDateValue
=
dateValue
(
year
,
gc
.
get
(
Calendar
.
MONTH
)
+
1
,
gc
.
get
(
Calendar
.
DAY_OF_MONTH
));
long
dateValue
=
DateTimeUtils
.
dateValueFromAbsoluteDay
(
i
);
assertEquals
(
expectedDateValue
,
dateValue
);
...
...
@@ -92,4 +95,15 @@ public class TestDateTimeUtils extends TestBase {
}
}
/**
* Test for {@link DateTimeUtils#dateValueFromDenormalizedDate(long, long, int)}.
*/
private
void
testDateValueFromDenormalizedDate
()
{
assertEquals
(
dateValue
(
2017
,
1
,
1
),
DateTimeUtils
.
dateValueFromDenormalizedDate
(
2018
,
-
11
,
0
));
assertEquals
(
dateValue
(
2001
,
2
,
28
),
DateTimeUtils
.
dateValueFromDenormalizedDate
(
2000
,
14
,
29
));
assertEquals
(
dateValue
(
1999
,
8
,
1
),
DateTimeUtils
.
dateValueFromDenormalizedDate
(
2000
,
-
4
,
-
100
));
assertEquals
(
dateValue
(
2100
,
12
,
31
),
DateTimeUtils
.
dateValueFromDenormalizedDate
(
2100
,
12
,
2000
));
assertEquals
(
dateValue
(-
100
,
2
,
29
),
DateTimeUtils
.
dateValueFromDenormalizedDate
(-
100
,
2
,
30
));
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论