7.2? 日期和時間元素
本小節(jié)將為讀者介紹如何對指定日期和時間元素的數(shù)值進行提取,另外如何通過datetime的屬性來對指定的元素進行賦值环鲤。MATLAB提供了如下函數(shù)進行元素操作,請見表3-12狱杰。
表3-12日期和時間元素提取函數(shù)
函?數(shù)說?明函?數(shù)說?明
year年份minute分鐘
hour小時second秒
day日quarter季度數(shù)
month月份week星期數(shù)
ymd???年月日hms???時分秒
split???將日歷時間長度按單位級別分解為數(shù)值形式time???將日歷時間長度轉(zhuǎn)換為固定時間長度
timeofday將時間點轉(zhuǎn)換為時間長度isdst??檢測夏令時元素
isweekend檢測是否是周末?tzoffset檢測時區(qū)搬味,返回和UTC的時差
下面我們舉例來說明如何從已有的datetime數(shù)組中提取日期和時間元素。然后將會介紹如何對指定元素通過對數(shù)組屬性的設(shè)置來進行修改。
【例3-45】?日期和時間數(shù)組元素的提取制市。
首先創(chuàng)建一個測試用datetime數(shù)組抬旺。
>> 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
如果想提取數(shù)組中的“年”這一元素,那么只需要使用“.”這一符號加Year屬性就可以了祥楣。
>> t_years = t.Year
t_years =
???????2014??????? 2015??????? 2016
輸出的t_years是一個數(shù)值數(shù)組开财。
同樣的,如果想提取月這一元素误褪,可以通過以下方法:
>> t_months = t.Month
t_months =
???? 9??? 10???11
在以上方法之外责鳍,用戶可以通過函數(shù)來對日期和時間的各元素進行檢索。例如要檢索月份的話兽间,那么就可以通過month函數(shù)來實現(xiàn)历葛。
>> m = month(t)
m =
???? 9??? 10???11
通過使用month函數(shù)而不是Month屬性來提取月份的全名:
>> m = month(t,'name')
m =
???'September'??? 'October'??? 'November'
同樣的也可以使用year,quarter嘀略,week恤溶,hour,minute和second函數(shù)來分別提取時間數(shù)組t中的其他元素:
>> w = week(t)
w =
??? 36??? 41???46
這里返回的是數(shù)據(jù)所對應(yīng)與當年第幾周帜羊。
使用ymd函數(shù)可以同時提取年咒程、月、日三個元素:
>> [y,m,d] = ymd(t)
y =
???????2014??????? 2015??????? 2016
m =
???? 9??? 10???11
d =
???? 4???? 5????6
使用hms函數(shù)可以同時提取時讼育、分帐姻、秒三個元素:
>> [h,m,s] = hms(t)
h =
??? 20??? 16???12
m =
??? 42??? 42???42
s =
??32.9365?? 32.9365?? 32.9365
【例3-46】?日期和時間數(shù)組元素的修改。
對已有時間數(shù)組中的元素數(shù)值進行修改可以通過“.”加屬性名來實現(xiàn)奶段。
改變時間數(shù)組t中的年份饥瓷,令其等于2014:
>> t.Year = 2014
t =
??04-Sep-2014 20:42:32?? 05-Oct-201416:42:32?? 06-Nov-2014 12:42:32
將時間數(shù)組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屬性更改時間數(shù)組的時區(qū):
>> t.TimeZone = 'Europe/Berlin';
更改時間數(shù)組的顯示格式:
>> t.Format = 'dd-MMM-yyyy'
t =
??04-Jan-2014?? 05-Feb-2014?? 06-Mar-2014
如果用戶在賦值的時候給出的數(shù)值超出了正常范圍扛伍,那么MATLAB會對相應(yīng)的元素進行正常化處理词裤。例如刺洒,日期的正常范圍是1-31鳖宾,如果將范圍之外的數(shù)值賦值給數(shù)組,那么結(jié)果如下:
>> t.Day = [-1 1 32]
t =
??30-Dec-2013?? 01-Feb-2014?? 01-Apr-2014
這里月份和年份的數(shù)值同時做了調(diào)整逆航,從而使結(jié)果是屬于正常范圍的鼎文。例如這里將January -1, 2014轉(zhuǎn)化成為了December 30, 2013。
7.3? 日期和時間計算與繪圖
本小節(jié)將為讀者介紹日期和時間的相關(guān)加因俐、減拇惋、繪圖操作。MATLAB提供了多種函數(shù)以供使用抹剩,見表3-13撑帖。
表3-13日期和時間計算函數(shù)
函?數(shù)說?明函?數(shù)說?明
between日歷代數(shù)差isdatetime判斷是否是datetime數(shù)組
caldiff日歷連續(xù)代數(shù)差isduration判斷是否是duration數(shù)組
dateshift平移日期或者產(chǎn)生日期和時間序列iscalendarduration判斷是否是calendar duration數(shù)組
isbetween判斷元素是否在日期和時間區(qū)間內(nèi)isnat??判斷是否是NaT元素(非時間元素)
【例3-47】?日歷時間長度與時間數(shù)組相加。
將一個日歷時間長度數(shù)組和日期January31, 2014相加:
>> t1 = datetime(2014,1,31)?????????????? %?測試時間數(shù)組
t1 =
??31-Jan-2014
>> t2 = t1 + calmonths(1:4)?????????????? %?將日歷月相加
t2 =
??28-Feb-2014?? 31-Mar-2014?? 30-Apr-2014??31-May-2014
結(jié)果中的每一個時間點都是當月的最后一天澳眷。
使用caldiff?函數(shù)可以計算數(shù)組中相鄰的一對時間點之差:
>> dt = caldiff(t2,'days')???????????? %計算數(shù)組各時間點之間的日歷天數(shù)差
dt =
?? 31d?? 30d??31d
從結(jié)果中可以看出胡嘿,連續(xù)的幾對時間點之間的差都是一個日歷月,但是天數(shù)并不都是等于31天钳踊。
同樣的我們可以對年份也進行類似的操作:
>> t2 = t1 + calyears(0:4)????????????????? %?初始測試數(shù)組
t2 =
??31-Jan-2014?? 31-Jan-2015?? 31-Jan-2016??31-Jan-2017?? 31-Jan-2018
使用caldiff函數(shù)可以計算數(shù)組t2中相鄰時間點之間的天數(shù)差:
>> dt = caldiff(t2,'days')
dt =
?? 365d?? 365d??366d?? 365d
由結(jié)果可以看出衷敌,并不是每一年的天數(shù)都等于365天。
【例3-48】?計算兩個日歷時間點之間的時間差拓瞪。
使用between函數(shù)可以計算兩個日歷時間點之間的年缴罗、月、日之差祭埂。
>> 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數(shù)組的比較面氓。
本例將為讀者演示如何對datetime和duration數(shù)組進行比較。用戶可以在兩個datetime數(shù)組之間進行元素對元素的對比蛆橡,也可以對兩個duration數(shù)組采用邏輯運算符進行比較侧但,例如>和<。
對比兩個datetime數(shù)組航罗,兩個數(shù)組必須具有相同的尺寸或者其中一個是標量禀横。
>> 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數(shù)組和一個日期字符串:
>> A >= 'September 26, 2014'
ans =
???? 0???? 1????1???? 1
讀者還可以對比不同時區(qū)的時間柏锄。例如比較洛杉磯的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
從結(jié)果可以看出洛杉磯時間下午4點在紐約時間下午5點之后。
下面我們來對duration數(shù)組之間的比較進行演示复亏。
>> A = duration([2,30,30;3,15,0])?????????? %測試數(shù)據(jù)A
>> B = duration([2,40,0;2,50,0])??????????? %測試數(shù)據(jù)B
A =
?? 02:30:30
?? 03:15:00
B =
?? 02:40:00
?? 02:50:00
>> A >= B
ans =
???? 0
???? 1
從結(jié)果中可以看出趾娃,和B相比較,A的第一個元素較短缔御,而第二個元素較長抬闷。
如果將一個duration數(shù)組和一個數(shù)值型的數(shù)組進行比較,那么數(shù)值型的數(shù)組將會被看作是天數(shù)(固定每天24小時)。
>> A < [1; 1/24]???????????? %?A和【1天1小時】相比較
ans =
???? 1
???? 0
使用isbetween函數(shù)可以判斷某一日期時間是否在一個時間區(qū)間內(nèi)笤成。
首先需要創(chuàng)建時間區(qū)間的兩個邊界時間點:
>> tlower = datetime(2014,08,01)????? %?起點
>> tupper = datetime(2014,09,01)????? %?終點
tlower =
??01-Aug-2014
tupper =
??01-Sep-2014
然后創(chuàng)建一個datetime數(shù)組评架,然后判斷數(shù)組是否在所設(shè)定的時間區(qū)間內(nèi)。
>> 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】?日期和時間數(shù)組的繪圖炕泳。
首先創(chuàng)建一個datetime數(shù)組作為x軸纵诞。
>> t = datetime(2014,6,28) + caldays(1:10);
將y軸數(shù)據(jù)定義一個隨機數(shù)組,然后繪制曲線培遵。
>> y = rand(1,10);
>> plot(t,y);
得到的結(jié)果如圖3-8所示浙芙。
圖3-8?日期數(shù)組繪圖
在默認情況下,plot函數(shù)會基于數(shù)據(jù)的范圍自動選擇刻度線籽腕。當用戶放大或縮小圖形時嗡呼,刻度線會自動隨之調(diào)整。另外用戶還可以自定義刻度線格式皇耗,例如通過下面的語句就可以將刻度線定義為日-月-年的格式南窗。
>> plot(t,y,'DatetimeTickFormat','dd-MMM-yyyy')
得到的結(jié)果如圖3-9所示。
圖3-9?指定刻度線格式
對于duration數(shù)組來說也可以使用類似的方式進行繪圖廊宪。
首先創(chuàng)建一個duration數(shù)組,例如以30秒為步長女轿,總時間3分鐘的一個數(shù)組:
>> t = 0:seconds(30):minutes(3);
同時創(chuàng)建隨機數(shù)組作為y軸數(shù)據(jù):
>> y = rand(1,7);
在繪圖過程中可以指定橫軸刻度均以秒為單位:
>> h = plot(t,y,'DurationTickFormat','s');
得到的結(jié)果如圖3-10所示箭启。
7.4? 日期和時間作為數(shù)值和字符
如果用戶在使用2014a及以前版本,或者和其他使用之前版本的人共享代碼時蛉迹,這就需要處理存儲為雙精度數(shù)值或字符串形式的日期和時間數(shù)據(jù)傅寡。此外,用數(shù)值形式表示的日期和時間還可以適用于一些不接受datetime和duration數(shù)據(jù)類型的函數(shù)北救。
盡管datetime數(shù)組是表達時間點的最佳數(shù)據(jù)類型荐操,但用戶還可以通過以下三種形式來表示日期和時間:
(1)Date String:字符串,例如Thursday, August 23, 2012?9:45:44.946 AM
(2)Date Vector:一個1×6的數(shù)值向量珍策,包含了年托启、月、日攘宙、時屯耸、分、秒蹭劈,例如[2012?? 8??? 23???9??? 45??? 44.946]
(3)Serial Date Number — 一個數(shù)值疗绣,從January 0, 0000開始計算,例如7.3510e+005
采用元胞數(shù)組铺韧、矩陣等可以以數(shù)組形式存儲上述各種類型日期時間數(shù)據(jù)多矮。
用戶可以使用datetime函數(shù)將上述類型數(shù)據(jù)轉(zhuǎn)換為datetime數(shù)組。反過來哈打,用戶可以分別使用datenum塔逃、datevec或datestr函數(shù)將datetime數(shù)組轉(zhuǎn)換為日期數(shù)值讯壶、日期向量或者日期字符串類型。
日期字符串就是由表示日期或者時間的字符組成患雏,可以有多種格式鹏溯,例如下面的字符串都是表示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】?日期字符串的轉(zhuǎn)換匀借。
使用datetime函數(shù)可以將字符串轉(zhuǎn)換為datetime數(shù)組颜阐。由于輸入字符串格式可能有很多種,用戶最好指明輸入字符串的格式從而提高運行效率吓肋。
>> 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的雙精度數(shù)值的數(shù)組是鬼,其中的數(shù)值除了秒以外都是整數(shù)肤舞,采用24時制的形式來表示。日期向量采用年月日時分秒的順序來進行記錄均蜜。例如[2012? 10? 24?10? 45? 07]表示的是10:45:07AM on October 24, 2012李剖。
【例3-52】?日期向量的轉(zhuǎn)換。
使用datetime函數(shù)將日期向量[2012? 10? 24?10? 45? 07]轉(zhuǎn)換為datetime數(shù)組囤耳。
>> t = datetime([2012? 10?24? 10? 45?07])???
t =
??24-Oct-2012 10:45:07
連續(xù)日期數(shù)值表示的是距離計時起點過去了多少天篙顺。在MATLAB里面,這個起點日期是January 0, 0000充择。日期數(shù)值通過小數(shù)來表示不滿一天的情況德玫,例如6 p.m等于0.75天。所以采用日期數(shù)值來表示'31-Oct-2003, 6:00 PM'?的話那就是731885.75椎麦。
【例3-53】?日期數(shù)值的轉(zhuǎn)換宰僧。
使用datetime函數(shù)將日期數(shù)值轉(zhuǎn)換為datetime數(shù)組。
>> t =datetime(731885.75,'ConvertFrom','datenum')
t =
??31-Oct-2003 18:00:00
【例3-54】?將datetime數(shù)組轉(zhuǎn)換為日期數(shù)值观挎。
一些MATLAB函數(shù)只接受日期數(shù)值輸入但并不接受datetime數(shù)組輸入撒桨。如果想要調(diào)用這些函數(shù)的話,那么就需要將datetime數(shù)組轉(zhuǎn)換為日期數(shù)值格式键兜,然后再調(diào)用函數(shù)凤类。例如log函數(shù)只接受數(shù)值格式輸入,不接受datetime數(shù)組普气。
假設(shè)用戶有一datetime數(shù)組表示了一項實驗的時間數(shù)據(jù):
>> t = datetime('18-Jun-2014') +calmonths(1:4)
t =
??18-Jul-2014?? 18-Aug-2014?? 18-Sep-2014??18-Oct-2014
減去實驗開始的時間就可以得到該時間點對應(yīng)的實驗所花時間長度:
>> dt = t - '1-Jul-2014'
dt =
???408:00:00?? 1152:00:00?? 1896:00:00??2616:00:00
dt是一個duration數(shù)組谜疤。將dt使用years、days、hours夷磕、minutes或seconds轉(zhuǎn)換為統(tǒng)一單位的數(shù)值履肃,例如:
>> x = hours(dt)
x =
????????408??????? 1152??????? 1896??????? 2616
將此雙精度數(shù)組輸入到log函數(shù)中就可以進行相應(yīng)的計算:
>> y = log(x)
y =
???6.0113??? 7.0493??? 7.5475???7.8694