Save Date.now() to timestamp column but get date/time field value out of range - postgresql

My project (NestJS with TypeScript) is using TypeOrm on PostgreSQL database.
My table has a column (in migration file):
new TableColumn({
name: 'managed_at',
type: 'timestamp',
isNullable: true,
}),
Associated field in entity class:
#Column({ type: 'timestamp', nullable: true })
managedAt: Date | null;
I would like the column managed_at holds value of date and time.
If I save a data to the table with:
import { Repository } from 'typeorm';
...
// repo is the Repository of typeorm
repo.update(
{ managedAt: Date.now() }
);
I get error:
QueryFailedError: date/time field value out of range: "1651495656811"
How to solve this problem that using Date.now() and hold value of data and time?

import { Repository } from 'typeorm';
...
// repo is the Repository of typeorm
repo.update(
{ managedAt: new Date() }
);
Change Date.now() -> new Date().
You need to save Date type data to column in timestamp type.
Btw, you can add this in your entity class.
It will update column before update data.
#BeforeUpdate()
updateManagedAt(): void {
this.managedAt = new Date();
}

The static Date.now() method returns the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC, as per documentation here Date.now().
Whereas valid input for the time stamp types consists of the concatenation of a date and a time, followed by an optional time zone (if you are using timestamptz type instead of timestamp type), followed by an optional AD or BC. (Alternatively, AD/BC can appear before the time zone, but this is not the preferred ordering.
You can read more about Date/Time types in pgSQL here.
In your case, you can do it like this
repo.update({ managedAt: (new Date()).toISOString() });
You'd use toISOString for sharing a date with another machine or process.

Related

How to add a date to a prisma typescript form?

I am trying to figure out how to post a date to a prisma database.
I have a prisma.schema which has a createdAt field as follows:
createdAt DateTime #default(now()) #db.Timestamptz(6)
I made a model with a date field in it as follows:
#Field()
createdAt: Date;
And a create.input.ts with a similar field:
#IsNotEmpty()
#Field()
createdAt: Date;
then, in the form, I'm trying to add the createdAt date as the date the form is submitted, as follows:
return form.handler(() => createIssueGroup({ variables: { data: { ...data, createdAt: Date.now() } } })),
However, I get an error that says type number is not assignable to type string. I don't think I'm using a string in any of the date fields.
How can I post a date to prisma?
From your schema definition,
createdAt DateTime #default(now()) #db.Timestamptz(6)
The date will be automatically generated due to the now() method you specified in #default(). You don't need to pass a date to the database as that will be handled for you by Prisma. See the docs for more information on using now() and defining a default value.

Persisting time with timezone offset in mongodb with nestjs

I have a nestjs application which has a very date heavy schema.
According to my understanding date is stored in mongo without timezone. My API accepts time in ISO format with timezone offset.
Inserting following object {"date": "2009-06-30T18:30:00+11:00"}
will result in following document in the mongo database {date: ISODate('2009-06-30T07:30:00.000Z'), _id: "..."}
So the timezone offset is lost.
Is there an elegant way to keep the timezone offset and deliver the ISO string with the same offset on an GET request? Maybe make use of the class-transformer and store the offset in a separate property? If yes, how?
Here are the involved classes. (There is a dedicated ItemDto for GET requests which is not shown here.)
Dto:
export class CreateItemDto {
// Some other props are here
/**
* Date of this Information.
* #example "1900-01-01T05:00:00.000+05:00"
*/
#IsNotEmpty()
#IsDate()
#Type(() => Date)
date: Date;
}
Schema:
export class ItemSchema {
// Some other props are here
#Prop({ type: Date, required: true })
date!: Date;
}
In many cases the client application will convert and display the time in current local time zone, no matter in which time zone the timestamp was inserted.
If this is not sufficient for you then you have to store the time zone information in a separate field along with the actual timestamp.

Add timestamp fields to ogr2ogr import into Postgis

I managed to create a model/schema and insert geo-Points into Postgis using sequelize. Since I have a lot of points (>100K) I am longing back to the old way I used to import, using ogr2ogr (gdal), which was much faster (almost instant instead of >20 minutes). As I would like to continue to work with sequelize after the initial import I still want sequelize to create the model/schema upfront, but then do import with ogr2ogr, and then continue CRUD with sequelize.
Here I found this fragment “[….] One way to get around this is to create your table structures before hand and use OGR2OGR to just load the data.” Which gave me the idea that this could work for Postgres/Postgis as well.
Sequelize creates timestamp columns for createdAt and updatedAt, which I like. But when I use ogr2ogr I get “null value in column "createdAt" violates not-null constraint” as loginfo.
Based on this slightly similar issue I tried to add a createdAt column by adding an -sql option:
ogr2ogr -f PostgreSQL PG:"host='0.0.0.0' user='root' port='5432' dbname='db' password='pw'" /home/user/geojsonImportfile.json -nln "DataPoints" -a_srs EPSG:4326 -sql "SELECT url, customfield, wkb_geometry, CURRENT_TIMESTAMP as createdAt FROM '/home/usr/geojsonImportfile.json'" -dialect 'PostgreSQL'
The error I get when running this is:
ERROR 1: SQL Expression Parsing Error: syntax error, unexpected end of string, expecting '.'. Occurred around :
home/user/geojsonImportfile0.json'
Besides my lack of SQL knowledge I am not sure if this can work at all.
How can I solve this, i.e. make the import with ogr2ogr but keep the timestamp columns?
When you create a table with sequelize.define, createdAt and updatedAt columns are created automatically as timestamp with time zone NOT NULL.
But you can rule not-null constraint in your sequelize definition script:
const Mytable = sequelize.define('mytable', {
id: {type: Sequelize.INTEGER, primaryKey: true},
createdAt: {type: Sequelize.DATE, validate: {notNull:false}}
});
Then table is created like :
CREATE TABLE mytables
(
id integer NOT NULL,
"createdAt" timestamp with time zone,
"updatedAt" timestamp with time zone NOT NULL,
CONSTRAINT mytables_pkey PRIMARY KEY (id)
)
http://docs.sequelizejs.com/manual/tutorial/models-definition.html#configuration
#JGH following your suggestion it makes sense to have a default timestamp. I can already set this up using sequelize, as discussed here:
var user = sequelize.define('user', {
createdAt: {
type: DataTypes.DATE,
field: 'beginTime',
defaultValue: sequelize.literal('NOW()')
}
}, {
timestamps: true,
});

Apollo/GraphQL: Field Type to Use for Timestamp?

I'm storing a value to a postgres field that is of type timestamp with time zone. I was defining the field as an int in my Apollo schema, but I'm getting this error message in the resolver:
column "apptDateTime" is of type timestamp with time zone but expression is of type integer
Looking up GraphQL data types, I don't yet see any type that is cited as corresponding to a field of type timestamp.
What's the correct field type to use in the Apollo schema for a field that is of type timestamp in the database?
I find this way to work with input in forms, needed convert from client (input form) to the server, and from the server to client (input form)
Graphql:
updatedAt: String
Sequelize:
updatedAt: { type: Sequelize.DATE },
Postgresql:
"createdAt" timestamp(6) with time zone DEFAULT now(),
Value transform to the Server:
value = dateToISO(value);
Value transform to the Client:
if ( isNil(value) ) {
value = '';
} else {
value = value.toLocaleDateString() +' '+ value.toLocaleTimeString();
}
the helpers:
let dateToISO = function (dateString) {
if (!dateString) {
return null;
}
let p = dateString.split(/\D/g);
/* It's up your date on input in this case come from DD-MM-YYYY
for MM-DD-YYY use: return [p[1], p[2], p[0]].join('-'); */
return [p[2], p[1], p[0]].join('-');
};
I got my mutation working that includes a field of type Timestamp with Time Zone. I did it by changing the schema for my apptDateTime field from Int to String, and passing in an ISO string. Sequelize and Postgres took care of changing it into a field of type Timestamp with Time Zone.
Update 2021:
Here's what I'm using these days.
Sequelize:
timeOfNonce: {type: Sequelize.DATE}
Schema:
scalar DATETIME
.....
timeOfNonce: DATETIME
These days I let Sequelize define my SQL tables via:
const deleteAllData_fromThisModel = false;
const alterThisTableToMatchDBConnectorsModel = true;
myDataModel.sync({force: deleteAllData_fromThisModel,
alter: alterThisTableToMatchDBConnectorsModel}).then(err => {
console.log('myDataModel has been synced')
}).catch(err => {
throw err
});

Change date storage format in MongoDB

In an input json file i receive dates in this format:
{ "dt_received" : "2016-01-22T12:35:52.123+05" }
When loaded into MongoDB, those dates are stored this way:
dt_received: "2016-01-22T07:35:52.123Z"
The issue is that i need the timezone to calculate my indicator.
In constraint, i can't create new columns such as "dt_received_timezone".
So i'm looking for changing the date storage format into MongoDB in order to make the timezone appear (or at least not disapear)
Is it a way to to this? Or any solution ?
If you receive data from various time zones and want to keep the time zone offset, you will have to save it into the database like this:
var now = new Date();
db.data.save( { date: now, offset: now.getTimezoneOffset() } );
You can then reconstruct the original time like this
var record = db.data.findOne();
var localNow = new Date( record.date.getTime() - ( record.offset * 60000 ) );
See the documentation for further details