时间和空间是世界存在的两种基本属性,大部分的数据都有特有的通道存储时间信息,用户需要通过获取数据存储的信息,来判断数据的可用性,以及数据在时间上发生的变化。在遥感上,空间数据集合中,时间信息显得更加重要,研究人员需要通过时间信息判断地物类型发生的变化,在时间序列上展开分析。时间都去哪了?是大家要面对的共性问题,今天我们探讨一下,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学习之路不易,大家加油!更多内容,欢迎关注小编的后续分享!