Skip to content

针对pgsql不支持 DateTimeOffset 引发的时间时区错乱问题 #2191

@jackletter

Description

@jackletter

经试验,freesql针对pgsql不支持 DateTimeOffset 的映射:

Image

那么,对于pgsql的 timestamptz 列类型将只能用 DateTime 操作,但如果pgsql和c#所处的时区不一致的话,就会导致时间错误,看下面的代码:

//故意让 pgsql 和 c# 时区不一致 (注意: -09:00 在 pgsql 中表示东九区)
var orm = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.PostgreSQL, "Server=localhost;Port=5432;UserId=postgres;Password=123456;Database=postgres;Timezone=-09:00")
    .UseNoneCommandParameter(true)
    .Build();

//准备原始
orm.Ado.ExecuteArray("drop table if exists \"Person\"");
orm.Ado.ExecuteArray("create table \"Person\"(\"CreateTime\" timestamptz)");
orm.Ado.ExecuteArray("insert into \"Person\"(\"CreateTime\") values ('2022-02-11 09:30:00+08:00')");

//第一次从db中读取
var person = orm.Ado.QuerySingle<Person>("select \"CreateTime\" from \"Person\"");
//打印: True 读取的没问题
Console.WriteLine(person.CreateTime == new DateTime(2022, 2, 11, 9, 30, 0, DateTimeKind.Local));

//清理db数据
orm.Ado.ExecuteArray("delete from \"Person\"");

//将数据原封不动写到db
//sql: INSERT INTO "Person"("CreateTime") VALUES('2022-02-11 09:30:00.000000')
var sql = orm.Insert<Person>()
    .InsertColumns(i => new { i.CreateTime,i.CreateTimeOffset })
    .AppendData(new Person { CreateTime = person.CreateTime })
    .ToSql();
orm.Ado.ExecuteArray(sql);

//第二次从db中读取
var person2 = orm.Ado.QuerySingle<Person>("select \"CreateTime\" from \"Person\"");
//打印: True
Console.WriteLine(person2.CreateTime == new DateTime(2022, 2, 11, 8, 30, 0, DateTimeKind.Local));

//两次结果比对: 不一致, 时间乱掉了
//打印: False
Console.WriteLine(person.CreateTime == person2.CreateTime);

这种问题的原因:在于 freesql 将 DateTime 转成 sql 的时候没有输出时区信息(事实上不输出从设计上也没什么问题),但c#个pgsql一旦时区不一致就完蛋了

解决这个问题的方法,最好是支持 DateTimeOffset,这样就可以用 DateTimeOffset 映射 timestamptz了

mysql 也有相同的问题

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions