summaryrefslogtreecommitdiffstats
path: root/test/date3.test
blob: 1798a3478a6243de66ad57dfefa971c7411d0b31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# 2022-01-27
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing date and time functions.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Skip this whole file if date and time functions are omitted
# at compile-time
#
ifcapable {!datetime} {
  finish_test
  return
}

proc datetest {tnum expr result} {
  do_test date3-$tnum [subst {
    execsql "SELECT coalesce($expr,'NULL')"
  }] [list $result]
}
set tcl_precision 15

# EVIDENCE-OF: R-45708-63005 unixepoch(time-value, modifier, modifier,
# ...)
#
datetest 1.1 {unixepoch('1970-01-01')} {0}
datetest 1.2 {unixepoch('1969-12-31 23:59:59')} {-1}
datetest 1.3 {unixepoch('2106-02-07 06:28:15')} {4294967295}
datetest 1.4 {unixepoch('2106-02-07 06:28:16')} {4294967296}
datetest 1.5 {unixepoch('9999-12-31 23:59:59')} {253402300799}
datetest 1.6 {unixepoch('0000-01-01 00:00:00')} {-62167219200}

# EVIDENCE-OF: R-30877-63179 The unixepoch() function returns a unix
# timestamp - the number of seconds since 1970-01-01 00:00:00 UTC.
#
for {set i 1} {$i<=100} {incr i} {
  set x [expr {int(rand()*0xfffffffff)-0xffffffff}]
  datetest 1.7.$i "unixepoch($x,'unixepoch')==$x" {1}
}

# EVIDENCE-OF: R-62992-54137 The unixepoch() always returns an integer,
# even if the input time-value has millisecond precision.
#
datetest 1.8 {unixepoch('2022-01-27 12:59:28.052')} {1643288368}

# EVIDENCE-OF: R-05412-24332 If the time-value is numeric (the
# DDDDDDDDDD format) then the 'auto' modifier causes the time-value to
# interpreted as either a julian day number or a unix timestamp,
# depending on its magnitude.
#
# EVIDENCE-OF: R-56763-40111 If the value is between 0.0 and
# 5373484.499999, then it is interpreted as a julian day number
# (corresponding to dates between -4713-11-24 12:00:00 and 9999-12-31
# 23:59:59, inclusive).
#
# EVIDENCE-OF: R-07289-49223 For numeric values outside of the range of
# valid julian day numbers, but within the range of -210866760000 to
# 253402300799, the 'auto' modifier causes the value to be interpreted
# as a unix timestamp.
#
# EVIDENCE-OF: R-20795-34947 Other numeric values are out of range and
# cause a NULL return.
#
foreach {tn jd date} {
  2.1  0.0              {-4713-11-24 12:00:00}
  2.2  5373484.4999999  {9999-12-31 23:59:59}
  2.3  2440587.5        {1970-01-01 00:00:00}
  2.4  2440587.49998843 {1969-12-31 23:59:59}
  2.5  2440615.7475463  {1970-01-29 05:56:28}

  2.10 -1               {1969-12-31 23:59:59}
  2.11 5373485          {1970-03-04 04:38:05}
  2.12 -210866760000    {-4713-11-24 12:00:00}
  2.13 253402300799     {9999-12-31 23:59:59}

  2.20 -210866760001    {NULL}
  2.21 253402300800     {NULL}
} {
  datetest $tn "datetime($jd,'auto')" $date
}

# EVIDENCE-OF: R-38886-35357 The 'auto' modifier is a no-op for text
# time-values.
#
datetest 2.30 {date('2022-01-29','auto')==date('2022-01-29')} {1}

# EVIDENCE-OF: R-53132-26856 The 'auto' modifier can be used to work
# with date/time values even in cases where it is not known if the
# julian day number or unix timestamp formats are in use.
#
do_execsql_test date3-2.40 {
  WITH tx(timeval,datetime) AS (
     VALUES('2022-01-27 13:15:44','2022-01-27 13:15:44'),
           (2459607.05260275,'2022-01-27 13:15:44'),
           (1643289344,'2022-01-27 13:15:44')
  )
  SELECT datetime(timeval,'auto') == datetime FROM tx;
} {1 1 1}

# EVIDENCE-OF: R-49255-55373 The "unixepoch" modifier (11) only works if
# it immediately follows a time value in the DDDDDDDDDD format.
#
# EVIDENCE-OF: R-23075-39245 This modifier causes the DDDDDDDDDD to be
# interpreted not as a Julian day number as it normally would be, but as
# Unix Time - the number of seconds since 1970.
#
datetest 3.1 {datetime(2459607.05,'+1 hour','unixepoch')} {NULL}
datetest 3.2 {datetime(2459607.05,'unixepoch','+1 hour')} {1970-01-29 12:13:27}

# EVIDENCE-OF: R-21150-52363 The "julianday" modifier must immediately
# follow the initial time-value which must be of the form DDDDDDDDD.
#
# EVIDENCE-OF: R-31176-64601 Any other use of the 'julianday' modifier
# is an error and causes the function to return NULL.
#
# EVIDENCE-OF: R-32483-36353 The 'julianday' modifier forces the
# time-value number to be interpreted as a julian-day number.
#
# EVIDENCE-OF: R-25859-20124 The only difference is that adding
# 'julianday' forces the DDDDDDDDD time-value format, and causes a NULL
# to be returned if any other time-value format is used.
#
datetest 4.1 {datetime(2459607,'julianday')}           {2022-01-27 12:00:00}
datetest 4.2 {datetime(2459607,'+1 hour','julianday')} {NULL}
datetest 4.3 {datetime('2022-01-27','julianday')}      {NULL}



# EVIDENCE-OF: R-33431-18865 Unix timestamps for the first 63 days of
# 1970 will be interpreted as julian day numbers.
#
do_execsql_test date3-5.0 {
  WITH inc(x) AS (VALUES(-10) UNION ALL SELECT x+1 FROM inc WHERE x<100)
  SELECT count(*) FROM inc
  WHERE datetime('1970-01-01',format('%+d days',x))
     <> datetime(unixepoch('1970-01-01',format('%+d days',x)),'auto');
} {63}

finish_test