extensions/time: normalize offset_sec

This commit is contained in:
meteorgan 2025-02-19 21:22:34 +08:00
parent 8ac09b73bf
commit 97337614db
3 changed files with 55 additions and 54 deletions

View file

@ -646,50 +646,50 @@ The `vector` extension is compatible with libSQL native vector search.
The `time` extension is compatible with [sqlean-time](https://github.com/nalgeon/sqlean/blob/main/docs/time.md).
| Function | Status | Comment |
| ------------------------------------------------------------------- | ------ | ---------------------------- |
| time_now() | Yes | |
| time_date(year, month, day[, hour, min, sec[, nsec[, offset_sec]]]) | Yes | offset_sec is not normalized |
| time_get_year(t) | Yes | |
| time_get_month(t) | Yes | |
| time_get_day(t) | Yes | |
| time_get_hour(t) | Yes | |
| time_get_minute(t) | Yes | |
| time_get_second(t) | Yes | |
| time_get_nano(t) | Yes | |
| time_get_weekday(t) | Yes | |
| time_get_yearday(t) | Yes | |
| time_get_isoyear(t) | Yes | |
| time_get_isoweek(t) | Yes | |
| time_get(t, field) | Yes | |
| time_unix(sec[, nsec]) | Yes | |
| time_milli(msec) | Yes | |
| time_micro(usec) | Yes | |
| time_nano(nsec) | Yes | |
| time_to_unix(t) | Yes | |
| time_to_milli(t) | Yes | |
| time_to_micro(t) | Yes | |
| time_to_nano(t) | Yes | |
| time_after(t, u) | Yes | |
| time_before(t, u) | Yes | |
| time_compare(t, u) | Yes | |
| time_equal(t, u) | Yes | |
| time_add(t, d) | Yes | |
| time_add_date(t, years[, months[, days]]) | Yes | |
| time_sub(t, u) | Yes | |
| time_since(t) | Yes | |
| time_until(t) | Yes | |
| time_trunc(t, field) | Yes | |
| time_trunc(t, d) | Yes | |
| time_round(t, d) | Yes | |
| time_fmt_iso(t[, offset_sec]) | Yes | |
| time_fmt_datetime(t[, offset_sec]) | Yes | |
| time_fmt_date(t[, offset_sec]) | Yes | |
| time_fmt_time(t[, offset_sec]) | Yes | |
| time_parse(s) | Yes | |
| dur_ns() | Yes | |
| dur_us() | Yes | |
| dur_ms() | Yes | |
| dur_s() | Yes | |
| dur_m() | Yes | |
| dur_h() | Yes | |
| Function | Status | Comment |
| ------------------------------------------------------------------- | ------ |---------|
| time_now() | Yes | |
| time_date(year, month, day[, hour, min, sec[, nsec[, offset_sec]]]) | Yes | |
| time_get_year(t) | Yes | |
| time_get_month(t) | Yes | |
| time_get_day(t) | Yes | |
| time_get_hour(t) | Yes | |
| time_get_minute(t) | Yes | |
| time_get_second(t) | Yes | |
| time_get_nano(t) | Yes | |
| time_get_weekday(t) | Yes | |
| time_get_yearday(t) | Yes | |
| time_get_isoyear(t) | Yes | |
| time_get_isoweek(t) | Yes | |
| time_get(t, field) | Yes | |
| time_unix(sec[, nsec]) | Yes | |
| time_milli(msec) | Yes | |
| time_micro(usec) | Yes | |
| time_nano(nsec) | Yes | |
| time_to_unix(t) | Yes | |
| time_to_milli(t) | Yes | |
| time_to_micro(t) | Yes | |
| time_to_nano(t) | Yes | |
| time_after(t, u) | Yes | |
| time_before(t, u) | Yes | |
| time_compare(t, u) | Yes | |
| time_equal(t, u) | Yes | |
| time_add(t, d) | Yes | |
| time_add_date(t, years[, months[, days]]) | Yes | |
| time_sub(t, u) | Yes | |
| time_since(t) | Yes | |
| time_until(t) | Yes | |
| time_trunc(t, field) | Yes | |
| time_trunc(t, d) | Yes | |
| time_round(t, d) | Yes | |
| time_fmt_iso(t[, offset_sec]) | Yes | |
| time_fmt_datetime(t[, offset_sec]) | Yes | |
| time_fmt_date(t[, offset_sec]) | Yes | |
| time_fmt_time(t[, offset_sec]) | Yes | |
| time_parse(s) | Yes | |
| dur_ns() | Yes | |
| dur_us() | Yes | |
| dur_ms() | Yes | |
| dur_s() | Yes | |
| dur_m() | Yes | |
| dur_h() | Yes | |

View file

@ -171,7 +171,6 @@ fn time_date_internal(args: &[Value]) -> Value {
let mut minutes = 0;
let mut seconds = 0;
let mut nano_secs = 0;
let mut offset = FixedOffset::east_opt(0).unwrap();
if args.len() >= 6 {
hour = ok_tri!(args[3].to_integer());
@ -185,9 +184,7 @@ fn time_date_internal(args: &[Value]) -> Value {
if args.len() == 8 {
let offset_sec = ok_tri!(args[7].to_integer()) as i32;
// TODO offset is not normalized. Maybe could just increase/decrease the number of seconds
// instead of relying in this offset
offset = ok_tri!(FixedOffset::east_opt(offset_sec));
seconds -= offset_sec as i64;
}
let t = Time::time_date(
@ -198,7 +195,7 @@ fn time_date_internal(args: &[Value]) -> Value {
minutes,
seconds,
nano_secs,
offset,
FixedOffset::east_opt(0).unwrap(),
);
let t = tri!(t);

View file

@ -9,12 +9,16 @@ do_execsql_test time_date {
SELECT time_fmt_iso(time_date(2011, 11, 18, 15, 56, 35, 666777888));
SELECT time_fmt_iso(time_date(2011, 11, 18, 15, 56, 35, 0, 3*3600));
SELECT time_fmt_iso(time_date(2011, 11, 18, 15, 56, 35, 666777888, 3*3600));
SELECT time_fmt_iso(time_date(2011, 11, 18, 15, 56, 35, 666777888, 25*3600));
SELECT time_fmt_iso(time_date(2011, 11, 18, 15, 56, 35, 666777888, -25*3600));
} {
{2011-11-18T00:00:00Z}
{2011-11-18T00:00:00Z}
{2011-11-18T15:56:35Z}
{2011-11-18T15:56:35.666777888Z}
{2011-11-18T15:56:35.666777888Z}
{2011-11-18T12:56:35Z}
{2011-11-18T12:56:35.666777888Z}
{2011-11-17T14:56:35.666777888Z}
{2011-11-19T16:56:35.666777888Z}
}
do_execsql_test time_get_year {