時間和空間是世界存在的兩種基本屬性,大部分的數據都有特有的通道存儲時間信息,用戶需要通過獲取數據存儲的信息,來判斷數據的可用性,以及數據在時間上發生的變化。在遙感上,空間數據集合中,時間信息顯得更加重要,研究人員需要通過時間信息判斷地物類型發生的變化,在時間序列上展開分析。時間都去哪了?是大家要面對的共性問題,今天我們探討一下,GEE平臺上的日期參數類型。
一、Date參數類型
日期作為GEE的參數類型,共包括兩種,一種指的是特定的日期,一種指的是日期的范圍。先看到Date參數類型。
1.定義日期
老樣子,凡是先定義,GEE上定義一個日期有多種方法,且看:
//定義日期
var date1 = ee.Date("2023-01-01");
print("date1:",date1);
var date2 = ee.Date.parse("YYYYDDD","2023010");
print("date2:",date2);
//var date2 = ee.Date.fromYMD(2020,01,01);
一種是直接采用ee.Date方法定義直接定義日期,方便快捷。一種是利用parse方法,通過指定格式和對應的日期進行創建,//后面給出了第三種方法,采用fromYMD格式,進行日期的格式化創建。
有沒有小伙伴想知道GEE上最早的時間定義的是什么時候,要知道這個,我們不煩耍點小聰明,用24*60*60*1000(h*min*se*mi),這個算式表示的含義是距初始時間一天的時間算式表達方式。
//判斷GEE上最開始的時間加一天的日期是
var Date = ee.Date(24*60*60*1000);
print("Date",Date);
var InitialDate = ee.Date("1970-01-01");
print("IDate",InitialDate);
此時我們會發現一個神奇的現象:
從打印的結果可以看出,時間是1970-01-02,此時我們反推一天,是不是能夠得到GEE平臺上定義的初始時間就是1970-01-01呢?小編寫了個代碼驗證了一下,欸!發現它的value值等于0,說明1970-01-01是初始時間,這是一個神圣的日子,大家要記住。
2.獲取時間單位的占比
如果想知道當前日期在一年中的占比,可以這樣:
//獲取時間單位的比例
var time = ee.Date("2020-03-02");
var fraction = time.getFraction("year");
print(time,fraction,(31+29+2)/366);
此處使用getFraction方法,獲取了該時間在一年中所占的比例,即年份的小數部分,打印時我們手算了一下(2024年是閏年記得哈),對比一下輸出結果:
可以看出,手算和機算之間還是有差別的,這里的結果不一樣是因用前者方法返回的是一個精確的小數值,而手動計算的結果,可能存在四舍五入或者精度損失的情況。因此,兩者的值可能會有微小的差異。
3.獲取前一天或者是后一天的數據
接下來要分享的方法對于時間序列很重要,有時候寫循環,需要讓時間能夠自動實現遞增或者是遞減,也即依據當前日期獲得前一天或者是后一天的日期。
//獲取后一天或者是前一天,單位可以是year,month,week,day,hour,minute,second
var date3 = ee.Date("2024-01-01");
var nextDate = date3.advance(1,"month");
var preDate = date3.advance(-1,"day");
print("nextDate:",nextDate);
print("preDate:",preDate);
要實現上述目標,我們要用到advance方法,該方法兩個參數中,前者是數字,代表日期的遞增步長,后者的字符串代表時間單位,可以是年月日小時分鐘等多種單位,具體應用何種單位要依據各位小可愛的實際研究情境確定。這個一定要記住,以后我們在時間序列分析過程中會經常看到它。
4.獲取日期間隔
知道兩個日期,怎么得到兩個日期之間的間隔?
//日期間隔,單位可以是year,month,week,day,hour,minute,second
var date4 = ee.Date("2024-02-01");
var date5 = ee.Date("2024-02-22");
var gap1 = date5.difference(date4,"day");
var gap2 = date5.difference(date4,"hour");
var gap3 = date5.difference(date4,"week");
print("gap1:",gap1);
print("gap2:",gap2);
print("gap3:",gap3);
間隔采用difference命令,該方法可以指定要計算間隔的時間單位,此處小編以天、小時和周來舉例子,且看代碼的運行結果:
按天來看,兩個日期之間相差21天,按小時來看,21*24=504h,按周來算,21/7 = 3。
5.計算逝去時間
如果想知道想現日期相對于當年以某個特定的時間單位逝去的時間,應該如何做?
//計算當前日期為一年中的第幾天(指定格式,相對于這一年的開始)
var date6 = ee.Date("2024-02-02");
var day1 = date6.getRelative("day","year");
var day2 = date6.getRelative("day","month");
var month = date6.getRelative("month","year");
print("day1:",day1,"day2:",day2,"month:",month);
要實現上述目標,我們需要用到GEE的getRelative,此處小編以一年當中的第幾天,一月當中的第一天,一年當中的第幾月為例子,得到下列結果:
2024年2月2日相對于2024年1月1日是32天,從月份來看,2月2日相對于2月1日是過了一天,2024年2月相對與2024年1月時間過去一個月,因此結果如上,你理解了嘛?
6.按照指定格式獲取日期時間
有時我們只想知道一年,或者某月等的時間,那么只需要想如下:
//按照指定格式獲取日期
var date7 = ee.Date("2024-02-20");
var Day = date7.format("dddd");
var Month = date7.format("MM");
print("Day:",Day,"Month:",Month);
利用format方法,并添上合適的日期格式,小編這里設置的是用4為數字表示天(dddd),用兩位數字表示月份(MM),注意單位是其英文的縮寫,即可得到想要的結果。
7.獲取指定日期的年月日等時間信息
這個就像去字典里面取屬性一般,使用get方法即可:
//獲取日期的年月日等信息
var date8 = ee.Date.parse("yyyy-mm-dd HH:mm:ss","2024-02-22 17:22:48");
print("Year:",date8.get("year"));
print("Month:",date8.get("month"));
print("Week:",date8.get("week"));
print("Day:",date8.get("day"));
print("Hour:",date8.get("hour"));
print("Minute:",date8.get("minute"));
print("Second:",date8.get("second"));
通過上述代碼,能夠得到每一個時間單位存儲的時間信息:
二、DateRange參數類型
聊完了Date類型,我們還要接觸一下時間范圍DateRange的基操。
1.定義時間范圍:
//時間段的定義
var range1 = ee.DateRange("2020-01-01");
var range2 = ee.DateRange("2020-01-01","2020-02-01");
print(range1,range2);
定義日期的時間范圍,采用ee.DateRange即可,小編此處舉了兩個例子,運行的結果如下:
如果只是給定了一個日期,能實現時間范圍的定義嘛?當然,如上導出的結果所示,此時GEE會自動創建一個時間范圍,二者之間相差一個毫秒。第二個時間范圍不用過多解釋,就是形成了一個正常的時間范圍。
2.創建無限時間范圍
小編想創建一個時間范圍,從起始時間開始延申至無限,可以包含任意的時間段,能做到嗎?用unbounded方法,一鍵生成無限時間段:
//創建無限時間段
var range3 = ee.DateRange("1990-01-01","2024-02-01");
var unbound = ee.DateRange.unbounded();
var test = unbound.contains(range3);
print("range3:",range3,"test:",test);
此處unbound變量存儲是定義的無限時間段,信不信它能夠包含定義的長時間范圍range3,且看結果吧!!見證奇跡的時候到了!
測試結果是true,小編沒騙你吧,是無限的時間段。
3.時間段合并
給定任意的兩個時間段可以進行合并嘛?
//時間段的合并
var range4 = ee.DateRange("2020-01-01","2020-02-01");
var range5 = ee.DateRange("2020-04-01","2020-06-01");
var union = range4.union(range5);
print("Union",union);
時間的合并采用的是union方法,該方法能夠聯合兩個時間范圍,無論兩個時間段是首尾相連,彼此有交叉還是相互獨立(本例),union會選擇時間段的最小日期和最大日期進行合并,組成一個更寬的時間段,本代碼結果如下:
4.求時間段交集
如果把剛剛的合并看成是求時間段之間的并集,那么問題來了,給定兩個時間段,我們應該怎么樣得到兩個時間段之間的交集呢?
//時間段的相交
var range6 = ee.DateRange("2020-01-01","2020-04-01");
var range7 = ee.DateRange("2019-12-01","2020-05-27");
var intersection = range6.intersection(range7);
print("Intersection",intersect);
借助intersection方法,我們能夠很方便得到兩個時間段之間的交集,結果如下:
5.判斷時間段的相交與包含與否
在進行上述的求交集等的操作時,我們要判斷時間段之間是否存在相交關系,或者是包含關系,更希望得到一個肯定或者否定的答案,我們可以這樣做:
//時間段的相交與包含與否
var range9 = ee.DateRange("2022-04-01","2022-08-01");
var range10 = ee.DateRange("2022-01-01","2022-06-01");
var intersect = range9.intersects(range10);
var contain = range9.contains(range10);
print("Is Intersect:",intersect,"Is contasin:",contain);
相交關系用intersects,注意區別于前面的intersection方法,包含關系用contains。結果如下:
6.時間段的內容判斷
給定一個錯誤的時間段,如何設置檢查點?
//時間段的內容判斷
var range11 = ee.DateRange("2022-01-01","2012-01-01");
var isempty = range11.isEmpty();
var isunbounded = range11.isUnbounded();
print("isempty:",isempty,"isunbounded",isunbounded);
上面,小編給出了一個錯誤的時間范圍,使用isEmpty方法,如果返回值為true,代表時間范圍為空值,或使用isUnbounded,如果返回值為true,代表無限段時間范圍內包含小編定義的時間段,反之。本代碼得到的結果如下:
7.時間段首末日期的獲取
最后一個方法水一下,什么意思自己理解hhh
//獲取時間段的初始和結尾時間
var range8 = ee.DateRange("2021-06-01","2021-08-01");
var start = range8.start();
var end = range8.end();
關于GEE平臺上擁有的參數類型—時間的學習分享到這里就結束了,希望對大家入門GEE有幫助!
本篇文章代碼鏈接分享:
https://code.earthengine.google.com/8ebb59711931dec387985b1565d7ab39https://code.earthengine.google.com/8ebb59711931dec387985b1565d7ab39
GEE學習之路不易,大家加油!更多內容,歡迎關注小編的后續分享!