日期/时间类型

作为一个时序数据库,DolphinDB 提供了丰富的时间/日期类型,并提供了大量内置函数进行高效的操作。

1. 日期和时间类型

1.1. DolphinDB 时序数据类型

DolphinDB 支持以下九种时序数据类型用于日期、时间的表示:

类型举例符号字节数
DATE2012.06.13d4
MONTH2012.06MM4
TIME13:30:10.008t4
MINUTE13:30mm4
SECOND13:30:10s4
DATETIME2012.06.13 13:30:10 or 2012.06.13T13:30:10D4
TIMESTAMP2012.06.13 13:30:10.008 or 2012.06.13T13:30:10.008T8
NANOTIME09:00:01.000100001n8
NANOTIMESTAMP2016.12.30T09:00:01.000100001N8

1.2. 时序数据在 DolphinDB 的内部表示

在 DolphinDB 内部,时序对象以整型和长整型存储。因此,DolphinDB 的时序对象支持+ - * / %等运算符的操作。其中,运算符+-可以用来调整时间变量的值。

DolphinDB 时序对象与内部整数的转换:

  • 对于日期类型 DATE,在 DolphinDB 存储的整数为从 1970.01.01 开始经过的天数(1970.01.01 在 DolphinDB 内部存储为 0,1970.01.02 在 DolphinDB 内部存储为 1,以此类推)。
  • 对于日期类型 MONTH,在 DolphinDB 存储的整数为(月份 - 1) + 年份 * 12
  • 对于时间类型 MINUTE、SECOND、TIME 和 NANOTIME 的对象,表示这些对象的内部整数的最小值为 0,最大值分别为 1439, 86399,86399999 和 86399999999999。其中,秒、分、时之间以 60 进位,TIME 的毫秒与秒之间以 1000 进位,NANOTIME 的毫微秒与秒之间以 1000000000 进位。
  • DATETIME、TIMESTAMP 和 NANOTIMESTAMP 为日期和时间的组合类型,将以上基本日期、时间类型的转换方法结合,即为组合类型的转换方法。

不同时序对象转换 DolphinDB 内部存储整数的方法和计算结果示例见下表:

类型举例转换公式结果
DATE2012.06.13-15504
MONTH2012.06M(6 - 1) + 2012 * 1224149
MINUTE13:30m30 + 13 * 60810
SECOND13:30:1010 + 30 60 + 13 60 * 6048610
TIME13:30:10.0088 + 10 1000 + 30 60 1000 + 13 60 60 100048610008
NANOTIME09:00:01.000100001100001 + 1 long(1000000000) + 0 60 long(1000000000) + 9 60 60 long(1000000000)32401000100001
DATETIME2012.06.13 13:30:10 or 2012.06.13T13:30:1048610 + 15504 24 60 * 601339594210

在下面的例子中,给定一个整数 1339594210008,表示 DolphinDB 中的 TIMESTAMP,将其转换为 DolphinDB 中的 TIMESTAMP 对象:

  • 日期的计算:

    计算1339594210008 / 86400000可以得到从 1970.01.01 开始经过的天数 15504。通过 DolphinDB C++ API 中头文件 Util.h 定义的静态函数parseDate,传入天数 15504,即可得到对应的年月日分别为 2012,6 和 13。Java API 中 Util.java 也定义了同样的函数。

  • 时间的计算:

    计算1339594210008 % 86400000可以得到时间部分的总毫秒数 48610008。然后,计算48610008 % 1000可以得到 TIMESTAMP 中的毫秒数 8。

    48610008 / 1000可以得到时间部分的总秒数 48610。然后,计算48610 % 60可以得到 TIMESTAMP 中的秒数 10。

    48610 / 60可以得到时间部分的总分钟数 810。然后,计算810 % 60可以得到 TIMESTAMP 中的分钟数 30。

    810 / 60可以得到时间部分的总小时数 13,即为 TIMESTAMP 中的小时数 13。

    因此,将整数 1339594210008 转换为 DolphinDB TIMESTAMP 的结果为:2012.06.13T13:30:10.008。

2. 日期/时间对象类型转换及基本操作

2.1. 时序类型转换函数

使用时序类型转换函数可以将时序数据转换成另一种时序类型的数据。

例子:

>month(2016.02.14);
2016.02M
>date(2012.06.13 13:30:10)
2012.06.13
>second(2012.06.13 13:30:10)
13:30:10
>timestamp(2012.06.13 13:30:10)
2012.06.13T13:30:10.000

2.2. 时区转换函数

DolphinDB 能够自动识别本地时区。DolphinDB 中的时间序列对象不包括时区信息,由用户决定时序对象的时区。通过以下的时区转换函数可以实现时区之间的转换。

  • localtime: 把零时区时间(格林尼治时间)转换成本地时间 以下例子在美国东部时区执行:
>localtime(2018.01.22T15:20:26);
2018.01.22T10:20:26
>localtime(2017.12.16T18:30:10.001);
2017.12.16T13:30:10.001
  • gmtime: 把本地时间转换成零时区时间(格林尼治时间) 以下例子在美国东部时区执行:
>gmtime(2018.01.22 10:20:26);
gmtime(2018.01.22 10:20:26);
>gmtime(2017.12.16T13:30:10.008);
2017.12.16T18:30:10.008
  • convertTZ: 转换任意两个时区的时间 例子:
>convertTZ(2016.04.25T08:25:45,"US/Eastern","Asia/Shanghai");
2016.04.25T20:25:45

2.3. 基本操作

2.3.1. 获取时间变量的部分信息

