Below is the code to reproduce.
Basically any PostgreSQL table that has a timestamptz
or timestamp with time zone
field/column will cause the error as that DateTime is converted due to time zone.
created new select
Expected: 2020-01-25 04:51:04.318
But was: 2020-01-24 22:51:04.318
Note: There isn’t a ServiceStack.DataAnnotations
attribute for timestamptz
so custom sql was required to reproduce the result.
drop table if exists timestamp_model;
create table timestamp_model
(
id bigserial not null constraint timestamp_model_pkey primary key,
created timestamptz not null,
modified timestamptz not null
);
Note 2: There was a [PgSqlTimestampTz]
attribute that is now obsolete
due to being incorrectly used for the array [PgSqlTimestampTzArray]
(if I remember correctly).
Below is the NUnit Test to reproduce the issue
using System;
using NUnit.Framework;
using ServiceStack.DataAnnotations;
using ServiceStack.OrmLite.Tests;
using ServiceStack.Text;
namespace ServiceStack.OrmLite.PostgreSQL.Tests.Issues
{
public class TimestampModel
{
[AutoIncrement]
[PrimaryKey]
[ReturnOnInsert]
public long Id { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
}
[TestFixtureOrmLiteDialects(Dialect.AnyPostgreSql)]
public class TimestampOnSelectAndReSaveTests : OrmLiteProvidersTestBase
{
private const int MillisecondsTimeout = 2000;
public TimestampOnSelectAndReSaveTests(DialectContext context) : base(context) { }
private const string DropCreateTableSql = @"drop table if exists timestamp_model;
create table timestamp_model
(
id bigserial not null
constraint timestamp_model_pkey
primary key,
created timestamptz not null,
modified timestamptz not null
);";
[Test]
public void test_model_with_save_custom_sql()
{
using (var db = OpenDbConnection())
{
// db.DropAndCreateTable<TimestampModel>();
db.ExecuteNonQuery(DropCreateTableSql);
var created = SystemTime.UtcNow.RoundToMs();
var record = new TimestampModel()
{
Created = created,
Modified = created
};
db.Save(record);
var id = record.Id;
Assert.That(record, Is.Not.Null);
Assert.That(record, Is.Not.EqualTo(0));
Assert.That(record, Is.Not.Null);
Assert.That(record.Id, Is.EqualTo(id));
Assert.That(record.Created, Is.EqualTo(created), "created new");
Assert.That(record.Modified, Is.EqualTo(created), "modified new");
record = db.SingleById<TimestampModel>(id);
Assert.That(record, Is.Not.Null);
Assert.That(record.Id, Is.EqualTo(id));
Assert.That(record.Created, Is.EqualTo(created), "created new select");
Assert.That(record.Modified, Is.EqualTo(created), "modified new select");
//System.Threading.Thread.Sleep(MillisecondsTimeout);
var modified = SystemTime.UtcNow.RoundToMs();
record.Modified = modified;
db.Save(record);
record = db.SingleById<TimestampModel>(id);
Assert.That(record, Is.Not.Null);
Assert.That(record.Id, Is.EqualTo(id));
Assert.That(record.Created, Is.EqualTo(created), "created update");
Assert.That(record.Modified, Is.EqualTo(modified), "modified update");
db.Save(record);
//System.Threading.Thread.Sleep(MillisecondsTimeout);
record = db.SingleById<TimestampModel>(id);
Assert.That(record, Is.Not.Null);
Assert.That(record.Id, Is.EqualTo(id));
Assert.That(record.Created, Is.EqualTo(created), "created update 2");
Assert.That(record.Modified, Is.EqualTo(modified), "modified update 2");
}
}
}
}