javascript + postgres:时区和时间戳的使用
javascript + postgres: timezone and timestamp usage
我不太了解时间戳的用法,
例如
用户创建文章可以选择PublishDate
,系统也会自动存储CreateDate
。
一个。我应该用时区制作 PublishDate
和 CreateDate
时间戳并设置 utc 吗?
b。用户 post 字符串然后我像下面那样转换使用 momentjs
到 utc 时间戳并存储,当有人 select 这一行时,将他们显示为用户客户端时间反向使用 momentjs
c。我用CURRENT_TIMESTAMP
到CreateDate
,CURRENT_TIMESTAMP
是服务器时间吗?我做得对吗?
我的想法是,我总是在数据库中插入utc时区时间戳,然后在user/client读取的地方,将数据转换为user/client时区?我做得对吗?
一个。我的数据库 (postgres) 由
创建
CREATE TABLE IF NOT EXISTS "Article"(
"ArticleId" SERIAL NOT NULL,
"PublishDate" timestamp with time zone,
"Active" bit NOT NULL,
"CreateByUserId" integer,
"CreateDate" timestamp with time zone,
PRIMARY KEY ("ArticleId")
);
SET timezone = 'UTC';
b。用户提交 post 存储 (nodejs)
// publishDate: '{"y":2015,"m":8,"d":16,"h":15,"mi":46,"s":24}
var publishDate = JSON.parse(req.body.publishDate);
var leadingZeroAndDateFormat = function(publishDate) {
return new Promise(function (fulfill, reject){
if (publishDate.m < 10) { publishDate.m = '0'+publishDate.m; }
if (publishDate.d < 10) { publishDate.d = '0'+publishDate.d; }
if (publishDate.h < 10) { publishDate.h = '0'+publishDate.h; }
if (publishDate.mi < 10) { publishDate.mi = '0'+publishDate.mi; }
if (publishDate.s < 10) { publishDate.s = '0'+publishDate.s; }
var str = publishDate.y+'-'+publishDate.m+'-'+publishDate.d+' '+publishDate.h+':'+publishDate.mi+':'+publishDate.s;
var utc = moment(str).unix();
fulfill(utc);
});
};
c。插入数据库 CreateDate
使用 CURRENT_TIMESTAMP
var insertArticle = function(publishDate, active, createByUserId) {
return new Promise(function (fulfill, reject){
var query = 'INSERT INTO "Article" ("PublishDate","Active","CreateByUserId","CreateDate") VALUES (,,,CURRENT_TIMESTAMP) RETURNING "ArticleId"';
dbClient.query(query,[publishDate,active,createByUserId], function(error, result) {
if (error) {
reject(error);
} else {
fulfill(result);
}
});
});
};
更新
当我更改所有没有时区的列时,我执行 insertArticle
显示错误
{ [error: date/time field value out of range: "1439717298"]
name: 'error',
length: 158,
severity: 'ERROR',
code: '22008',
detail: undefined,
hint: 'Perhaps you need a different "datestyle" setting.',
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'datetime.c',
line: '3775',
routine: 'DateTimeParseError' }
var insertArticle = function(publishDate, active, createByUserId) {
return new Promise(function (fulfill, reject){
var query = 'INSERT INTO "Article" ("PublishDate","Active","CreateByUserId","CreateDate") VALUES (,,,) RETURNING "ArticleId"';
dbClient.query(query,[publishDate,active,createByUserId,moment.utc().unix()], function(error, result) {
if (error) {
reject(error);
} else {
fulfill(result);
}
});
});
};
最简单的方法是始终以 UTC 格式存储不带时区的时间戳。这样,使用它们进行显示和计算总是很容易的。差就是减法,直接比较
如果该列是带有时区的时间戳,那么输入无论如何都会转换为 UTC,但输出会在当前设置的时区内,如果设置不正确,可能会显示错误的值。它还使数据库效率降低。
在表示层中,时间戳可以显示在适当的时区中,输入的值也可以转换为 UTC 进行存储。
这是最简单、最高效、最灵活的时间戳处理方式。
使用CURRENT_TIMESTAMP将在执行时从服务器获取时间戳。
不带时区的传入时间戳以本地时间而不是 UTC 进行解析——我将此称为 node-postgres 中的错误。无论如何,您可以通过添加以下代码来覆盖它以做正确的事情:
pg.types.setTypeParser(1114, function(stringValue) {
console.log(stringValue);
return new Date(Date.parse(stringValue + "+0000"));
})
我不太了解时间戳的用法,
例如
用户创建文章可以选择PublishDate
,系统也会自动存储CreateDate
。
一个。我应该用时区制作 PublishDate
和 CreateDate
时间戳并设置 utc 吗?
b。用户 post 字符串然后我像下面那样转换使用 momentjs
到 utc 时间戳并存储,当有人 select 这一行时,将他们显示为用户客户端时间反向使用 momentjs
c。我用CURRENT_TIMESTAMP
到CreateDate
,CURRENT_TIMESTAMP
是服务器时间吗?我做得对吗?
我的想法是,我总是在数据库中插入utc时区时间戳,然后在user/client读取的地方,将数据转换为user/client时区?我做得对吗?
一个。我的数据库 (postgres) 由
创建CREATE TABLE IF NOT EXISTS "Article"(
"ArticleId" SERIAL NOT NULL,
"PublishDate" timestamp with time zone,
"Active" bit NOT NULL,
"CreateByUserId" integer,
"CreateDate" timestamp with time zone,
PRIMARY KEY ("ArticleId")
);
SET timezone = 'UTC';
b。用户提交 post 存储 (nodejs)
// publishDate: '{"y":2015,"m":8,"d":16,"h":15,"mi":46,"s":24}
var publishDate = JSON.parse(req.body.publishDate);
var leadingZeroAndDateFormat = function(publishDate) {
return new Promise(function (fulfill, reject){
if (publishDate.m < 10) { publishDate.m = '0'+publishDate.m; }
if (publishDate.d < 10) { publishDate.d = '0'+publishDate.d; }
if (publishDate.h < 10) { publishDate.h = '0'+publishDate.h; }
if (publishDate.mi < 10) { publishDate.mi = '0'+publishDate.mi; }
if (publishDate.s < 10) { publishDate.s = '0'+publishDate.s; }
var str = publishDate.y+'-'+publishDate.m+'-'+publishDate.d+' '+publishDate.h+':'+publishDate.mi+':'+publishDate.s;
var utc = moment(str).unix();
fulfill(utc);
});
};
c。插入数据库 CreateDate
使用 CURRENT_TIMESTAMP
var insertArticle = function(publishDate, active, createByUserId) {
return new Promise(function (fulfill, reject){
var query = 'INSERT INTO "Article" ("PublishDate","Active","CreateByUserId","CreateDate") VALUES (,,,CURRENT_TIMESTAMP) RETURNING "ArticleId"';
dbClient.query(query,[publishDate,active,createByUserId], function(error, result) {
if (error) {
reject(error);
} else {
fulfill(result);
}
});
});
};
更新
当我更改所有没有时区的列时,我执行 insertArticle
显示错误
{ [error: date/time field value out of range: "1439717298"]
name: 'error',
length: 158,
severity: 'ERROR',
code: '22008',
detail: undefined,
hint: 'Perhaps you need a different "datestyle" setting.',
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'datetime.c',
line: '3775',
routine: 'DateTimeParseError' }
var insertArticle = function(publishDate, active, createByUserId) {
return new Promise(function (fulfill, reject){
var query = 'INSERT INTO "Article" ("PublishDate","Active","CreateByUserId","CreateDate") VALUES (,,,) RETURNING "ArticleId"';
dbClient.query(query,[publishDate,active,createByUserId,moment.utc().unix()], function(error, result) {
if (error) {
reject(error);
} else {
fulfill(result);
}
});
});
};
最简单的方法是始终以 UTC 格式存储不带时区的时间戳。这样,使用它们进行显示和计算总是很容易的。差就是减法,直接比较
如果该列是带有时区的时间戳,那么输入无论如何都会转换为 UTC,但输出会在当前设置的时区内,如果设置不正确,可能会显示错误的值。它还使数据库效率降低。
在表示层中,时间戳可以显示在适当的时区中,输入的值也可以转换为 UTC 进行存储。
这是最简单、最高效、最灵活的时间戳处理方式。
使用CURRENT_TIMESTAMP将在执行时从服务器获取时间戳。
不带时区的传入时间戳以本地时间而不是 UTC 进行解析——我将此称为 node-postgres 中的错误。无论如何,您可以通过添加以下代码来覆盖它以做正确的事情:
pg.types.setTypeParser(1114, function(stringValue) {
console.log(stringValue);
return new Date(Date.parse(stringValue + "+0000"));
})