MATLAB时间与日期的基本操作

7.2  日期和时间元素

本小节将为读者介绍如何对指定日期和时间元素的数值进行提取,另外如何通过datetime的属性来对指定的元素进行赋值。MATLAB提供了如下函数进行元素操作,请见表3-12。

表3-12日期和时间元素提取函数

函 数说 明函 数说 明

year年份minute分钟

hour小时second秒

day日quarter季度数

month月份week星期数

ymd   年月日hms   时分秒

split   将日历时间长度按单位级别分解为数值形式time   将日历时间长度转换为固定时间长度

timeofday将时间点转换为时间长度isdst  检测夏令时元素

isweekend检测是否是周末 tzoffset检测时区,返回和UTC的时差

下面我们举例来说明如何从已有的datetime数组中提取日期和时间元素。然后将会介绍如何对指定元素通过对数组属性的设置来进行修改。

【例3-45】 日期和时间数组元素的提取。

首先创建一个测试用datetime数组。

>> t = datetime('now') + calyears(0:2) +calmonths(0:2) + hours(20:20:60)

t =

  04-Sep-2014 20:42:32   05-Oct-201516:42:32   06-Nov-2016 12:42:32

如果想提取数组中的“年”这一元素,那么只需要使用“.”这一符号加Year属性就可以了。

>> t_years = t.Year

t_years =

       2014        2015        2016

输出的t_years是一个数值数组。

同样的,如果想提取月这一元素,可以通过以下方法:

>> t_months = t.Month

t_months =

     9    10   11

在以上方法之外,用户可以通过函数来对日期和时间的各元素进行检索。例如要检索月份的话,那么就可以通过month函数来实现。

>> m = month(t)

m =

     9    10   11

通过使用month函数而不是Month属性来提取月份的全名:

>> m = month(t,'name')

m =

   'September'    'October'    'November'

同样的也可以使用year,quarter,week,hour,minute和second函数来分别提取时间数组t中的其他元素:

>> w = week(t)

w =

    36    41   46

这里返回的是数据所对应与当年第几周。

使用ymd函数可以同时提取年、月、日三个元素:

>> [y,m,d] = ymd(t)

y =

       2014        2015        2016

m =

     9    10   11

d =

     4     5    6

使用hms函数可以同时提取时、分、秒三个元素:

>> [h,m,s] = hms(t)

h =

    20    16   12

m =

    42    42   42

s =

  32.9365   32.9365   32.9365

【例3-46】 日期和时间数组元素的修改。

对已有时间数组中的元素数值进行修改可以通过“.”加属性名来实现。

改变时间数组t中的年份,令其等于2014:

>> t.Year = 2014

t =

  04-Sep-2014 20:42:32   05-Oct-201416:42:32   06-Nov-2014 12:42:32

将时间数组t中的月份分别改成1月、2月、3月:

>> t.Month = [1,2,3]

t =

  04-Jan-2014 20:42:32   05-Feb-201416:42:32   06-Mar-2014 12:42:32

通过TimeZone属性更改时间数组的时区:

>> t.TimeZone = 'Europe/Berlin';

更改时间数组的显示格式:

>> t.Format = 'dd-MMM-yyyy'

t =

  04-Jan-2014   05-Feb-2014   06-Mar-2014

如果用户在赋值的时候给出的数值超出了正常范围,那么MATLAB会对相应的元素进行正常化处理。例如,日期的正常范围是1-31,如果将范围之外的数值赋值给数组,那么结果如下:

>> t.Day = [-1 1 32]

t =

  30-Dec-2013   01-Feb-2014   01-Apr-2014

这里月份和年份的数值同时做了调整,从而使结果是属于正常范围的。例如这里将January -1, 2014转化成为了December 30, 2013。

7.3  日期和时间计算与绘图

本小节将为读者介绍日期和时间的相关加、减、绘图操作。MATLAB提供了多种函数以供使用,见表3-13。

表3-13日期和时间计算函数

函 数说 明函 数说 明

between日历代数差isdatetime判断是否是datetime数组

caldiff日历连续代数差isduration判断是否是duration数组

dateshift平移日期或者产生日期和时间序列iscalendarduration判断是否是calendar duration数组

isbetween判断元素是否在日期和时间区间内isnat  判断是否是NaT元素(非时间元素)

【例3-47】 日历时间长度与时间数组相加。

将一个日历时间长度数组和日期January31, 2014相加:

>> t1 = datetime(2014,1,31)               % 测试时间数组

t1 =

  31-Jan-2014

>> t2 = t1 + calmonths(1:4)               % 将日历月相加

t2 =

  28-Feb-2014   31-Mar-2014   30-Apr-2014  31-May-2014

结果中的每一个时间点都是当月的最后一天。

