Problem with date before the start of Gregorian Calendar
Hi,
I have a problem when inserting date before the start of the gregorian calendar (10-15-1582)
If i insert a date in OrientDb before 10-15-1582, the date returned on select does not match to the inserted.
If i insert a date in OrientDb after 10-15-1582, the date returned on select match to the inserted.
I have created a unit test if you want to see :
describe("Bug 330: Select date before gregorian calendar", function () {
this.timeout(10 * 10000);
var LIMIT = 5000;
before(function () {
return CREATE_TEST_DB(this, 'testdb_bug_330')
.bind(this)
.then(function () {
return this.db.class.create('User', 'V');
})
.then(function (item) {
this.class = item;
return item.property.create([
{
name: 'firstname',
type: 'String'
},
{
name: 'birthDate',
type: 'datetime'
}
])
})
.then(function () {
return this.db.query('CREATE VERTEX User SET firstname = :firstname, birthDate = :birthDate',
{
params: {
firstname: 'Robert',
birthDate: new Date("1200-11-11T00:00:00.000Z")
}
}
);
})
.then(function () {
return this.db.query('CREATE VERTEX User SET firstname = :firstname, birthDate = :birthDate',
{
params: {
firstname: 'Marcel',
birthDate: new Date("1582-10-15T00:00:00.000Z") // Start Gregorian calendar
}
}
);
})
.then(function () {
return this.db.query('CREATE VERTEX User SET firstname = :firstname, birthDate = :birthDate',
{
params: {
firstname: 'Andrew',
birthDate: new Date("1987-03-03T00:00:00.000Z")
}
}
);
})
});
after(function () {
return DELETE_TEST_DB('testdb_bug_330');
});
it('should get the previously inserted date', function () {
return this.db.query('SELECT FROM User WHERE firstname = :firstname',
{
params: {
firstname: 'Robert'
}
}
).then(function (result) {
var expectedDate = new Date("1200-11-11T00:00:00.000Z");
result[0].birthDate.should.be.eql(expectedDate);
})
});
it('should get the previously inserted date', function () {
return this.db.query('SELECT FROM User WHERE firstname = :firstname',
{
params: {
firstname: 'Marcel'
}
}
).then(function (result) {
var expectedDate = new Date("1582-10-15T00:00:00.000Z");
result[0].birthDate.should.be.eql(expectedDate);
})
});
it('should get the previously inserted date', function () {
return this.db.query('SELECT FROM User WHERE firstname = :firstname',
{
params: {
firstname: 'Andrew'
}
}
).then(function (result) {
var expectedDate = new Date("1987-03-03T00:00:00.000Z");
result[0].birthDate.should.be.eql(expectedDate);
})
});
});
If someone else have the same problem, below a temporary fix :
If you need to get date, get the date as string :
SELECT birthDate.format("yyyy-MM-dd HH:mm:ss:SSS Z", "UTC") as birthDate FROM User
And in javascript, reconstruct the date field :
var resultDate = new Date(result[0].birthDate);
Created your test case in Java and passes.
The LONG value of 1200-11-11T00:00:00.000Z in javascript is -24271660800000.
When i select this field with orientjs, the raw result equals -24271056000000
-24271660800000 = Sat, 11 Nov 1200 00:00:00 GMT
-24271056000000 = Sat, 18 Nov 1200 00:00:00 GMT
You should test the LONG value returned to the binary protocol.
@Ndrou
the problem is
JavaScript
var expectedDate = new Date("1200-11-11T00:00:00.000Z");
console.log(expectedDate.getTime());
-24271660800000
Java
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date d = format.parse("1200-11-11 00:00:00.000");
System.out.println(d.getTime());
-24271059600000
In the meantime, we have fixed the problem by storing dates as LONG.