Domanda

I need to get date, which was 30 (later I will use also 90 or 18O) days before first day of current (and previous) month. I wrote this, but I think it's unnecessarily complicated, so I come here for help. It's any way how can I simplify this:

ib_encodedate(EXTRACT(YEAR from (dateadd(-30-datediff(day from cast(EXTRACT(MONTH from CURRENT_DATE) 
|| '-1-' 
|| EXTRACT(YEAR from CURRENT_DATE) as date) to date 'now') DAY to CURRENT_DATE))), EXTRACT(MONTH from (dateadd(-30-datediff(day from cast(EXTRACT(MONTH from CURRENT_DATE) 
|| '-1-' 
|| EXTRACT(YEAR from CURRENT_DATE) as date) to date 'now') DAY to CURRENT_DATE))),EXTRACT(DAY from (dateadd(-30-datediff(day from cast(EXTRACT(MONTH from CURRENT_DATE) 
|| '-1-' 
|| EXTRACT(YEAR from CURRENT_DATE) as date) to date 'now') DAY to CURRENT_DATE))))

In database I have dates in double, so I have to use function ib_encodedate to convert date to double and compare with date in database. Function have prototype:

ib_encodedate(INT year, INT month, INT day)

The same I need to write for last day of month.

Thanks for any help.

È stato utile?

Soluzione

Seems like you need something like this:

SELECT
    DATEADD (-EXTRACT(DAY FROM CURRENT_DATE)+1 DAY TO CURRENT_DATE) AS FIRST_DAY_OF_MONTH,
    DATEADD (-30 DAY TO DATEADD (-EXTRACT(DAY FROM CURRENT_DATE)+1 DAY TO CURRENT_DATE)) AS A_MONTH_AGO,
    DATEADD (-90 DAY TO DATEADD (-EXTRACT(DAY FROM CURRENT_DATE)+1 DAY TO CURRENT_DATE)) AS THREE_MONTHS_AGO,
    DATEADD (-180 DAY TO DATEADD (-EXTRACT(DAY FROM CURRENT_DATE)+1 DAY TO CURRENT_DATE)) AS SIX_MONTHS_AGO
FROM 
    RDB$DATABASE

Using the function DATEADD from firebird you can easily accomplish this.

Altri suggerimenti

First Day of The Date:

select cast(:DATA as date) - extract(day from cast(:DATA as date)) + 1 from RDB$DATABASE

Last Day of The Date:

select cast(:DATA as date) - extract(day from cast(:DATA as date)) + 32 - extract(day from (cast(:DATA as date) - extract(day from cast(:DATA as date)) + 32)) from RDB$DATABASE

Using Firebird 2.5

First Day:

SELECT CAST(EXTRACT(YEAR FROM CURRENT_DATE)||'-'||EXTRACT(MONTH FROM 
       CURRENT_DATE)||'-01' AS DATE) FROM RDB$DATABASE

Last Day:

SELECT DATEADD (-1 DAY TO DATEADD (1 MONTH TO CAST(EXTRACT(YEAR FROM 
                CURRENT_DATE)||'-'||EXTRACT(MONTH FROM CURRENT_DATE)||'-01' AS DATE))) 
      FROM RDB$DATABASE

If you use firebird 1.5 you can create this function which returns the last day of the month of a specified date:

create or alter procedure LAST_DAY_OF_MONTH (
    REFERENCE_DATE date)
returns (
    LAST_DAY date)
as
declare variable NEXT_DAY date;
declare variable COUNTER integer;
begin
    NEXT_DAY = :REFERENCE_DATE;
    COUNTER = 0;
    while (:COUNTER < 33) do begin
        NEXT_DAY = :NEXT_DAY + 1;
        if (extract(month from :NEXT_DAY) = extract(month from :REFERENCE_DATE)) then begin
            LAST_DAY = :NEXT_DAY;
        end
        COUNTER = :COUNTER + 1;
    end
    suspend;
end

Then to call it just execute:

select last_day from last_day_of_month('02-23-2016')

This will return 02-29-2016

select dateadd (month, -1,dateadd (-extract(day from current_date)+1 day to current_date)) First_day_month_ago 
from RDB$DATABASE 
union all
select dateadd (-extract(day from current_date)+1 day to current_date) First_day_current_month 
from RDB$DATABASE

Migrating from MySQL I needed the FIRST_DAY and LAST_DAY functions. Here they are:

CREATE OR ALTER FUNCTION FIRST_DAY(d TIMESTAMP)
RETURNS DATE
AS 
BEGIN
   RETURN CAST(d - EXTRACT(DAY FROM d) + 1 AS DATE); 
END

and

CREATE OR ALTER FUNCTION LAST_DAY(d TIMESTAMP)
RETURNS DATE
AS 
BEGIN
   RETURN DATEADD(1 MONTH TO FIRST_DAY(d)) - 1;  
END

And executing from isql:

SQL> SELECT first_day(CURRENT_TIMESTAMP), last_day(CURRENT_TIMESTAMP) FROM RDB$DATABASE rd;

  FIRST_DAY    LAST_DAY 
=========== =========== 
2020-08-01  2020-08-31  

but creating a function like this:

create or alter function F_DAYSOFMONTH (
    LMONTH integer,
    LYEAR integer)
returns integer
as
declare variable LTMPDT DM_DATA;
declare variable LTMPDT2 timestamp;
begin
  SELECT CAST(CAST(:lmonth AS VARCHAR(10)) || '/01/' || CAST(:lyear AS VARCHAR(10)) AS TIMESTAMP) FROM RDB$DATABASE INTO :LTMPDT;

  LTMPDT2 = dateadd(1 month TO :LTMPDT);


  return datediff(DAY FROM :ltmpdt TO :LTMPDT2);;
end^

SET TERM ; ^

CREATE PROCEDURE FIRST_LAST_DAYOFMONTH(COMPARE_DATE TIMESTAMP)
RETURNS (FIRST_DAYOFOMONTH TIMESTAMP,LAST_DAYOFMONTH TIMESTAM)
AS
BEGIN
FIRST_DAYOFMONTH=COMPARE_DATE-(EXTRACT(DAY FROM :COMPARE_DATE)-1);
LAST_DAYOFMONTH=DATEADD(1 MONT TO :COMPARE_DATE)-1;
SUSPEND;
END^
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top