使用caldiff 函数可以计算数组中相邻的一对时间点之差:

>> dt = caldiff(t2,'days')             %计算数组各时间点之间的日历天数差

dt =

   31d   30d  31d

从结果中可以看出,连续的几对时间点之间的差都是一个日历月,但是天数并不都是等于31天。

同样的我们可以对年份也进行类似的操作:

>> t2 = t1 + calyears(0:4)                  % 初始测试数组

t2 =

  31-Jan-2014   31-Jan-2015   31-Jan-2016  31-Jan-2017   31-Jan-2018

使用caldiff函数可以计算数组t2中相邻时间点之间的天数差:

>> dt = caldiff(t2,'days')

dt =

   365d   365d  366d   365d

由结果可以看出,并不是每一年的天数都等于365天。

【例3-48】 计算两个日历时间点之间的时间差。

使用between函数可以计算两个日历时间点之间的年、月、日之差。

>> t1 = datetime('today')

t1 =

  02-Apr-2015

>> t2 = t1 + calmonths(0:2) + caldays(4)

t2 =

  06-Apr-2015   06-May-2015   06-Jun-2015

>> dt = between(t1,t2)

dt =

      4d   1mo 4d   2mo 4d

【例3-49】 datetime和duration数组的比较。

本例将为读者演示如何对datetime和duration数组进行比较。用户可以在两个datetime数组之间进行元素对元素的对比,也可以对两个duration数组采用逻辑运算符进行比较,例如>和<。

对比两个datetime数组,两个数组必须具有相同的尺寸或者其中一个是标量。

>> A = datetime(2013,07,26) +calyears(0:2:6)

>> B = datetime(2014,06,01)

A =

  26-Jul-2013   26-Jul-2015   26-Jul-2017  26-Jul-2019

B =

  01-Jun-2014

>> A < B

ans =

     1     0    0     0

在A中的时间早于B中的时间情况下,逻辑运算符<将会返回逻辑值1(true)。

对比一个datetime数组和一个日期字符串:

>> A >= 'September 26, 2014'

ans =

     0     1    1     1

读者还可以对比不同时区的时间。例如比较洛杉矶的September 1, 2014 at 4:00 p.m和同一天的纽约时间5:00p.m:

>> A = datetime(2014,09,01,16,0,0,'TimeZone','America/Los_Angeles',...

   'Format','dd-MMM-yyyy HH:mm:ss Z')

A =

  01-Sep-2014 16:00:00 -0700

>> B =datetime(2014,09,01,17,0,0,'TimeZone','America/New_York',...

   'Format','dd-MMM-yyyy HH:mm:ss Z')

B =

  01-Sep-2014 17:00:00 -0400

>> A < B

ans =

     0

从结果可以看出洛杉矶时间下午4点在纽约时间下午5点之后。

下面我们来对duration数组之间的比较进行演示。

>> A = duration([2,30,30;3,15,0])           %测试数据A

>> B = duration([2,40,0;2,50,0])            %测试数据B

A =

   02:30:30

   03:15:00

B =

   02:40:00

   02:50:00

>> A >= B

ans =

     0

     1

从结果中可以看出,和B相比较,A的第一个元素较短,而第二个元素较长。

如果将一个duration数组和一个数值型的数组进行比较,那么数值型的数组将会被看作是天数(固定每天24小时)。

>> A < [1; 1/24]             % A和【1天1小时】相比较

ans =

     1

     0

使用isbetween函数可以判断某一日期时间是否在一个时间区间内。

首先需要创建时间区间的两个边界时间点:

>> tlower = datetime(2014,08,01)      % 起点

>> tupper = datetime(2014,09,01)      % 终点

tlower =

  01-Aug-2014

tupper =

  01-Sep-2014

然后创建一个datetime数组,然后判断数组是否在所设定的时间区间内。

>> A = datetime(2014,08,21) + calweeks(0:2)

A =

  21-Aug-2014   28-Aug-2014   04-Sep-2014

>> tf = isbetween(A,tlower,tupper)

tf =

     1     1    0

【例3-50】 日期和时间数组的绘图。

首先创建一个datetime数组作为x轴。

>> t = datetime(2014,6,28) + caldays(1:10);

将y轴数据定义一个随机数组,然后绘制曲线。

>> y = rand(1,10);

>> plot(t,y);

得到的结果如图3-8所示。

图3-8 日期数组绘图

在默认情况下,plot函数会基于数据的范围自动选择刻度线。当用户放大或缩小图形时,刻度线会自动随之调整。另外用户还可以自定义刻度线格式,例如通过下面的语句就可以将刻度线定义为日-月-年的格式。

>> plot(t,y,'DatetimeTickFormat','dd-MMM-yyyy')

