MATLAB学习文档(十六)
目录
8.3 日期时间数组
8.3.1日期时间数据的基础知识
时区的概念
示例
世界时、国际原子时、协调世界时(UTC)和夏令时
1. 世界时(UT)
2. 国际原子时(TAI)
3. 协调世界时(UTC)
4. 夏令时
时区偏移量(Timezone offset)
日期时间显示的格式
国际标准 ISO 8601
Unix 时间戳(POSIX 时间)
Excel 中的日期时间数据
MATLAB 中三种不同的日期时间数据
1. datetime数组
2. duration数组
3. calendarDuration数组
日期时间数据的运算
日期时间数据的比较和排序
日期时间数据的提取和操作
日期时间数据的格式化输出
日期时间数据的时区转换
日期时间数据的特殊处理
日期时间数据的性能优化
日期时间数据的常见应用场景
1. 时间序列分析
2. 事件记录和查询
3. 时间差计算
日期时间数据的注意事项
8.3.2 时间点(时刻)、持续时间和日历持续时间
1. 时间点(时刻) - Datetime Array
2. 时间点数组的属性
3. 提取日期时间分量
4. 使用 duration 函数创建持续时间数组
5. 使用 years、days、hours 等函数创建持续时间数组
6. 时间点数组和持续时间数组的运算方法
7. 日历持续时间数组(Calendar Duration Array)
8. 生成时间点或对时间点进行推移
9. 综合练习题: 空气质量数据分析
8.3.3 常用的配套函数
ymd函数
hms函数
datevec函数
string函数
timeofday函数
isregular函数
yyyymmdd函数
综合应用示例
8.3 日期时间数组
8.3.1日期时间数据的基础知识
知识点 | 说明 | 语法示例 | 相关特性 |
基本概念 | 日期时间型数据具有灵活的显示格式和高达毫微秒的精度,可以处理时区、夏令时和平闰年等特殊因素1 | - | 支持多种时间表示方式,精度高 |
创建日期时间数组 | 使用datetime函数创建表示日期和时间的数组,有多种创建方式2 | t = datetime() | 不带参数时创建当前日期时间的数组 |
时区处理 | MATLAB支持IANA时区数据库,可以处理全球各时区的时间转换56 | t = datetime('now','TimeZone','Asia/Shanghai') | 可以显示所有IANA时区列表及与UTC的偏移量 |
日期时间显示格式 | datetime数组有Format属性,可控制显示方式10 | t.Format = 'yyyy-MM-dd HH:mm:ss' | 支持自定义格式,符合ISO 8601等国际标准 |
日期时间计算 | 支持算术运算、排序、比较,结果在duration数组中返回9 | diff = t2 - t1 | 可以进行加减运算,支持各种时间单位 |
Unix时间戳转换 | Unix时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数8 | t = datetime(0,'ConvertFrom','posixtime') | MATLAB提供与Unix时间戳的相互转换功能 |
Excel日期时间转换 | MATLAB提供与Excel日期数字的转换功能4 | e = exceltime(t) | 支持与Excel日期数字格式的相互转换 |
数据读取与处理 | 可以从Excel等文件中读取日期时间数据3 | [~,~,c]=xlsread('aaa.xlsx') | 支持从外部文件导入日期时间数据并处理 |
日期时间函数 | 提供多种日期时间处理函数 | year(t), month(t), day(t) | 可以提取日期时间的各个组成部分 |
MATLAB中的日期时间数据具有灵活的显示格式和高达纳秒级的精度,能够处理时区、夏令时、闰年等复杂情况。
在MATLAB中,日期时间数据主要用于时间序列分析、事件记录、数据可视化等场景。
时区的概念
时区是地球表面按经度划分的24个区域,每个区域使用统一的时间标准。
MATLAB支持IANA时区数据库,可以处理全球各时区的时间转换。
示例
% 创建带时区的datetime对象dt = datetime('now', 'TimeZone', 'America/New_York')% 创建不同时区的当前时间dt_beijing = datetime('now', 'TimeZone', 'Asia/Shanghai')dt_newyork = datetime('now', 'TimeZone', 'America/New_York')dt_london = datetime('now', 'TimeZone', 'Europe/London')% 显示时区信息fprintf('北京时间: %s\n', string(dt_beijing))fprintf('纽约时间: %s\n', string(dt_newyork))fprintf('伦敦时间: %s\n', string(dt_london))
世界时、国际原子时、协调世界时(UTC)和夏令时
1. 世界时(UT)
基于地球自转的时间标准,MATLAB中可以通过指定'UTC'时区来使用。
2. 国际原子时(TAI)
基于原子钟的时间标准,MATLAB不直接支持TAI,但可以通过转换实现。
3. 协调世界时(UTC)
MATLAB中默认使用UTC作为参考时间标准。
4. 夏令时
MATLAB自动处理夏令时转换。
语法
% 创建UTC时间dt_utc = datetime('now', 'TimeZone', 'UTC')% 检查是否处于夏令时isDST = dt_utc.TimeZone == 'America/New_York' && ...datetime('now', 'TimeZone', 'America/New_York').TimeZone.DST
举例
% 创建UTC时间utc_time = datetime('2023-07-15 12:00:00', 'TimeZone', 'UTC')% 转换为不同时区(自动处理夏令时)ny_time = datetime(utc_time, 'TimeZone', 'America/New_York')london_time = datetime(utc_time, 'TimeZone', 'Europe/London')fprintf('UTC时间: %s\n', string(utc_time))fprintf('纽约时间: %s\n', string(ny_time))fprintf('伦敦时间: %s\n', string(london_time))
时区偏移量(Timezone offset)
时区偏移量表示某个时区与UTC的时间差,通常以小时为单位。
语法
% 获取时区偏移量offset = dt.TimeZone.UTCOffset
举例
% 获取不同时区的偏移量dt_beijing = datetime('now', 'TimeZone', 'Asia/Shanghai')dt_newyork = datetime('now', 'TimeZone', 'America/New_York')beijing_offset = hours(dt_beijing.TimeZone.UTCOffset)newyork_offset = hours(dt_newyork.TimeZone.UTCOffset)fprintf('北京时区偏移量: %.1f小时\n', beijing_offset)fprintf('纽约时区偏移量: %.1f小时\n', newyork_offset)
日期时间显示的格式
MATLAB提供了多种日期时间显示格式,可以使用默认格式或自定义格式。
语法
% 使用默认格式显示dt = datetime('now')% 使用自定义格式显示dt_formatted = datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss.SSS')
举例
% 创建datetime对象dt = datetime('2023-07-15 14:30:45.123')% 不同格式显示format1 = datestr(dt, 'yyyy-mm-dd HH:MM:SS')format2 = datestr(dt, 'dd-mmm-yyyy')format3 = datestr(dt, 'mm/dd/yyyy')fprintf('格式1: %s\n', format1)fprintf('格式2: %s\n', format2)fprintf('格式3: %s\n', format3)% 使用datetime的Format属性dt.Format = 'dd-MMM-yyyy HH:mm:ss'fprintf('自定义格式: %s\n', string(dt))
国际标准 ISO 8601
ISO 8601是国际标准化组织制定的日期和时间表示方法标准。
语法
% 创建ISO 8601格式的datetimedt = datetime('2023-07-15T14:30:45', 'InputFormat', 'yyyy-MM-dd''T''HH:mm:ss')
举例
% 从ISO 8601字符串创建datetimeiso_string = '2023-07-15T14:30:45Z'dt = datetime(iso_string, 'InputFormat', 'yyyy-MM-dd''T''HH:mm:ssX', 'TimeZone', 'UTC')% 转换为ISO 8601格式dt.Format = 'yyyy-MM-dd''T''HH:mm:ssXXX'fprintf('ISO 8601格式: %s\n', string(dt))
Unix 时间戳(POSIX 时间)
Unix时间戳是从1970年1月1日00:00:00 UTC开始所经过的秒数。
语法
% Unix时间戳转换为datetimedt = datetime(unix_time, 'ConvertFrom', 'posixtime')% datetime转换为Unix时间戳unix_time = posixtime(dt)
举例
% 当前时间的Unix时间戳current_unix_time = posixtime(datetime('now', 'TimeZone', 'UTC'))fprintf('当前Unix时间戳: %f\n', current_unix_time)% Unix时间戳转换为datetimeunix_time = 1689413445;dt = datetime(unix_time, 'ConvertFrom', 'posixtime', 'TimeZone', 'UTC')fprintf('Unix时间戳 %f 对应的UTC时间: %s\n', unix_time, string(dt))
Excel 中的日期时间数据
Excel使用序列日期值表示日期,其中1900年1月1日为序列值1。
语法
% Excel日期转换为MATLAB datetimedt = datetime(excel_date, 'ConvertFrom', 'excel')% datetime转换为Excel日期excel_date = exceltime(dt)
举例
% Excel日期转换为MATLAB datetimeexcel_date = 45100; % Excel中的日期序列值dt = datetime(excel_date, 'ConvertFrom', 'excel')fprintf('Excel日期 %d 对应的日期: %s\n', excel_date, string(dt))% 当前日期转换为Excel日期current_excel_date = exceltime(datetime('today'))fprintf('今天的Excel日期值: %f\n', current_excel_date)
MATLAB 中三种不同的日期时间数据
1. datetime数组
最现代、功能最全面的日期时间数据类型。
语法
% 创建datetime数组dt = datetime('now')% 创建datetime数组dt_array = datetime(2023, 7, 15:17, 14, 30, 0)
举例
% 创建单个datetimedt_single = datetime('2023-07-15 14:30:00')% 创建datetime数组dt_array = [datetime('2023-07-15'), datetime('2023-07-16'), datetime('2023-07-17')]% 创建带时间的datetime数组dt_time_array = datetime(2023, 7, 15, [0 6 12 18], 0, 0)% 显示结果disp('单个datetime:')disp(dt_single)disp('datetime数组:')disp(dt_array)disp('带时间的datetime数组:')disp(dt_time_array)
2. duration数组
表示时间长度或持续时间。
语法
% 创建durationdur = duration(1, 30, 45) % 1小时30分45秒% 创建duration数组dur_array = duration([1 2 3], [30 45 0], [45 30 15])
举例
% 创建单个durationdur_single = duration(1, 30, 45)% 创建duration数组dur_array = duration([1 2 3], [30 45 0], [45 30 15])% 进行duration运算dur_sum = dur_single + duration(0, 30, 15)dur_diff = dur_array(2) - dur_array(1)% 显示结果disp('单个duration:')disp(dur_single)disp('duration数组:')disp(dur_array)disp('duration运算结果:')disp(dur_sum)disp(dur_diff)
3. calendarDuration数组
表示日历上的时间长度,考虑不同月份的天数差异。
语法
% 创建calendarDurationcal_dur = calyears(1) + calmonths(2) + caldays(15)% 创建calendarDuration数组cal_dur_array = [calyears(1), calmonths(2), caldays(15)]
举例
% 创建单个calendarDurationcal_dur_single = calyears(1) + calmonths(2) + caldays(15)% 创建calendarDuration数组cal_dur_array = [calyears(1), calmonths(2), caldays(15)]% 与datetime进行运算dt = datetime('2023-07-15')dt_future = dt + cal_dur_single% 显示结果disp('单个calendarDuration:')disp(cal_dur_single)disp('calendarDuration数组:')disp(cal_dur_array)disp('与datetime运算结果:')disp(dt_future)
日期时间数据的运算
% datetime之间的差值time_diff = dt2 - dt1% datetime与duration的加减dt_new = dt + dur% datetime与calendarDuration的加减dt_new = dt + cal_dur% 创建datetime对象dt1 = datetime('2023-07-15 14:00:00')dt2 = datetime('2023-07-15 16:30:00')% 计算时间差time_diff = dt2 - dt1fprintf('时间差: %s\n', string(time_diff))% 创建durationdur = hours(2) + minutes(30)% datetime与duration运算dt3 = dt1 + durfprintf('dt1 + duration: %s\n', string(dt3))% 创建calendarDurationcal_dur = calmonths(1) + caldays(15)% datetime与calendarDuration运算dt4 = dt1 + cal_durfprintf('dt1 + calendarDuration: %s\n', string(dt4))
日期时间数据的比较和排序
% 比较datetimeis_equal = dt1 == dt2is_before = dt1 < dt2% 排序datetime数组sorted_dt = sort(dt_array)% 创建datetime数组dt_array = [datetime('2023-07-17'), datetime('2023-07-15'), datetime('2023-07-16')]% 比较datetimeis_equal = dt_array(1) == dt_array(2)is_before = dt_array(1) < dt_array(2)fprintf('dt_array(1) == dt_array(2): %d\n', is_equal)fprintf('dt_array(1) < dt_array(2): %d\n', is_before)% 排序datetime数组sorted_dt = sort(dt_array)disp('排序前的datetime数组:')disp(dt_array)disp('排序后的datetime数组:')disp(sorted_dt)
日期时间数据的提取和操作
% 提取datetime的各个部分year = year(dt)month = month(dt)day = day(dt)hour = hour(dt)minute = minute(dt)second = second(dt)% 修改datetime的各个部分dt_new = datetime(year(dt), month(dt), day(dt), hour(dt), minute(dt), second(dt))% 创建datetime对象dt = datetime('2023-07-15 14:30:45.123')% 提取datetime的各个部分yr = year(dt)mn = month(dt)dy = day(dt)hr = hour(dt)min = minute(dt)sec = second(dt)ms = millisecond(dt)fprintf('年份: %d\n', yr)fprintf('月份: %d\n', mn)fprintf('日期: %d\n', dy)fprintf('小时: %d\n', hr)fprintf('分钟: %d\n', min)fprintf('秒钟: %d\n', sec)fprintf('毫秒: %d\n', ms)% 修改datetime的各个部分dt_new = datetime(yr, mn, dy, hr+1, min, sec)fprintf('修改后的datetime: %s\n', string(dt_new))
日期时间数据的格式化输出
% 使用datestr函数格式化输出formatted_str = datestr(dt, 'yyyy-mm-dd HH:MM:SS')% 使用datetime的Format属性dt.Format = 'dd-mmm-yyyy HH:MM:SS.FFF'% 创建datetime对象dt = datetime('2023-07-15 14:30:45.123')% 使用datestr函数格式化输出format1 = datestr(dt, 'yyyy-mm-dd HH:MM:SS')format2 = datestr(dt, 'dd-mmm-yyyy')format3 = datestr(dt, 'mm/dd/yyyy HH:MM:SS.FFF')fprintf('datestr格式1: %s\n', format1)fprintf('datestr格式2: %s\n', format2)fprintf('datestr格式3: %s\n', format3)% 使用datetime的Format属性dt.Format = 'dd-mmm-yyyy HH:MM:SS.FFF'fprintf('datetime.Format: %s\n', string(dt))
日期时间数据的时区转换
% 转换时区dt_new = datetime(dt, 'TimeZone', 'New_TimeZone')举例:% 创建带时区的datetimedt_utc = datetime('2023-07-15 14:30:00', 'TimeZone', 'UTC')% 转换为不同时区dt_beijing = datetime(dt_utc, 'TimeZone', 'Asia/Shanghai')dt_newyork = datetime(dt_utc, 'TimeZone', 'America/New_York')dt_london = datetime(dt_utc, 'TimeZone', 'Europe/London')fprintf('UTC时间: %s\n', string(dt_utc))fprintf('北京时间: %s\n', string(dt_beijing))fprintf('纽约时间: %s\n', string(dt_newyork))fprintf('伦敦时间: %s\n', string(dt_london))
日期时间数据的特殊处理
% 处理闰年is_leap = isleap(year(dt))% 处理月末eom = eomdate(year(dt), month(dt))% 处理工作日is_weekday = isweekday(dt)next_workday = busdate(dt, 1)% 创建datetime对象dt = datetime('2023-07-15')% 处理闰年yr = year(dt)is_leap = isleap(yr)fprintf('%d年是闰年: %d\n', yr, is_leap)% 处理月末eom = datetime(eomdate(yr, month(dt)), 'ConvertFrom', 'datenum')fprintf('%d年%d月的月末: %s\n', yr, month(dt), string(eom))% 处理工作日is_weekday = isweekday(dt)next_workday = busdate(dt, 1);next_workday_dt = datetime(next_workday, 'ConvertFrom', 'datenum')fprintf('%s是工作日: %d\n', string(dt), is_weekday)fprintf('下一个工作日: %s\n', string(next_workday_dt))
日期时间数据的性能优化
% 预分配datetime数组dt_array = datetime(zeros(1000, 1));% 使用向量化操作dt_array = datetime(2023, 7, 15:814);% 预分配datetime数组n = 1000;dt_array = datetime(zeros(n, 1));% 填充datetime数组for i = 1:ndt_array(i) = datetime('2023-07-15') + days(i-1);end% 使用向量化操作(更高效)dt_array_vectorized = datetime(2023, 7, 15:1014);% 显示前5个元素disp('循环创建的datetime数组前5个元素:')disp(dt_array(1:5))disp('向量化创建的datetime数组前5个元素:')disp(dt_array_vectorized(1:5))
日期时间数据的常见应用场景
1. 时间序列分析
% 创建时间序列time_points = datetime('2023-01-01') + calmonths(0:11);values = rand(12, 1);% 绘制时间序列图plot(time_points, values)xlabel('时间')ylabel('值')title('时间序列图')
2. 事件记录和查询
% 创建事件记录events = table(...[datetime('2023-07-15 09:00:00'); datetime('2023-07-15 14:30:00'); datetime('2023-07-16 10:15:00')], ...['会议'; '报告'; '培训'], ...'VariableNames', {'时间', '事件'});% 查询特定日期的事件target_date = datetime('2023-07-15');daily_events = events(events.时间.Date == target_date, :);disp(daily_events)
3. 时间差计算
% 计算项目持续时间start_date = datetime('2023-01-01');end_date = datetime('2023-07-15');project_duration = end_date - start_date;fprintf('项目持续时间: %d天\n', days(project_duration))
日期时间数据的注意事项
在进行跨时区计算时,确保所有datetime对象都有正确的时区设置。
MATLAB的datetime数据类型支持纳秒级精度,但在实际应用中要注意浮点数精度限制。
对于大规模日期时间数据处理,尽量使用向量化操作而非循环。
在与其他系统交换日期时间数据时,注意使用标准格式如ISO 8601。
MATLAB会自动处理夏令时转换,但在涉及历史数据时要注意夏令时规则的变化。
8.3.2 时间点(时刻)、持续时间和日历持续时间
知识点 | 说明 | 语法示例 | 相关特性 |
时间点(时刻) | 表示特定的时刻,如"2023年10月1日15:30:00" | t = datetime('2023-10-01 15:30:00') | 支持多种创建方式,可设置时区 |
时间点数组的属性 | Datetime数组是面向对象的数据类型,具有多种属性 | t.Format = 'yyyy-MM-dd HH:mm:ss' | 可控制显示格式和时区 |
提取日期时间分量 | 从时间点数组中提取各种日期时间分量 | year(t) | 可提取年、月、日、星期、季度等 |
duration函数创建持续时间 | 表示固定长度的时间间隔,不受日历规则影响 | d = duration(2, 30, 45) | 精确的时间长度,不随日历规则变化 |
特定函数创建持续时间 | 使用years、days、hours等函数创建持续时间 | d = days(365) | 提供直观的时间单位创建方式 |
时间点和持续时间的运算 | 时间点数组和持续时间数组可以进行各种数学运算 | t + d | 支持加减运算和比较运算 |
日历持续时间 | 基于日历规则的时间间隔,考虑日历复杂性 | cd = calendarDuration(1, 2, 15) | 考虑不同月份天数、闰年等日历规则 |
生成时间点或推移时间点 | 生成时间点序列或对时间点进行推移 | tArray = start:step:end | dateshift函数是重要工具 |
空气质量数据分析 | 综合应用日期时间处理、时间序列分析和数据可视化 | monthlyAvg = varfun(@mean, airQuality, 'GroupingVariables', {'Year', 'Month'}) | 涉及日期时间处理、分组计算、趋势分析等 |
1. 时间点(时刻) - Datetime Array
时间点表示特定的时刻,如"2023年10月1日15:30:00"。
MATLAB中使用datetime数组表示时间点,它是一个面向对象的数据类型,具有属性和方法。
语法
% 创建时间点数组t = datetime() % 当前时间t = datetime('now') % 当前时间t = datetime(2023,10,1) % 指定日期t = datetime(2023,10,1,15,30,0) % 指定日期时间t = datetime('2023-10-01 15:30:00') % 从字符串创建
举例
% 创建当前时间nowTime = datetime()% 创建指定时间specificTime = datetime(2023,10,1,15,30,0)% 从字符串数组创建时间点strTimes = ["2023-01-01"; "2023-02-01"; "2023-03-01"]timeArray = datetime(strTimes)% 创建带时区的时间点timeWithZone = datetime('now', 'TimeZone', 'Asia/Shanghai')
2. 时间点数组的属性
Datetime数组是面向对象的数据类型,具有多种属性可以控制其行为和显示方式。
面向对象编程是一种将数据和处理数据的方法封装在一起的编程范式。
语法
% 查看和设置时间点数组的属性t.Format % 获取或设置显示格式t.TimeZone % 获取或设置时区t.Year % 获取年份t.Month % 获取月份t.Day % 获取日期
举例
% 创建时间点t = datetime('2023-10-01 15:30:00')% 查看和设置格式disp(t.Format) % 显示当前格式t.Format = 'yyyy-MM-dd HH:mm:ss' % 设置新格式disp(t) % 显示新格式的时间% 查看和设置时区t.TimeZone = 'UTC'; % 设置为UTC时区t.TimeZone = 'Asia/Shanghai'; % 设置为上海时区% 访问属性year = t.Year % 获取年份month = t.Month % 获取月份day = t.Day % 获取日期
3. 提取日期时间分量
可以从时间点数组中提取各种日期时间分量,如年、月、日、时、分、秒、星期几、第几周、季度值等。
语法
% 提取日期时间分量year(t) % 年份month(t) % 月份day(t, 'dayofmonth') % 月份中的日期day(t, 'dayofweek') % 星期几(1-7,1为星期日)day(t, 'dayofyear') % 一年中的第几天week(t) % 一年中的第几周quarter(t) % 季度值(1-4)hour(t) % 小时minute(t) % 分钟second(t) % 秒
举例
% 创建时间点数组t = datetime('2023-10-01 15:30:45')% 提取各种分量y = year(t) % 2023m = month(t) % 10d = day(t, 'dayofmonth') % 1wd = day(t, 'dayofweek') % 1 (星期日)yd = day(t, 'dayofyear') % 274w = week(t) % 40q = quarter(t) % 4h = hour(t) % 15min = minute(t) % 30s = second(t) % 45% 对时间点数组提取分量tArray = datetime([2023;2024], [1;1], [1;1])years = year(tArray) % [2023; 2024]quarters = quarter(tArray) % [1; 1]
4. 使用 duration 函数创建持续时间数组
持续时间表示固定长度的时间间隔,如"2小时30分钟"。MATLAB中使用duration数组表示持续时间,它不受日历规则(如闰年、闰秒)的影响。
语法
% 创建持续时间数组d = duration(h, m, s) % 小时、分钟、秒d = duration(h, m, s, 'Format', format) % 指定格式d = hours(n) % n小时d = minutes(n) % n分钟d = seconds(n) % n秒d = milliseconds(n) % n毫秒
举例
% 使用duration函数创建d1 = duration(2, 30, 45) % 2小时30分钟45秒% 指定格式d2 = duration(2, 30, 45, 'Format', 'hh:mm:ss.SSS')% 使用特定函数创建d3 = hours(2.5) % 2.5小时d4 = minutes(150) % 150分钟d5 = seconds(9000) % 9000秒d6 = milliseconds(9000000) % 9000000毫秒% 创建持续时间数组dArray = duration([1; 2], [30; 45], [0; 30]) % [1小时30分钟0秒; 2小时45分钟30秒]
5. 使用 years、days、hours 等函数创建持续时间数组
MATLAB提供了多种函数来创建特定单位的持续时间数组,如years、days、hours、minutes、seconds等。
语法
% 创建特定单位的持续时间d = years(n) % n年d = days(n) % n天d = hours(n) % n小时d = minutes(n) % n分钟d = seconds(n) % n秒
举例
% 创建各种单位的持续时间dYears = years(2) % 2年dDays = days(365) % 365天dHours = hours(24) % 24小时dMinutes = minutes(60) % 60分钟dSeconds = seconds(3600) % 3600秒% 创建数组dYearsArray = years([1; 2; 3]) % [1年; 2年; 3年]dDaysArray = days([30; 60; 90]) % [30天; 60天; 90天]
6. 时间点数组和持续时间数组的运算方法
时间点数组和持续时间数组可以进行各种数学运算,如加减运算、比较运算等。
这些运算在时间序列分析、事件时间计算等场景中非常有用。
语法
% 时间点和持续时间的运算t + d % 时间点加上持续时间t - d % 时间点减去持续时间t2 - t1 % 两个时间点相减得到持续时间d1 + d2 % 两个持续时间相加d1 - d2 % 两个持续时间相减d * n % 持续时间乘以标量d / n % 持续时间除以标量
举例
% 创建时间点和持续时间t1 = datetime('2023-01-01')t2 = datetime('2023-12-31')d = days(100)% 运算示例t3 = t1 + d % 2023-01-01加上100天t4 = t2 - d % 2023-12-31减去100天dDiff = t2 - t1 % 两个时间点之间的持续时间% 持续时间运算d1 = days(50)d2 = hours(24)dSum = d1 + d2 % 50天加24小时dProduct = d1 * 2 % 50天乘以2dQuotient = d1 / 2 % 50天除以2% 比较运算tf = t3 > t1 % 比较时间点tf2 = d1 > d2 % 比较持续时间% 国赛2023年C题应用示例% 假设有一个时间序列数据,表示某地区每天的温度dates = datetime(2023,1,1) + caldays(0:364); % 2023年全年日期temperatures = randn(365,1) * 5 + 20; % 随机生成温度数据% 计算每7天的平均温度weeklyAvg = movmean(temperatures, 7);% 找出温度超过25度的日期hotDays = dates(temperatures > 25);% 计算高温持续天数hotSpells = diff(find([0; temperatures > 25; 0]));maxHotSpell = max(hotSpells) - 1; % 最长高温持续天数
7. 日历持续时间数组(Calendar Duration Array)
日历持续时间是基于日历规则的时间间隔,如"1个月"或"1年",它会考虑日历的复杂性(如不同月份的天数不同、闰年等)。
MATLAB中使用calendarDuration数组表示日历持续时间。
语法
% 创建日历持续时间cd = calendarDuration(Y, M, D, h, m, s) % 年、月、日、小时、分钟、秒cd = years(n) % n年(日历年)cd = quarters(n) % n季度cd = months(n) % n月cd = weeks(n) % n周cd = days(n) % n天(日历天)
举例
% 创建日历持续时间cd1 = calendarDuration(1, 2, 15) % 1年2个月15天cd2 = calendarDuration(0, 1, 0, 12, 30, 0) % 1个月12小时30分钟0秒% 使用特定函数创建cdYears = years(2) % 2年(日历年)cdQuarters = quarters(4) % 4季度cdMonths = months(6) % 6个月cdWeeks = weeks(2) % 2周cdDays = days(30) % 30天(日历天)% 创建数组cdArray = calendarDuration([1; 2], [3; 4], [0; 15]) % [1年3个月0天; 2年4个月15天]
8. 生成时间点或对时间点进行推移
MATLAB提供了多种方法来生成时间点序列或对时间点进行推移,其中dateshift函数是一个重要的工具,可以将时间点推移到特定的日历单位。
语法
% 生成时间点序列tArray = datetime(start, step, end) % 生成从start到end,步长为step的时间点序列tArray = dateshift(t, 'start', unit) % 将时间点t推移到unit单位的开始tArray = dateshift(t, 'end', unit) % 将时间点t推移到unit单位的结束tArray = dateshift(t, 'next', unit) % 将时间点t推移到下一个unit单位tArray = dateshift(t, 'previous', unit) % 将时间点t推移到上一个unit单位
举例
% 生成时间点序列start = datetime('2023-01-01');end = datetime('2023-12-31');step = caldays(1); % 日历天dailyDates = start:step:end; % 生成2023年全年的日期% 使用dateshift函数t = datetime('2023-10-15 15:30:45');% 推移到特定单位的开始monthStart = dateshift(t, 'start', 'month') % 2023-10-01 00:00:00yearStart = dateshift(t, 'start', 'year') % 2023-01-01 00:00:00dayStart = dateshift(t, 'start', 'day') % 2023-10-15 00:00:00% 推移到特定单位的结束monthEnd = dateshift(t, 'end', 'month') % 2023-10-31 23:59:59yearEnd = dateshift(t, 'end', 'year') % 2023-12-31 23:59:59dayEnd = dateshift(t, 'end', 'day') % 2023-10-15 23:59:59% 推移到下一个或上一个特定单位nextMonday = dateshift(t, 'next', 'Monday') % 下一个星期一prevMonday = dateshift(t, 'previous', 'Monday') % 上一个星期一nextMonth = dateshift(t, 'next', 'month') % 下个月的同一天prevMonth = dateshift(t, 'previous', 'month') % 上个月的同一天% 使用日历持续时间进行推移tPlus1Month = t + calmonths(1) % 加上1个月(日历月)tPlus1Year = t + calyears(1) % 加上1年(日历年)tPlus1Week = t + calweeks(1) % 加上1周(日历周)
9. 综合练习题: 空气质量数据分析
涉及日期时间数据处理、时间序列分析和数据可视化。
% 假设我们有一个包含日期时间和空气质量数据的表格% 创建示例数据dates = datetime(2023,1,1) + caldays(0:364); % 2023年全年日期pm25 = randn(365,1) * 30 + 75; % 随机生成PM2.5数据pm10 = randn(365,1) * 40 + 100; % 随机生成PM10数据so2 = randn(365,1) * 10 + 20; % 随机生成SO2数据no2 = randn(365,1) * 15 + 30; % 随机生成NO2数据% 创建表格airQuality = table(dates, pm25, pm10, so2, no2);% 1. 计算每月的平均空气质量指数% 添加月份和年份列airQuality.Month = month(airQuality.dates);airQuality.Year = year(airQuality.dates);% 按月份分组计算平均值monthlyAvg = varfun(@mean, airQuality, ...'InputVariables', {'pm25', 'pm10', 'so2', 'no2'}, ...'GroupingVariables', {'Year', 'Month'});% 2. 找出空气质量最好和最差的日期% 计算综合空气质量指数(简单加权平均)weights = [0.4, 0.3, 0.15, 0.15]; % PM2.5, PM10, SO2, NO2的权重aqi = airQuality.pm25 * weights(1) + airQuality.pm10 * weights(2) + ...airQuality.so2 * weights(3) + airQuality.no2 * weights(4);airQuality.AQI = aqi;% 找出AQI最小和最大的日期[bestAQI, bestIdx] = min(airQuality.AQI);[worstAQI, worstIdx] = max(airQuality.AQI);bestDay = airQuality.dates(bestIdx);worstDay = airQuality.dates(worstIdx);fprintf('空气质量最好的日期: %s, AQI: %.2f\n', string(bestDay), bestAQI);fprintf('空气质量最差的日期: %s, AQI: %.2f\n', string(worstDay), worstAQI);% 3. 分析空气质量的变化趋势% 计算每周的平均AQIweeklyDates = airQuality.dates(1:7:end);weeklyAQI = mean(reshape(airQuality.AQI, 7, []), 1)';% 绘制趋势图figure;plot(weeklyDates, weeklyAQI, 'b-', 'LineWidth', 2);xlabel('日期');ylabel('空气质量指数(AQI)');title('2023年每周平均空气质量指数变化趋势');grid on;% 4. 分析特定时间段(如春节、国庆节)的空气质量% 假设春节是1月22日,国庆节是10月1日-7日springFestivalStart = datetime(2023,1,22);springFestivalEnd = datetime(2023,1,28);nationalDayStart = datetime(2023,10,1);nationalDayEnd = datetime(2023,10,7);% 提取特定时间段的数据springFestivalData = airQuality(airQuality.dates >= springFestivalStart & ...airQuality.dates <= springFestivalEnd, :);nationalDayData = airQuality(airQuality.dates >= nationalDayStart & ...airQuality.dates <= nationalDayEnd, :);% 计算平均AQIspringFestivalAvg = mean(springFestivalData.AQI);nationalDayAvg = mean(nationalDayData.AQI);fprintf('春节期间平均AQI: %.2f\n', springFestivalAvg);fprintf('国庆节期间平均AQI: %.2f\n', nationalDayAvg);% 5. 预测未来一周的空气质量(简单移动平均法)% 使用最近30天的数据预测recentData = airQuality.AQI(end-29:end);predictedAQI = mean(recentData);% 生成未来一周的日期futureDates = airQuality.dates(end) + caldays(1:7);fprintf('预测未来一周的平均AQI: %.2f\n', predictedAQI);% 6. 分析空气质量与季节的关系% 添加季节列season = zeros(size(airQuality.dates));season(month(airQuality.dates) == 12 | month(airQuality.dates) <= 2) = 1; % 冬季season(month(airQuality.dates) >= 3 & month(airQuality.dates) <= 5) = 2; % 春季season(month(airQuality.dates) >= 6 & month(airQuality.dates) <= 8) = 3; % 夏季season(month(airQuality.dates) >= 9 & month(airQuality.dates) <= 11) = 4; % 秋季airQuality.Season = categorical(season, [1,2,3,4], {'冬季', '春季', '夏季', '秋季'});% 按季节分组计算平均AQIseasonalAvg = varfun(@mean, airQuality, ...'InputVariables', 'AQI', ...'GroupingVariables', 'Season');% 绘制季节性变化图figure;bar(seasonalAvg.Season, seasonalAvg.mean_AQI);xlabel('季节');ylabel('平均空气质量指数(AQI)');title('2023年不同季节的平均空气质量指数');grid on;
8.3.3 常用的配套函数
函数名 | 说明 | 语法示例 | 举例 |
ymd | 以单独的数值数组形式返回时间点数组的年、月和天数值 | [y, m, d] = ymd(t) | t = datetime('2023-10-15'); |
hms | 单独的数值数组形式返回时间点数组或持续时间数组的小时、分钟和秒数值 | [h, m, s] = hms(t) | t = datetime('2023-10-15 14:30:45'); |
datevec | 将时间点数组或持续时间数组转换为数值数组形式 | dv = datevec(t) | t = datetime('2023-10-15 14:30:45'); |
string | 将时间点数组或持续时间数组转换为字符串形式 | s = string(t) | t = datetime('2023-10-15 14:30:45'); |
timeofday | 计算时间点数组中各元素自午夜以来经过的时间 | tod = timeofday(t) | t = datetime('2023-10-15 14:30:45'); |
isregular | 确定输入的时间点数组基于时间单位或日历单位是否规则 | tf = isregular(t) | t = datetime(2023,10,15) + caldays(0:2:6); |
yyyymmdd | 将时间点数组转换为yyyyMMdd格式的数值数组形式 | n = yyyymmdd(t) | t = datetime('2023-10-15'); |
ymd函数
ymd函数用于从datetime数组中提取年、月、日信息,返回三个独立的数值数组。这在需要分别处理日期的各个组成部分时非常有用。
语法
[y, m, d] = ymd(t)
应用场景
当你需要按年份、月份或日期进行数据分组或筛选时,可以使用此函数快速提取相应信息。
hms函数
hms函数用于从datetime或duration数组中提取小时、分钟、秒信息,返回三个独立的数值数组。
语法
[h, m, s] = hms(t)
应用场景
在分析一天内的时间分布模式或计算时间差时特别有用。
datevec函数
datevec函数将datetime或duration数组转换为传统的MATLAB日期向量格式,包含年、月、日、时、分、秒六个元素的数值数组。
语法
dv = datevec(t)
应用场景
与旧版MATLAB代码兼容或需要使用传统日期向量格式的函数时使用。
string函数
string函数将datetime或duration数组转换为字符串形式,便于显示、存储或与其他系统交换数据。
语法
s = string(t)
应用场景
需要将日期时间信息以文本形式输出或保存到文件时使用。
timeofday函数
timeofday函数计算datetime数组中每个时间点自午夜以来经过的时间,返回duration数组。
语法
tod = timeofday(t)
应用场景
分析一天内的时间模式,如交通流量、用电量等随时间变化的规律。
isregular函数
isregular函数检查datetime数组是否按指定的时间单位(如'hour'、'day'、'month'等)规则间隔。
语法
tf = isregular(t, unit)
应用场景
在时间序列分析前验证数据是否均匀采样,这对后续分析很重要。
yyyymmdd函数
yyyymmdd函数将datetime数组转换为YYYYMMDD格式的数值数组,便于存储和比较。
语法
n = yyyymmdd(t)
应用场景
需要将日期压缩为单一数值以便存储或作为数据库键值时使用。
综合应用示例
% 创建示例时间点数组t = datetime('2023-10-15') + hours(0:2:20);% 使用ymd提取年月日[y, m, d] = ymd(t);% 使用hms提取时分秒[h, min, s] = hms(t);% 转换为字符串t_str = string(t);% 计算自午夜以来的时间tod = timeofday(t);% 检查是否规则间隔is_regular = isregular(t, 'hour');% 转换为YYYYMMDD格式n = yyyymmdd(t);% 显示结果disp(['原始时间点: ' t_str(1)]);disp(['年月日: ' num2str(y(1)) '-' num2str(m(1)) '-' num2str(d(1))]);disp(['时分秒: ' num2str(h(1)) ':' num2str(min(1)) ':' num2str(s(1))]);disp(['自午夜时间: ' char(tod(1))]);disp(['是否规则间隔: ' mat2str(is_regular)]);disp(['YYYYMMDD格式: ' num2str(n(1))]);