如何在Octave中将年月日格式的时间序列转换为十进制年份?
在Octave中将年/月/日时间序列转换为十进制年份
刚好之前处理过类似的需求,在Octave里把年/月/日转成十进制年份其实挺简单的,核心思路就是算出这个日期在当年的占比,再加上年份本身就行。下面给你两种实用的实现方式:
方法一:使用Octave内置函数(推荐,省心可靠)
Octave的datevec和datenum函数可以帮我们快速处理日期计算,还能自动处理闰年的情况,不用自己写判断逻辑。
假设你的日期是字符串格式(比如"yyyy-mm-dd"),可以用下面的代码:
% 示例日期数组 dates = ["2023-03-15"; "2024-07-20"; "2022-12-31"]; % 把日期字符串转换成日期向量:[年, 月, 日, 时, 分, 秒] date_vecs = datevec(dates); % 提取年份列 years = date_vecs(:, 1); % 生成当年1月1日的日期向量(时分秒设为0) start_of_year = [years, ones(size(years,1),1), ones(size(years,1),1), zeros(size(years,1),3)]; % 生成当年12月31日23:59:59的日期向量,确保覆盖全年 end_of_year = [years, 12*ones(size(years,1),1), 31*ones(size(years,1),1), 23*ones(size(years,1),1), 59*ones(size(years,1),1), 59*ones(size(years,1),1)]; % 计算每个日期的datenum值(从某个基准日开始的天数) datenum_current = datenum(date_vecs); datenum_start = datenum(start_of_year); datenum_end = datenum(end_of_year); % 计算十进制年份:年份 + 当年已过天数/全年总天数 decimal_years = years + (datenum_current - datenum_start) ./ (datenum_end - datenum_start);
如果你的日期本来就是数值型的年、月、日数组,直接把date_vecs换成你的数值矩阵就行,不用调用datevec。
方法二:手动实现(适合理解底层逻辑)
如果你想搞清楚具体的计算过程,可以手动实现,需要自己判断闰年并计算天数:
% 示例:单独的年、月、日数组 Y = [2023, 2024, 2022]; M = [3, 7, 12]; D = [15, 20, 31]; % 判断闰年:能被4整除但不能被100整除,或者能被400整除 is_leap = (mod(Y,4)==0 & mod(Y,100)~=0) | (mod(Y,400)==0); % 非闰年各月的天数 month_days = repmat([31,28,31,30,31,30,31,31,30,31,30,31], length(Y), 1); % 闰年2月改成29天 month_days(is_leap, 2) = 29; % 计算当月之前的累计天数 cum_days = arrayfun(@(i) sum(month_days(i,1:M(i)-1)), 1:length(Y)); % 加上当月的天数,得到当天是当年的第几天 total_day_of_year = cum_days + D; % 全年总天数 year_total_days = is_leap.*366 + (~is_leap).*365; % 计算十进制年份 decimal_years = Y + total_day_of_year ./ year_total_days;
小提示
- 如果你的日期包含时分秒,方法一的
datenum会自动把时分秒转换成天数的小数部分,结果更精确;方法二需要额外把时分秒转换成一天的占比(比如(H*3600 + M*60 + S)/86400),加到total_day_of_year里。 - 如果你的日期字符串格式比较特殊(比如不是
yyyy-mm-dd),可以先用strptime函数解析成日期向量。
内容的提问来源于stack exchange,提问作者Pakat 123
相关产品推荐
相关产品推荐

