繁体   English   中英

javascript + postgres:时区和时间戳用法

[英]javascript + postgres: timezone and timestamp usage

我不太了解时间戳的使用情况,
例如
用户创建文章并可以选择PublishDate ,系统也会自动存储CreateDate

一种。 我应该使用时区制作PublishDateCreateDate时间戳并设置utc吗?

用户发布字符串然后我转换如下使用momentjs到utc时间戳和存储,当有人选择此行时,将它们显示为用户客户端时间反向使用momentjs

C。 我将CURRENT_TIMESTAMP用于CreateDateCURRENT_TIMESTAMP是否意味着服务器时间? 我做得对吗?

我的想法是我总是将utc时区时间戳插入数据库,无论用户/客户端读取的位置,将数据转换为用户/客户端时区? 我做得对吗?

一种。 我创建的数据库(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';

用户提交发布到商店(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 ($1,$2,$3,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 ($1,$2,$3,$4) 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"));
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM