ArcGIS中的日期类型有别于其他数据类型,处理起来比较麻烦。本文将从存储、显示、查询、Flex/java调用及转换方面,探讨日期类型的机理并对常见问题进行汇总,希望对读者能有所帮助。
存储
- shapefile或coverage存储的日期格式为:yyyy-mm-dd。需要注意的是,这两种数据类型只能存储日期,不能存储时间,时间部分会被截掉;如果要根据时间做时态数据的显示和分析,请使用geodatabase。
- geodatabase(地理数据库)存储的日期格式为:yyyy-mm-dd hh:mm:ss AM或PM。
- 企业级数据库因数据库而异,可参考此处
显示
ArcMap中日期字段随数据源类型的不同而有所差异,其显示格式取决于系统而不是数据源本身。
可在Windows的系统区域设置(控制面板->区域和语言)中设置ArcMap中的日期显示格式。ArcMap使用系统短日期格式显示日期,使用长时间来显示时间。
查询
在ArcMap中新建shapefile格式的点图层和geodatabase的点图层(FeatureClass)各一个,以便进行测试。下面是其属性表的截图,每个图层中只有两个点,西安和北京,其中geodatabase的点图层中存储了时间信息。
shapefile格式的点图层的属性表
geodatabase中的点图层的属性表
ArcMap中时间字段的查询方法为:"Date" = date '2012-01-10'
ArcGIS Server发布成服务后的查询方法:将点图层通过ArcGIS Server发布成Map Service服务,然后在浏览器输入服务地址,进入Query操作页面。 在Where中输入查询条件(输入1=1,可得到所有内容),在Out Fields中输入*(用于将所有的字段都显示出来,当然也可指定字段),便可以得到查询结果。
查询结果为:
where处的查询语句:
经过测试,对于shapefile格式的数据发布的点图层,以下查询语句都可通过:
Date = date '01-10-2012 00:00:00'
Date = date '01-10-2012"
Date = date '01/10/2012"
Date = date '1/10/2012"
Date = date '1-10-2012"
Date = date '2012-1-10"
对于geodatabase中点图层发布的服务,以下查询语句可通过:
Date = date '01-10-2012 10:10:10'
Date = date '2012-1-05 8:20:20 pm'
Date = date '2012-1-05 20:20:20'
大整数问题:
但是我们发现查询结果中时间字段为一个大整数(Format选择了HTML),网上有服务的查询结果是时间格式(目前不清楚如何发布数据以便在Rest页面中能正确显示为时间而非大整数)。不过我们在代码中调用时通常使用json格式,它返回的都是一个大整数。这个大整数的含义是:自 1970 年 1 月 1 日起已经过的毫秒数(如果晚于1970年1月1日,则为正数,否则为负数)。下文会对大整数的处理进行探讨。
Flex/Java中调用
参见《利用ArcGIS Server REST API实现对Feature的编辑操作》和《Java中调用ArcGIS Server REST API》两篇文章,完成利用ArcGIS REST API获取日期信息。完成对结果的解析后,会得到一个大整数,这里以西安为例,得到的数值是1326190210000。
flex中
Flex中可利用构造函数完成从大整数到日期类型的转换:
var date:Date = new Date(1326190210000).
日期转换为大整数:
第一种:var date1:Number = Date.parse("2012/01/10 18:10:10 GMT+0800");//注意时区
第二种:var date2:Number = Date.UTC(2012,0,10,10,10,10,0);//月份范围是0-11.
利用Rest API实现新增功能时,如需构造时间字段,可将日期类型转成大整数,完成日期的添加。
部分服务也可利用这种形式("Date" : "09\/19\/2009"),但有些不行,赞不清楚原因。
java中
大整数转换为日期:
String str = "1326190210000";
Long lng = Long.parseLong(str);
Date date = new Date(lng);
Long lng = Long.parseLong(str);
Date date = new Date(lng);
日期转换为大整数:
第一种:long lng2 = Date.UTC(2012-1900,0,10,10,10,10);//年数需要减去1900
第二种:Calendar calendar = Calendar.getInstance();
calendar.set(2012,0,10, 18, 10, 10);
calendar.set(Calendar.MILLISECOND, 0);//设置下毫秒为0,否则得到的结果后三位不确定
long lng1 =calendar.getTimeInMillis();
calendar.set(Calendar.MILLISECOND, 0);//设置下毫秒为0,否则得到的结果后三位不确定
long lng1 =calendar.getTimeInMillis();
第三种:Date.parse()和DateFormat类也可以。
如在IOS开发中遇到关于日期类型的问题,可参考下<<关于ArcGIS Runtime SDK for iOS中AGSLayerDefinition使用日期类型字段过滤的问题>>