>year(2016.02.14);
2016
>monthOfYear(2016.02.14);
2
>dayOfMonth(2016.02.14);
14
>x=01:02:03.456;
>hour(x);
1
>minuteOfHour(x);
2
>secondOfMinute(x);
3
>x mod 1000;
456

2.3.2. 使用运算符"+"或"-"来调整时间变量的值

>2016.02M-13;
2015.01M
>2018.02.17+100;
2018.05.28
>01:20:15+200;
01:23:35

如果进行运算调整之后,其中一个表示这些对象的内部整数小于 0 或大于相应的最大值,最终结果是内部整数除以相应的最大值的余数。

>23:59m+10;
00:09m
>00:00:01-2;
23:59:59
>23:59:59.900+200;
00:00:00.100

2.3.3. 以不同的时间单位调整时间变量的值

>temporalAdd(2017.01.16,1,"w");
2017.01.23
>temporalAdd(2016.12M,2,"M");
2017.02M
>temporalAdd(13:30m,-15,"m");
13:15m

2.3.4. 合并日期和时间

>concatDateTime(2019.06.15,13:25:10);
2019.06.15T13:25:10
>concatDateTime(2019.06.15 2019.06.16 2019.06.17,[13:25:10, 13:25:12, 13:25:13]);
[2019.06.15T13:25:10,2019.06.16T13:25:12,2019.06.17T13:25:13]

2.4. 与 DateOffset 相关的函数

  • yearBegin / yearEnd: 获取当年的第一天/最后一天
  • businessYearBegin / businessYearEnd: 获取当年的第一个/最后一个工作日
  • isYearStart / isYearEnd: 判断当天是否为年初第一天/年末最后一天
  • isLeapYear: 判断当年是否为闰年
  • monthBegin / monthEnd: 获取当月的第一天/最后一天
  • buinessMonthBegin / buinessMonthEnd: 获取当月的第一个/最后一个工作日
  • semiMonthBegin / semiMonthEnd: 获取当月开始/结束的第 15(或其他)天
  • isMonthStart / isMonthEnd: 判断当天是否为月初的第一天/月末的最后一天
  • daysInMonth: 获取当月的天数
  • quarterBegin / quarterEnd: 获取当前季度的第一天/最后一天
  • businessQuarterBegin / businessQuarterEnd: 获取当前季度的第一个/最后一个工作日
  • isQuarterStart / isQuarterEnd: 判断当天是否为季度的第一天/最后一天
  • week: 获取当前星期或下一个星期的星期几(默认为星期一)
  • weekBegin: 获取当前星期或上一个星期的星期几(默认为星期一)
  • lastWeekOfMonth: 获取当月或上一个月最后一周的星期几(默认为星期一)
  • weekOfMonth: 获取当月或上一个月第几周的星期几(默认为第一周的星期一)
  • fy5253: 获取当前财年开始的第一天
  • fy5253Quarter: 获取当前财年开始的第一天

2.5. 解析和格式化

  • temporalParse: 把字符串转换成 DolphinDB 中的时序类型数据
>temporalParse("14-02-2018","dd-MM-yyyy");
2018.02.14
>temporalParse("14-02-18","d-M-y");
2018.02.14
>temporalParse("2018/2/6 02:33:01 PM","y/M/d h:m:s a");
2018.02.06T14:33:01
  • temporalFormat: 把 DolphinDB 中的时序对象转换成指定格式的字符串
>temporalFormat(2018.02.14,"dd-MM-yyyy");
14-02-2018
>temporalFormat(2018.02.14,"dd-MMM-yy");
14-FEB-18
>temporalFormat(2018.02.06T13:30:10.001, "y-M-d-H-m-s-SSS");
2018-2-6-13-30-10-001

3. dolphindb-python-api 中日期和时间相关操作

由于 Python pandas 中所有有关时间的数据类型均为 datetime64, DolphinDB 中的所有时间类型数据均会被转换为 datetime64 类型。 MONTH 类型,如 2012.06M,会被转换为 2012-06-01(即当月的第一天)。TIME, MINUTE, SECOND 与 NANOTIME 类型不包含日期信息,转换时会自动添加 1970-01-01,例如 13:30m 会被转换为 1970-01-01 13:30:00。

下表展示了从 DolphinDB 数据库中通过 toDF() 函数下载数据到 Python 时,数据类型的转换:

DolphinDB 类型DolphinDB 数据Python 类型Python 数据
DATE[2012.06.12,date()]datetime64[2012-06-12, NaT]
MONTH[2012.06M,month()]datetime64[2012-06-01, NaT]
TIME[13:10:10.008,time()]datetime64[1970-01-01 13:10:10.008, NaT]
MINUTE[13:30,minute()]datetime64[1970-01-01 13:30:00, NaT]
SECOND[13:30:10,second()]datetime64[1970-01-01 13:30:10, NaT]
DATETIME[2012.06.13 13:30:10,datetime()]datetime64[2012-06-13 13:30:10,NaT]
TIMESTAMP[2012.06.13 13:30:10.008,timestamp()]datetime64[2012-06-13 13:30:10.008,NaT]
NANOTIME[13:30:10.008007006, nanotime()]datetime64[1970-01-01 13:30:10.008007006,NaT]
NANOTIMESTAMP[2012.06.13 13:30:10.008007006,nanotimestamp()]datetime64[2012-06-13 13:30:10.008007006,NaT]

关于时序对象缺失值的处理,DolphinDB 中时序类型的 NULL 值默认情况下会被转换为 NaT(非时间空值,Not a Time)