得到的结果如图3-9所示。

图3-9 指定刻度线格式

对于duration数组来说也可以使用类似的方式进行绘图。

首先创建一个duration数组,例如以30秒为步长,总时间3分钟的一个数组:

>> t = 0:seconds(30):minutes(3);

同时创建随机数组作为y轴数据:

>> y = rand(1,7);

在绘图过程中可以指定横轴刻度均以秒为单位:

>> h = plot(t,y,'DurationTickFormat','s');

得到的结果如图3-10所示。

7.4  日期和时间作为数值和字符

如果用户在使用2014a及以前版本,或者和其他使用之前版本的人共享代码时,这就需要处理存储为双精度数值或字符串形式的日期和时间数据。此外,用数值形式表示的日期和时间还可以适用于一些不接受datetime和duration数据类型的函数。

尽管datetime数组是表达时间点的最佳数据类型,但用户还可以通过以下三种形式来表示日期和时间:

(1)Date String:字符串,例如Thursday, August 23, 2012 9:45:44.946 AM

(2)Date Vector:一个1×6的数值向量,包含了年、月、日、时、分、秒,例如[2012   8    23   9    45    44.946]

(3)Serial Date Number — 一个数值,从January 0, 0000开始计算,例如7.3510e+005

采用元胞数组、矩阵等可以以数组形式存储上述各种类型日期时间数据。

用户可以使用datetime函数将上述类型数据转换为datetime数组。反过来,用户可以分别使用datenum、datevec或datestr函数将datetime数组转换为日期数值、日期向量或者日期字符串类型。

日期字符串就是由表示日期或者时间的字符组成,可以有多种格式,例如下面的字符串都是表示August 23, 2010 at 04:35:42 PM:

'23-Aug-2010 04:35:06 PM'

'Wednesday, August 23'

'08/23/10 16:35'

'Aug 23 16:35:42.946'

用户可以采用12时制或者24时制来进行记录。在记录的字符串中还可以加入连字符、空格、冒号来分割各个元素。例如:

>> d = '23-Aug-2010 16:35:42'

【例3-51】 日期字符串的转换。

使用datetime函数可以将字符串转换为datetime数组。由于输入字符串格式可能有很多种,用户最好指明输入字符串的格式从而提高运行效率。

>> t = datetime(d,'InputFormat','dd-MMM-yyyyHH:mm:ss:')

t =

  23-Aug-2010 16:35:42

尽管日期字符串d和datetime标量t看起来非常相似,但是二者是不相同的。

>> whos d t

  Name      Size            Bytes  Class      Attributes

  t         1x1               121  datetime              

  d         1x20               40  char     

日期向量就是一个1×6的双精度数值的数组,其中的数值除了秒以外都是整数,采用24时制的形式来表示。日期向量采用年月日时分秒的顺序来进行记录。例如[2012  10  24 10  45  07]表示的是10:45:07AM on October 24, 2012。

【例3-52】 日期向量的转换。

使用datetime函数将日期向量[2012  10  24 10  45  07]转换为datetime数组。

>> t = datetime([2012  10 24  10  45 07])   

t =

  24-Oct-2012 10:45:07

连续日期数值表示的是距离计时起点过去了多少天。在MATLAB里面,这个起点日期是January 0, 0000。日期数值通过小数来表示不满一天的情况,例如6 p.m等于0.75天。所以采用日期数值来表示'31-Oct-2003, 6:00 PM' 的话那就是731885.75。

【例3-53】 日期数值的转换。

使用datetime函数将日期数值转换为datetime数组。

>> t =datetime(731885.75,'ConvertFrom','datenum')

t =

  31-Oct-2003 18:00:00

【例3-54】 将datetime数组转换为日期数值。

一些MATLAB函数只接受日期数值输入但并不接受datetime数组输入。如果想要调用这些函数的话,那么就需要将datetime数组转换为日期数值格式,然后再调用函数。例如log函数只接受数值格式输入,不接受datetime数组。

假设用户有一datetime数组表示了一项实验的时间数据:

>> t = datetime('18-Jun-2014') +calmonths(1:4)

t =

  18-Jul-2014   18-Aug-2014   18-Sep-2014  18-Oct-2014

减去实验开始的时间就可以得到该时间点对应的实验所花时间长度:

>> dt = t - '1-Jul-2014'

dt =

   408:00:00   1152:00:00   1896:00:00  2616:00:00

dt是一个duration数组。将dt使用years、days、hours、minutes或seconds转换为统一单位的数值,例如:

>> x = hours(dt)

x =

        408        1152        1896        2616

将此双精度数组输入到log函数中就可以进行相应的计算:

>> y = log(x)

y =

   6.0113    7.0493    7.5475   7.8694

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容