Necesito para obtener la diferencia entre dos fechas decir si la diferencia es de 84 días, probablemente debería tener una salida como 2 meses y 14 días, el código que solo se le da a los totales. Aquí está el código

SELECT Months_between(To_date('20120325', 'YYYYMMDD'),
       To_date('20120101', 'YYYYMMDD'))
       num_months,
       ( To_date('20120325', 'YYYYMMDD') - To_date('20120101', 'YYYYMMDD') )
       diff_in_days
FROM   dual; 

La salida es:

NUM_MONTHS    DIFF_IN_DAYS
2.774193548       84

Necesito, por ejemplo, el resultado de esta consulta será de 2 meses y 14 días, en el peor, de lo contrario no me importa si me pueden tener la exacta días después de los meses figura, ya que esos días no son en realidad 14 porque todos los meses no tienen 30 días.

Es que Nadie Tener respuesta a esto?
No debería ser 2 meses y 24 días?

OriginalEl autor ErrorNotFoundException | 2012-07-16

10 Comentarios

  1. 19
    select 
      dt1, dt2,
      trunc( months_between(dt2,dt1) ) mths, 
      dt2 - add_months( dt1, trunc(months_between(dt2,dt1)) ) days
    from
    (
        select date '2012-01-01' dt1, date '2012-03-25' dt2 from dual union all
        select date '2012-01-01' dt1, date '2013-01-01' dt2 from dual union all
        select date '2012-01-01' dt1, date '2012-01-01' dt2 from dual union all
        select date '2012-02-28' dt1, date '2012-03-01' dt2 from dual union all
        select date '2013-02-28' dt1, date '2013-03-01' dt2 from dual union all
        select date '2013-02-28' dt1, date '2013-04-01' dt2 from dual union all
        select trunc(sysdate-1)  dt1, sysdate               from dual
    ) sample_data

    Resultados:

    |                        DT1 |                       DT2 | MTHS |     DAYS |
    ----------------------------------------------------------------------------
    |  January, 01 2012 00:00:00 |   March, 25 2012 00:00:00 |    2 |       24 |
    |  January, 01 2012 00:00:00 | January, 01 2013 00:00:00 |   12 |        0 |
    |  January, 01 2012 00:00:00 | January, 01 2012 00:00:00 |    0 |        0 |
    | February, 28 2012 00:00:00 |   March, 01 2012 00:00:00 |    0 |        2 |
    | February, 28 2013 00:00:00 |   March, 01 2013 00:00:00 |    0 |        1 |
    | February, 28 2013 00:00:00 |   April, 01 2013 00:00:00 |    1 |        1 |
    |   August, 14 2013 00:00:00 |  August, 15 2013 05:47:26 |    0 | 1.241273 |

    Link de prueba: SQLFiddle

    Por favor, ¿qué dt2 y dt1 representan pensé que era algo de fechas?
    Espero no te importa he añadido algunos datos de ejemplo para su consulta. Ninguna de las otras respuestas producir resultados más precisos. La mayoría no están ni remotamente cerca. Es el resultado de alrededor de 28 de febrero que muestran realmente la diferencia. Suponiendo que el 30 o 31 días al mes no siempre funciona. No estoy seguro de si hay un oficial algoritmo para el conteo de los meses y los días, pero estos resultados de buscar lo mejor para mí.
    Me uní a jonearles y agregar dos ejemplos más para año bisiesto y la fecha con el tiempo y el enlace a la página donde cualquiera puede probar la solución en línea.
    Puede intentar lo siguiente de la fecha de pares y ver si las respuestas tienen sentido para usted? 2013-01-28 y 2013-02-28, 2013-01-29 y 2013-02-28, 2013-01-30 y 2013-02-28, y 2013-01-31 y 2013-02-28.
    Finalmente, jen. Esto es Lo que estaba Buscando!!!!! Gracias le tomó un año y un Mes 🙂

    OriginalEl autor jen

  2. 2

    Actualizado para la corrección. Originalmente contestada por @jen.

    with DATES as (
       select TO_DATE('20120101', 'YYYYMMDD') as Date1,
              TO_DATE('20120325', 'YYYYMMDD') as Date2
       from DUAL union all
       select TO_DATE('20120101', 'YYYYMMDD') as Date1,
              TO_DATE('20130101', 'YYYYMMDD') as Date2
       from DUAL union all
       select TO_DATE('20120101', 'YYYYMMDD') as Date1,
              TO_DATE('20120101', 'YYYYMMDD') as Date2
       from DUAL union all
       select TO_DATE('20130228', 'YYYYMMDD') as Date1,
              TO_DATE('20130301', 'YYYYMMDD') as Date2
       from DUAL union all
       select TO_DATE('20130228', 'YYYYMMDD') as Date1,
              TO_DATE('20130401', 'YYYYMMDD') as Date2
       from DUAL
    ), MONTHS_BTW as (
       select Date1, Date2,
              MONTHS_BETWEEN(Date2, Date1) as NumOfMonths
       from DATES
    )
    select TO_CHAR(Date1, 'MON DD YYYY') as Date_1,
           TO_CHAR(Date2, 'MON DD YYYY') as Date_2,
           NumOfMonths as Num_Of_Months,
           TRUNC(NumOfMonths) as "Month(s)",
           ADD_MONTHS(Date2, - TRUNC(NumOfMonths)) - Date1 as "Day(s)"
    from MONTHS_BTW;

    SQLFiddle Demo :

     +--------------+--------------+-----------------+-----------+--------+ 
    | DATE_1 | DATE_2 | NUM_OF_MONTHS | MES(S) DÍA(S) | 
    +--------------+--------------+-----------------+-----------+--------+ 
    | 01 ENE 2012 | MAR 25 2012 | 2.774193548387 | 2 | 24 | 
    | 01 ENE 2012 | ENE 01 2013 | 12 | 12 | 0 | 
    | 01 ENE 2012 | ENE 01 2012 | 0 | 0 | 0 | 
    | EL 28 DE FEBRERO DE 2013 | MAR 01 2013 | 0.129032258065 | 0 | 1 | 
    | EL 28 DE FEBRERO DE 2013 | ABR 01 2013 | 1.129032258065 | 1 | 1 | 
    +--------------+--------------+-----------------+-----------+--------+ 
    

    Aviso, cómo para las dos últimas fechas, Oracle reports la parte decimal de meses (lo que le da días) incorrectamente. 0.1290 se corresponde exactamente con 4 días con Oracle considerando 31 días en un mes (Marzo y abril).

    No es muy preciso. Se debería haber regresado de 24 días.
    Gracias por el aviso. Al parecer, el uso de 31 como «días en un mes» parece haberse solucionado. En realidad pensé que, tanto en el 30 y 31 a veces devolver el exacto y a veces apagado por 1 número de días (dependiendo de los meses fueron elegidos), pero, la ronda se toma el cuidado de él. Tener un vistazo de nuevo si lo desea.
    Multiplicando por 30 o 31 no es una buena idea. Se va a romper en algunas fechas, especialmente cuando de febrero está involucrado.
    Me hicieron algunas pruebas más. Entiendo lo que estás diciendo ahora.
    Uso 30.41667, que es (365/12). Este es el número promedio de días en un mes, por un año. Encontré cuando me pongo (365/12) en SQLite consulta que se hizo 30, (que de alguna manera piso de mi consulta, aunque no sé cómo), así que me tenía que conectar 30.41667 antes de que las cosas comenzaron a ser exacta, así que mira esto en el caso de que los cultivos en Oracle, demasiado, sobre todo porque se tendría que FLOOR (o TRUNC, como puedo ver arriba) su MONTHS_BETWEEN restarlas lejos para conseguir tu decimal, y por lo tanto, los días de la porción, para multiplicar este por.

    OriginalEl autor Ravi Thapliyal

  3. 2

    Creo que tu pregunta no está definido bastante bien, por la siguiente razón.

    Respuestas confiar en months_between tienen que lidiar con el problema siguiente: que la función de los informes de exactamente un mes entre 2013-02-28 y 2013-03-31, y entre 2013-01-28 y 2013-02-28, y entre 2013-01-31 y 2013-02-28 (sospecho que algunos de los ms responden no han utilizado estas funciones en la práctica, o ahora van a tener que revisar algunas código de producción!)

    Esto está documentado el comportamiento, en el que las fechas que son los últimos en sus respectivos meses o que caen en el mismo día del mes en que se juzga a ser un número entero de meses de diferencia.

    Así que se puede obtener el mismo resultado de «1» cuando se comparan 2013-02-28 con 2013-01-28 o con 2013-01-31, pero comparando con 2013-01-29 o 2013-01-30 da 0.967741935484 y 0.935483870968 respectivamente-así como uno de los enfoques de la fecha de la otra la diferencia reportada por esta función puede aumentar.

    Si esto no es una situación aceptable, entonces usted tendrá que escribir una función más compleja, o simplemente se basan en un cálculo que supone 30 (por ejemplo) días por mes. En el último caso, ¿cómo va a lidiar con 2013-02-28 y 2013-03-31?

    Traer algunos excelentes puntos. Este es un simple, común pregunta sin respuesta perfecta. Sea cual fuere la solución que se utiliza, probablemente debería incluir un descargo de responsabilidad. Todavía voy a premio de la recompensa a la aceptación de respuesta ya que se siente bien para mí. Pero eso sólo puede ser porque he usado months_between demasiado.
    Sí, como Jon Heller dice, un buen punto de cómo 2-28 a 3-31 es 1, en lugar de 2-28 a 3-28 = 1. Por eso, al llegar a los días, realmente debería contar los días, no MONTHS_BETWEEN.

    OriginalEl autor David Aldridge

  4. 1

    es esto lo que has ment ?

    select trunc(months_between(To_date('20120325', 'YYYYMMDD'),to_date('20120101','YYYYMMDD'))) months,
                 round(To_date('20120325', 'YYYYMMDD')-add_months(to_date('20120101','YYYYMMDD'),
                               trunc(months_between(To_date('20120325', 'YYYYMMDD'),to_date('20120101','YYYYMMDD'))))) days
            from dual;
    No funciona cuando para fechas como el 20120129 – 20120325.
    gracias, ahora lo es:)
    Esto También es Correcto 😛

    OriginalEl autor planben

  5. 1

    Aquí solo estoy haciendo la diferencia entre el día de hoy, y un CREATED_DATE DATE campo en una tabla, la cual, obviamente, es una fecha en el pasado:

    SELECT  
    ((FLOOR(ABS(MONTHS_BETWEEN(CREATED_DATE, SYSDATE))) / 12) * 12) || ' months, '  AS MONTHS,
    -- we take total days - years(as days) - months(as days) to get remaining days
    FLOOR((SYSDATE - CREATED_DATE) -      -- total days
    (FLOOR((SYSDATE - CREATED_DATE)/365)*12)*(365/12) -      -- years, as days
    -- this is total months - years (as months), to get number of months, 
    -- then multiplied by 30.416667 to get months as days (and remove it from total days)
    FLOOR(((SYSDATE - CREATED_DATE)/365)*12 - (FLOOR((SYSDATE - CREATED_DATE)/365)*12)) * (365/12))
    || ' days ' AS DAYS 
    FROM MyTable

    Yo uso (365/12), o 30.416667, como mi factor de conversión porque estoy utilizando el total de días y extracción de años y meses (días) para obtener el resto el número de días. Era lo suficientemente bueno para mis propósitos, de todos modos.

    OriginalEl autor vapcguy

  6. 0

    La solución que voy a publicar considerar un mes con 30 días

      select CONCAT (CONCAT (num_months,' MONTHS '), CONCAT ((days-(num_months)*30),' DAYS '))
      from ( 
      SELECT floor(Months_between(To_date('20120325', 'YYYYMMDD'),
       To_date('20120101', 'YYYYMMDD')))
       num_months,
       ( To_date('20120325', 'YYYYMMDD') - To_date('20120101', 'YYYYMMDD') )
       days
      FROM   dual);
    Multiplicando por 30 o 31 no es una buena idea. Se va a romper en algunas fechas, especialmente cuando de febrero está involucrado.
    Me multiplicar por (365/12), o 30.41667, pero la forma de uso que no es para encontrar directamente la cantidad real de días usando la resultante de la figura, como la de arriba. Usted puede utilizarlo para convertir el MONTHS_BETWEEN días, lo que da el total de días, luego de restar la cantidad de tiempo (en días) que son meses, a buscar los días restantes.

    OriginalEl autor Harshit

  7. -2

    MsSql Sintaxis : DATEDIFF ( datepart , fechainicio , enddate )

    Oracle: Este le devuelve el número de días

        select
      round(Second_date - First_date)  as Diff_InDays,round ((Second_date - First_date) / (30),1)  as Diff_InMonths,round ((Second_date - First_date) * (60*24),2)  as TimeIn_Minitues
    from
      (
      select
        to_date('01/01/2012 01:30:00 PM','mm/dd/yyyy hh:mi:ss am') as First_date
       ,to_date('05/02/2012 01:35:00 PM','mm/dd/yyyy HH:MI:SS AM') as Second_date
      from
        dual
      ) result;

    Demo : http://sqlfiddle.com/#!4/c26e8/36

    Esa es una sintaxis de transact sql, oracle no
    Incluso en tsql que no se dará OP está pidiendo
    Estoy usando Oracle y Talend Open Studio
    ¿Qué date_part representan?
    compruebe editado mi respuesta

    OriginalEl autor Satinder singh

  8. -2
    SELECT   (MONTHS_BETWEEN(date2,date1) +  (datediff(day,date2,date1))/30) as num_months,
    datediff(day,date2,date1) as diff_in_days  FROM  dual;
    
    // You should replace date2 with TO_DATE('2012/03/25', 'YYYY/MM/DD')
    // You should replace date1 with TO_DATE('2012/01/01', 'YYYY/MM/DD')
    // To get you results
    DateDiff es en qué tabla de Oracle porque vuelve Invaid Identificador en dual>???
    Sí. Tienes razón me proporcionaría pronto la solución específica de oracle
    Si datediff no funciona para usted, simplemente intentar fecha2-fecha1 en lugar de datediff(día,fecha2,fecha1) Lo trabajado compartir conmigo por favor.. Gracias
    w3schools.com/sql/func_datediff_mysql.asp en Realidad por el momento no he oracle motor de lo contrario creo que simple sql(lenguaje) la función debe trabajar en oracle así
    Por favor, Comprenda la potencia necesaria si es decir, 122 días, que debe ser 2months y 14 días

    OriginalEl autor Sami

  9. -2

    Averiguar Año – Mes – Día, entre dos Días en Orale Sql


    select 
    trunc(trunc(months_between(To_date('20120101', 'YYYYMMDD'),to_date('19910228','YYYYMMDD')))/12) years ,
    trunc(months_between(To_date('20120101', 'YYYYMMDD'),to_date('19910228','YYYYMMDD'))) 
    -
    (trunc(trunc(months_between(To_date('20120101', 'YYYYMMDD'),to_date('19910228','YYYYMMDD')))/12))*12
    months,
                 round(To_date('20120101', 'YYYYMMDD')-add_months(to_date('19910228','YYYYMMDD'),
                               trunc(months_between(To_date('20120101', 'YYYYMMDD'),to_date('19910228','YYYYMMDD'))))) days
            from dual;

    OriginalEl autor zico

  10. -4

    Ver la consulta de abajo (que se supone @dt1 >= @dt2);

    Declare @dt1 datetime = '2013-7-3'
    Declare @dt2 datetime = '2013-5-2'
    
    select abs(DATEDIFF(DD, @dt2, @dt1)) Days,
    case when @dt1 >= @dt2
        then case when DAY(@dt2)<=DAY(@dt1)
            then Convert(varchar, DATEDIFF(MONTH, @dt2, @dt1)) + CONVERT(varchar, ' Month(s) ') + Convert(varchar, DAY(@dt1)-DAY(@dt2)) + CONVERT(varchar, 'Day(s).')
            else Convert(varchar, DATEDIFF(MONTH, @dt2, @dt1)-1) + CONVERT(varchar, ' Month(s) ') + convert(varchar, abs(DATEDIFF(DD, @dt1, DateAdd(Month, -1, @dt1))) - (DAY(@dt2)-DAY(@dt1))) + CONVERT(varchar, 'Day(s).')
        end
        else 'See asumption: @dt1 must be >= @dt2'
    end In_Months_Days

    Devuelve:

    Days | In_Months_Days
    
    62   |   2 Month(s) 1Day(s).
    Oracle pregunta, no una de SQL Server pregunta.

    OriginalEl autor Hassan Farid

Dejar respuesta

Please enter your comment!
Please enter your name here