我想要计算两个日期时间字段之间的月数。
MySQL 中是否有更好的方法,而不是获取 Unix 时间戳,然后除以 2592000(秒),并向上取整?
我想要计算两个日期时间字段之间的月数。
MySQL 中是否有更好的方法,而不是获取 Unix 时间戳,然后除以 2592000(秒),并向上取整?
我很惊讶这还没有被提到:
请查看 MySQL 中的 TIMESTAMPDIFF() 函数。
该函数允许您传入两个 TIMESTAMP
或 DATETIME
值(甚至可以是 DATE
,因为 MySQL 会自动转换),以及您要基于的时间单位。
您可以在第一个参数中指定 MONTH
作为单位:
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-04')
-- Outputs: 0
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-05')
-- Outputs: 1
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-15')
-- Outputs: 1
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-12-16')
-- Outputs: 7
这基本上是从参数列表中的第一个日期开始计算经过的月数。该解决方案自动补偿每个月的天数(28、30、31),并考虑了闰年,您不必担心任何相关问题。
如果你想在经过的月数中引入小数精度,这会有点复杂,但是下面是如何实现:
SELECT
TIMESTAMPDIFF(MONTH, startdate, enddate) +
DATEDIFF(
enddate,
startdate + INTERVAL
TIMESTAMPDIFF(MONTH, startdate, enddate)
MONTH
) /
DATEDIFF(
startdate + INTERVAL
TIMESTAMPDIFF(MONTH, startdate, enddate) + 1
MONTH,
startdate + INTERVAL
TIMESTAMPDIFF(MONTH, startdate, enddate)
MONTH
)
如果你需要使用两个日期列或脚本输入参数中的日期参数,请使用startdate
和enddate
:
示例:
With startdate = '2012-05-05' AND enddate = '2012-05-27':
-- Outputs: 0.7097
With startdate = '2012-05-05' AND enddate = '2012-06-13':
-- Outputs: 1.2667
With startdate = '2012-02-27' AND enddate = '2012-06-02':
-- Outputs: 3.1935
PERIOD_DIFF 函数计算两个日期之间相差的月份数。
例如,要计算当前时间与你的表中某个时间列之间的差异:
select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table;
我同时使用PERIOD_DIFF函数。为了获取日期的年份和月份,我使用EXTRACT函数:
SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM time)) AS months FROM your_table;
DATE_FORMAT
方法少50%,谢谢!+1 - David RodriguesSELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM FROM_UNIXTIME(time, "%Y%m%d"))) AS months FROM your_table;
- SmollaPERIOD_DIFF
不接受天数值,因此您正在计算最接近整月的月份数,如果不足一个整月。您应该编辑您的答案以澄清这一点。 - rgvcorleyDATEDIFF 函数可以计算出两个日期之间的天数。这样更加准确,因为...如何定义一个月呢?(28、29、30或31天?)
PERIODDIFF
可以精确计算月份数量。 - Max CaceresPERIODDIFF
评论会有那么多赞?Perioddiff不接受天数值,所以如果不足整月,你正在计算最接近的整月数量并向上取整。 - rgvcorley正如这里的许多答案所展示的那样,'正确'的答案取决于你需要什么。在我的情况下,我需要将其四舍五入为最接近的整数。
考虑以下例子: 1月1日->1月31日:0个整月,几乎为1个月。 1月1日->2月1日?1个整月,正好为1个月。
要获取完整的月数,请使用:
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-01-31'); => 0
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-01'); => 1
要获取以月为单位的四舍五入持续时间,您可以使用:
SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1
SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1
这是精确到+/- 5天,适用于超过1000年的范围。Zane的答案显然更准确,但对我来说太冗长了。
我更喜欢这种方式,因为每个人一眼就能清晰地理解它:
SELECT
12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months
FROM
tab;
根据MySQL手册:
PERIOD_DIFF(P1,P2)
返回P1和P2之间的月数。P1和P2应该是YYMM或YYYYMM格式。请注意,期间参数P1和P2不是日期值。
mysql> SELECT PERIOD_DIFF(200802,200703); -> 11
因此,可能可以像这样做:
Select period_diff(concat(year(d1),if(month(d1)<10,'0',''),month(d1)), concat(year(d2),if(month(d2)<10,'0',''),month(d2))) as months from your_table;
d1和d2是日期表达式。
我不得不使用if()语句来确保月份是两位数,例如02而不是2。
select period_diff(date_format(now(),"%Y%m"),date_format(created,"%Y%m")) from customers where..
提供了一个日历月数,自客户记录创建日期时间戳以来,让MySQL在内部进行月份选择。
DROP FUNCTION IF EXISTS `calcula_edad` $$
CREATE DEFINER=`root`@`localhost` FUNCTION `calcula_edad`(pFecha1 date, pFecha2 date, pTipo char(1)) RETURNS int(11)
Begin
Declare vMeses int;
Declare vEdad int;
Set vMeses = period_diff( date_format( pFecha1, '%Y%m' ), date_format( pFecha2, '%Y%m' ) ) ;
/* Si el dia de la fecha1 es menor al dia de fecha2, restar 1 mes */
if day(pFecha1) < day(pFecha2) then
Set vMeses = VMeses - 1;
end if;
if pTipo='A' then
Set vEdad = vMeses div 12 ;
else
Set vEdad = vMeses ;
end if ;
Return vEdad;
End
select calcula_edad(curdate(),born_date,'M') -- for number of months between 2 dates
PERIODDIFF
评论的赞都是非常误导性的。 - rgvcorley