PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Hàm postgreSQL age ():kết quả khác biệt / không mong muốn khi hạ cánh vào tháng khác

age được tính bằng timestamptz_age hàm trong src/backend/utils/adt/timestamp.c . Nhận xét cho biết:

/* timestamptz_age()
 * Calculate time difference while retaining year/month fields.
 * Note that this does not result in an accurate absolute time span
 *  since year and month are out of context once the arithmetic
 *  is done.
 */

Đầu tiên, mã chuyển đổi các đối số thành struct pg_tm biến tm1tm2 (struct pg_tm tương tự như struct tm của thư viện C , nhưng có các trường múi giờ bổ sung) và sau đó tính toán sự khác biệt tm mỗi trường.

Trong trường hợp của age('2018-07-01','2018-05-20') , các trường có liên quan của sự khác biệt đó sẽ giống như sau:

tm_mday = -19
tm_mon  =   2
tm_year =   0

Bây giờ các trường phủ định được điều chỉnh. cho tm_mday , mã trông như thế này:

while (tm->tm_mday < 0)
{
    if (dt1 < dt2)
    {
        tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
        tm->tm_mon--;
    }
    else
    {
        tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
        tm->tm_mon--;
    }
}

Kể từ dt1 > dt2 , else nhánh được sử dụng và mã thêm số ngày trong tháng 5 (31) và giảm tháng đi 1, kết thúc bằng

tm_mday = 12
tm_mon  =  1
tm_year =  0

Đó là kết quả bạn nhận được.

Thoạt nhìn, có vẻ như tm2->tm_mon không phải là tháng thích hợp để chọn và tốt hơn nên lấy tháng trước của đối số bên trái:

day_tab[isleap(tm1->tm_year)][(tm1->tm_mon + 10) % 12]

Nhưng tôi không thể nói liệu lựa chọn đó có tốt hơn trong mọi trường hợp hay không và trong bất kỳ trường hợp nào, nhận xét này sẽ bồi thường cho chức năng, vì vậy tôi ngần ngại gọi đó là lỗi.

Bạn có thể muốn đưa nó vào danh sách gửi thư của tin tặc.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách sử dụng dj-database-url khi kết nối với postgresql trong heroku bằng python

  2. 2ndQuadrant Deutschland - Mặc cả khai mạc khóa huấn luyện đặc biệt

  3. Làm cách nào để sử dụng toán tử% từ phần mở rộng pg_trgm?

  4. Doctrine - Thêm dấu thời gian mặc định vào thực thể như NOW ()

  5. Tập lệnh PHP với các lệnh PostgreSQL trả về NULL cho dữ liệu JSon