【发布时间】:2020-11-04 19:59:03
【问题描述】:
由于我的 MySQL 数据库中有一些旧值代表 java.time.LocalDate 值,我想创建一个转换函数来取回正确的 MySQL DATE 值。初始值是通过LocalDate.toEpochDay() 生成的。于是我查看了对应的LocalDate.ofEpochDay(long epochDay)方法(见here)并尝试翻译。但是我的翻译产生了我无法解释的负面日子。
有谁知道为什么以下功能不起作用?
create function fromEpochDays(days bigint)
RETURNS date DETERMINISTIC
--RETURNS varchar(50) DETERMINISTIC
BEGIN
DECLARE dom bigint;
DECLARE month bigint;
DECLARE year bigint;
DECLARE zeroDay bigint;
DECLARE adjust bigint;
DECLARE daysPerCycle bigint;
DECLARE adjustCycles bigint;
DECLARE yearEst bigint;
DECLARE doyEst bigint;
DECLARE marchDoy0 bigint;
DECLARE marchMonth0 bigint;
DECLARE dateToParse CHAR(100);
DECLARE valToCheck CHAR(100);
SET daysPerCycle = 146097;
SET adjustCycles = 0;
SET adjust = 0;
SET zeroDay = days + 719528 - 60;
IF zeroDay < 0 THEN
SET adjustCycles = (zeroDay + 1) / daysPerCycle - 1;
SET adjust = adjustCycles * 400;
SET zeroDay = zeroDay + (-adjustCycles * daysPerCycle);
END IF;
SET yearEst = (400 * zeroDay + 591) / daysPerCycle;
SET doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
IF doyEst < 0 THEN
SET yearEst = yearEst - 1;
SET doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
END IF;
SET yearEst = yearEst + adjust;
SET marchDoy0 = doyEst;
SET marchMonth0 = (marchDoy0 * 5 + 2) / 153;
SET month = MOD((marchMonth0 + 2),12) + 1;
SET dom = marchDoy0 - (marchMonth0 * 306 + 5) / 10 + 1;
SET year = yearEst + marchMonth0 / 10;
SET dateToParse = concat(cast(dom as char(20)),',',cast(month as char(20)),',',cast(year as char(20)));
return STR_TO_DATE(dateToParse,'%d,%m,%Y');
END;
如果我将函数更改为仅返回变量 dateToParse 并使用不同的值调用它,我会得到以下结果:
select
fromEpochDays_AsChar(12),
fromEpochDays_AsChar(13),
fromEpochDays_AsChar(14),
fromEpochDays_AsChar(15),
fromEpochDays_AsChar(16),
fromEpochDays_AsChar(29),
fromEpochDays_AsChar(30),
fromEpochDays_AsChar(31),
fromEpochDays_AsChar(32)
fromEpochDays_AsChar(12) 13,1,1970
fromEpochDays_AsChar(13) 14,1,1970
fromEpochDays_AsChar(14) 15,1,1970
fromEpochDays_AsChar(15) -15,2,1970
fromEpochDays_AsChar(16) -14,2,1970
fromEpochDays_AsChar(29) -1,2,1970
fromEpochDays_AsChar(30) 0,2,1970
fromEpochDays_AsChar(31) 1,2,1970
fromEpochDays_AsChar(32) 2,2,1970
从 0 到 14 的值产生正确的值,但以下看起来显然很奇怪......看起来只有前半个月的计算正确。
【问题讨论】:
-
尝试使用 DECLARE result_date DATE 计算新日期;选择 DATE_ADD("1970-01-01", INTERVAL days DAY) 到 result_date;
-
@BUcorp 感谢您的评论!我现在使用它作为解决方法。但我真的很想知道我在那里做错了什么,因为我花了很多时间在这个功能上。也许这是 MySQL 在计算
bigint时的限制? -
老实说我不知道,但我将答案发布为函数 mysql。如果你解决了,请告诉我(记得标记为已回答;))