Обычно не имеет смысла пытаться представить разницу между двумя датами в формате даты.Если у вас есть две даты с интервалом в несколько дней, имеет ли смысл возвращать значение, которое представляет собой «3 января 0001 в 8:15:00 утра» (примерно 2,34 дня после 1 января 001 в полночь)?И все становится сложнее, когда различия становятся больше, потому что преобразование дней в месяцы и годы становится очень, очень неочевидным.Если у вас есть две даты, которые разделены ровно на 1 месяц, но этот месяц составляет 30 дней, вы возвращаете «31 января 0001», через 30 дней после 1 января, или «1 февраля, 0001», через 1 месяц после 1 января.
Если вы преобразуете два поля в метки времени, а не в дни, и вычитаете их, вы получите интервал, который является гораздо более подходящим способом представления разницы между двумя моментами времени.Затем вы можете делать такие вещи, как извлечение различных компонентов интервала или преобразование интервала в строку.
with x as (
select to_timestamp( '19.09.2019 11:26:00', 'dd.mm.yyyy hh24:mi:ss' ) -
to_timestamp( '01.01.2019 00:00:00', 'dd.mm.yyyy hh24:mi:ss' ) diff
from dual
)
select to_char( diff ),
extract( day from diff ) days,
extract( hour from diff ) hours,
extract( minute from diff ) minutes,
extract( second from diff ) seconds
from x;
Обратите внимание, что вы не можете использовать extract
, чтобы получить месяцы или годы, потому что нетоднозначный способ представить это.Если вы хотите реализовать свою собственную логику, чтобы выяснить, что для вас означают «годы» и «месяцы», вы можете делать это, манипулируя днями (т. Е. В финансах вы часто отработаете 360 дней, а 12 30 дней).месяцев, так что достаточно легко разделить на 30, не заботясь о том, имеете ли вы в реальности 28 или 31-дневный месяц).