我正在处理Rails和Postgres中的日期和时间并遇到这个问题:
数据库采用UTC格式.
用户在Rails应用程序中设置选择的时区,但仅在获取用户本地时间来比较时间时使用.
用户存储时间,例如2012年3月17日晚上7点.我不希望存储时区转换或时区.我只想保存日期和时间.这样,如果用户改变他们的时区,它仍将显示2012年3月17日,晚上7点.
我只使用用户指定的时区来获取用户本地时区当前时间之前或之后的记录.
我目前正在使用"没有时区的时间戳",但是当我检索记录时,rails(?)会将它们转换为应用程序中的时区,这是我不想要的.
Appointment.first.time
=> Fri, 02 Mar 2012 19:00:00 UTC +00:00
Run Code Online (Sandbox Code Playgroud)
因为数据库中的记录似乎是以UTC形式出现的,我的黑客是用当前时间,用'Date.strptime(str,"%m /%d /%Y")删除时区,然后做我的查询:
.where("time >= ?", date_start)
Run Code Online (Sandbox Code Playgroud)
似乎必须有一种更简单的方法来忽略周围的时区.有任何想法吗?
问题很简单:如果我已经在没有时区的列类型时间戳中有数据,如果我将类型设置为带时区的时间戳,postgresql对这些数据做了什么?
我ALTER COLUMN
在PostgreSQL 9.3 ALTER TABLE
手册页中找到了这个语句:
ALTER TABLE audits
ALTER COLUMN created_at SET DATA TYPE timestamp with time zone
USING
timestamp with time zone 'epoch' + created_at * interval '1 second';
Run Code Online (Sandbox Code Playgroud)
我似乎无法让这个工作.我收到这个错误:
Run Code Online (Sandbox Code Playgroud)ERROR: operator does not exist: timestamp without time zone * interval SQL state: 42883 Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
该ALTER TABLE
声明看起来很直盼着.但我已经尝试了各种类型的转换和转换列类型,但无法使其工作.我错过了什么?
我只是花了一个小时绝望,这两个表达式的结果有差异:
db=# SELECT '2012-01-18 1:0 CET'::timestamptz AT TIME ZONE 'UTC'
,'2012-01-18 1:0 Europe/Vienna'::timestamptz AT TIME ZONE 'UTC';
timezone | timezone
---------------------+---------------------
2012-08-18 00:00:00 | 2012-08-17 23:00:00
Run Code Online (Sandbox Code Playgroud)
显然,第二个表达式根据DST规则扣除两个小时,其中第一个表达式仅使用标准偏移量.
我检查了这两个时区名称的目录.他们都在那里,看起来一样:
db=# SELECT * FROM pg_timezone_names WHERE name IN ('CET', 'Europe/Vienna');
name | abbrev | utc_offset | is_dst
---------------+--------+------------+--------
Europe/Vienna | CEST | 02:00:00 | t
CET | CEST | 02:00:00 | t
Run Code Online (Sandbox Code Playgroud)
我查阅了关于时区的PostgreSQL手册:
PostgreSQL允许您以三种不同的形式指定时区:
全时区名称,例如America/New_York.识别的时区名称列在pg_timezone_names视图中(参见第45.67节).PostgreSQL为此目的使用广泛使用的zoneinfo时区数据,因此许多其他软件也识别相同的名称.
时区缩写,例如PST.这样的规范仅定义了与UTC的特定偏移,而不是全时区名称,其也可以暗示一组夏令时转换日期规则.公认的缩写列在pg_timezone_abbrevs视图中(参见第45.66节).您不能将配置参数timezone或log_timezone设置为时区缩写,但可以在日期/时间输入值和AT TIME ZONE运算符中使用缩写.
大胆的重点我的.
为什么差异呢?
关于Debian …