
# 时间宏变量使用解析
在创建表/文件迁移作业时，CDM支持在源端和目的端的以下参数中配置时间宏变量：
- 源端的源目录或文件
- 源端的表名
- "通配符"过滤类型中的目录过滤器和文件过滤器
- "时间过滤"中的起始时间和终止时间
- 分区过滤条件和Where子句
- 目的端的写入目录
- 目的端的表名
 
支持通过宏定义变量表示符"${}"来完成时间类型的宏定义，当前支持两种类型：dateformat和timestamp。
通过时间宏变量+定时执行作业，可以实现数据库增量同步和文件增量同步。
![](https://support.huaweicloud.com/usermanual-dataartsstudio/public_sys-resources/note_3.0-zh-cn.png)
如果配置了时间宏变量，通过DataArts Studio数据开发调度CDM迁移作业时，系统会将时间宏变量替换为"数据开发作业计划启动时间-偏移量"，而不是"CDM作业实际启动时间-偏移量"。
#### dateformat
dateformat支持两种形式的参数：
- dateformat(format) format表示返回日期的格式，格式定义参考"java.text.SimpleDateFormat.java"中的定义。
  例如当前日期为"2017-10-16 09:00:00"，则**"yyyy-MM-dd HH:mm:ss"**表示"2017-10-16 09:00:00"。
  
- dateformat(format, dateOffset, dateType)
  - format表示返回日期的格式。
  
  - dateOffset表示日期的偏移量。
  
  - dateType表示日期的偏移量的类型。 目前dateType支持以下几种类型：SECOND（秒），MINUTE（分钟），HOUR（小时），DAY（天），MONTH（月），YEAR（年）。
    ![](https://support.huaweicloud.com/usermanual-dataartsstudio/public_sys-resources/note_3.0-zh-cn.png)
    其中MONTH（月），YEAR（年）的偏移量类型存在特殊场景：
    - 对于年、月来说，若进行偏移后实际没有该日期，则按照日历取该月最大的日期。
    
    - 不支持在源端和目的端的"时间过滤"参数中的起始时间、终止时间使用年、月的偏移。
      
  
  
  例如当前日期为"2023-03-01 09:00:00"，则：
  - **"** **dateformat(yyyy-MM-dd HH:mm:ss, -1, YEAR)** **"**表示当前时间的前一年，也就是"2022-03-01 09:00:00"。
  
  - **"** **dateformat(yyyy-MM-dd HH:mm:ss, -3, MONTH)** **"**表示当前时间的前三月，也就是"2022-12-01 09:00:00"。
  
  - **"dateformat(yyyy-MM-dd HH:mm:ss, -1, DAY)** **"**表示当前时间的前一天，也就是"2023-02-28 09:00:00"。
  
  - **"dateformat(yyyy-MM-dd HH:mm:ss, -1, HOUR)"**表示当前时间的前一小时，也就是"2023-03-01 08:00:00"。
  
  - **"dateformat(yyyy-MM-dd HH:mm:ss, -1, MINUTE)"**表示当前时间的前一分钟，也就是"2023-03-01 08:59:00"。
  
  - **"** **dateformat(yyyy-MM-dd HH:mm:ss, -1, SECOND)** **"**表示当前时间的前一秒，也就是"2023-03-01 08:59:59"。
   
 
#### timestamp
timestamp支持两种形式的参数：
- timestamp() 返回当前时间的时间戳，即从1970年到现在的毫秒数，如1508078516286。
  
- timestamp(dateOffset, dateType) 返回经过时间偏移后的时间戳，"dateOffset"和"dateType"表示日期的偏移量以及偏移量的类型。
  例如当前日期为"2017-10-16 09:00:00"，则"timestamp(-10, MINUTE)"返回当前时间点10分钟前的时间戳，即"1508115000000"。
  
 
#### 时间变量宏定义具体展示
假设当前时间为"2017-10-16 09:00:00"，时间变量宏定义具体如[表1]所示。
![](https://support.huaweicloud.com/usermanual-dataartsstudio/public_sys-resources/note_3.0-zh-cn.png)
表中示例实际使用时必须嵌在''中使用，比如需要以yyyy-MM-dd格式返回当前时间时，参数为'${dateformat(yyyy-MM-dd)}'。
 表1时间变量宏定义具体展示 
| 宏变量                                         | 含义                                            | 实际显示效果                                                                                                                                              |
|:---|:---|:---|
| ${dateformat(yyyy-MM-dd)}                   | 以yyyy-MM-dd格式返回当前时间。                          | 2017-10-16                                                                                                                                          |
| ${dateformat(yyyy/MM/dd)}                   | 以yyyy/MM/dd格式返回当前时间。                          | 2017/10/16                                                                                                                                          |
| ${dateformat(yyyy_MM_dd HH:mm:ss)}          | 以yyyy_MM_dd HH:mm:ss格式返回当前时间。                 | 2017_10_16 09:00:00                                                                                                                                 |
| ${dateformat(yyyy-MM-dd HH:mm:ss, -1, DAY)} | 以yyyy-MM-dd HH:mm:ss格式返回时间，时间为当前时间的前一天。       | 2017-10-15 09:00:00                                                                                                                                 |
| ${dateformat(yyyy-MM-dd, -1, DAY)} 00:00:00 | 以yyyy-MM-dd HH:mm:ss格式返回时间，时间为当前时间的前一天0点。     | 2017-10-15 00:00:00                                                                                                                                 |
| ${dateformat(yyyy-MM-dd, -1, DAY)} 12:00:00 | 以yyyy-MM-dd HH:mm:ss格式返回时间，时间为当前时间的前一天12点。    | 2017-10-15 12:00:00                                                                                                                                 |
| ${dateformat(yyyy-MM-dd, -N, DAY)} 00:00:00 | 以yyyy-MM-dd HH:mm:ss格式返回时间，时间为当前时间的前N天的0点。    | N为3时： 2017-10-13 00:00:00  |
| ${dateformat(yyyy-MM-dd, -N, DAY)} 12:00:00 | 以yyyy-MM-dd HH:mm:ss格式返回时间，时间为当前时间的前N天的12点。   | N为3时： 2017-10-13 12:00:00 |
| ${timestamp()}                              | 返回当前时间的时间戳，即1970年1月1日（00:00:00 GMT）到当前时间的毫秒数。 | 1508115600000                                                                                                                                       |
| ${timestamp(-10, MINUTE)}                   | 返回当前时间点10分钟前的时间戳。                             | 1508115000000                                                                                                                                       |
| ${timestamp(dateformat(yyyyMMdd))}          | 返回今天0点的时间戳。                                   | 1508083200000                                                                                                                                       |
| ${timestamp(dateformat(yyyyMMdd,-1,DAY))}   | 返回昨天0点的时间戳。                                   | 1507996800000                                                                                                                                       |
| ${timestamp(dateformat(yyyyMMddHH))}        | 返回当前整小时的时间戳。                                  | 1508115600000                                                                                                                                       |
   
#### 路径和表名的时间宏变量
如[图1]所示，如果将：
- 源端的"表名"配置为"CDM_/${dateformat(yyyy-MM-dd)}"。
- 目的端的"写入目录"配置为"/opt/ttxx/${timestamp()}"。
 
经过宏定义转换，这个作业表示：将Oracle数据库的"SQOOP.CDM_20171016"表中数据，迁移到HDFS的"/opt/ttxx/1508115701746"目录中。
图1源表名和写入目录配置为时间宏变量   
![](https://support.huaweicloud.com/usermanual-dataartsstudio/zh-cn_image_0112508240.png "点击放大")
目前也支持一个表名或路径名中有多个宏定义变量，例如"/opt/ttxx/${dateformat(yyyy-MM-dd)}/${timestamp()}"，经过转换后为"/opt/ttxx/2017-10-16/1508115701746"。
#### Where子句中的时间宏变量
以SQOOP.CDM_20171016表为例，该表中存在表示时间的列DS，如[图2]所示。
图2表数据   
![](https://support.huaweicloud.com/usermanual-dataartsstudio/zh-cn_image_0108275444.png)
假设当前时间为"2017-10-16"，要导出前一天的数据（即DS='2017-10-15'），则可以在创建作业时配置"Where子句"为**DS='${dateformat(yyyy-MM-dd,-1,DAY)}'**，即可将符合DS='2017-10-15'条件的数据导出。
#### 时间宏变量和定时任务配合完成增量同步
这里列举两个简单的使用场景：
- 数据库表中存在表示时间的列DS，类型为"varchar(30)"，插入的时间格式类似于"2017-xx-xx"。 定时任务中，重复周期为1天，每天的凌晨0点执行定时任务。配置"Where子句"为**DS='${dateformat(yyyy-MM-dd,-1,DAY)}'**，这样就可以在每天的凌晨0点导出前一天产生的所有数据。
  
- 数据库表中存在表示时间的列time，类型为"Number"，插入的时间格式为时间戳。 定时任务中，重复周期为1天，每天的凌晨0点执行定时任务。配置"Where子句"为**time between ${timestamp(-1,DAY)} and ${timestamp()}**，这样就可以在每天的凌晨0点导出前一天产生的所有数据。
  
其它的配置方式原理相同。
