公式字段返回类型为日期(非日期时间)时,应该存储为utc时间0点,及相关规则确定
Created by: yinlianghui
需要确认存入到数据库中的字段值是否会带小时分钟值,还是说会存为utc的0点(目前我们普通的非公式的日期字段规则是存为utc的0点)。
关联任务:字段公式 #638 (closed)。
参考sf,结果如下:
- 公式
DATETIMEVALUE('2018-12-12 06:06:08')
将返回utc时间2018-12-12 06:06:08(数据库存的是这个),北京时区的话,将显示为+8小时后的14点06分。 - 公式
DATETIMEVALUE('2018-12-12T06:06:08Z')
或DATETIMEVALUE('2018-12-12 06:06')
将返回空,但是未出现异常且详细记录界面也未异常。 - 公式
DATEVALUE('2018-12-12 06:06:06')
或DATEVALUE('2018-12-12T06:06:06Z')
将会造成公式计算异常(界面),即不支持,正确的写法见下一点。 - 公式
DATEVALUE('2018-12-12')
或DATEVALUE(DATETIMEVALUE('2018-12-12 06:06:08'))
将会返回2018-12-12,数据库中存入的是2018-12-12的utc0点(数据库中未显示小时分,但是变更sf账户时区可能会看到详细界面日期变化,说明数据库存入的是utc的0点)。 - 公式
NOW()
将返回当前utc日期时间值,保存至我们数据库中是utc时间值,并且界面上能正确显示为本地时间值。 - 公式
TODAY()
将返回今天utc0点的日期值,保存至数据库中是utc0点【猜测的,因为没法确定真实保存的值,而且我们公式引擎是这么返回的】,并且界面上能正确显示为本地时间值,今天指向的是当前时间utc值中的日期部分,比如9月30号北京时间凌晨2点的时候,这个公式会返回9月29号(即数据库存的是这天的utc0点)。 - 公式
DATEVALUE(NOW())
效果同上,把当前时间转换成当前日期了,类型为日期。 - 公式
DATEVALUE(TEXT(NOW()))
效果同上。 - 公式
DATETIMEVALUE(TODAY())
将返回当天utc0点值,把当前日期值转换成日期时间值了,类型为日期时间。 - 公式
DATETIMEVALUE(DATEVALUE(NOW()))
效果同上,把当前时间转为日期类型再转为日期时间类型。 - 公式
DATETIMEVALUE(TEXT(TODAY()))
不支持,将返回空值,且公式运行时不会报错。 - 公式
TEXT(TODAY())
将返回当天的日期字符串,比如2020-09-30
, TODAY是按utc时间取日期,这点跟TODAY()
一样。 - 公式
TODAY() + 1
将返回当天日期+1天的日期值,即可以直接用+号运行运算。 - 公式
TODAY() + 0.7
将返回当天的日期值,而不是+1天的日期值,因为日期计算时小数部分会被忽略只取整数部分,公式TODAY() + 1.2
将返回当天日期+1天的日期值。 - 公式
TODAY() + 1.5 + 0.5
或TODAY() + 0.5 + 1.5
将返回当天日期+1天,而不是+2天的日期值,因为日期计算时所有的小数都部分都会被忽略不会累加,正确的写法是用括号让数值先计算:TODAY() + (1.5 + 0.5)
。 - 公式
NOW() + 1.1
将返回当前时间增加1.1天后的时间值,即增加1天2小时24分(1天的0.1)。就是说时间类型是支持小数点计算的,单位是天。 - 公式
T1 - T2
,如果以上两个日期时间字段值之差是 5.52,将意味着两个值分隔 5 天、12 小时(1 天的 0.5)和 28 分钟(1 天的 0.02)。
我们的现状是基本跟上面sf的结果一样,只有以下细节区别:
-
公式
DATETIMEVALUE('2018-12-12 06:06:00')
、DATETIMEVALUE('2018-12-12 06:06')
都会存入ISODate("2018-12-12T06:06:00.000Z")
到数据库,但是sf中该函数只支持第一种写法且结果一样。 -
公式
DATETIMEVALUE('2018-12-12T06:06:08Z')
不支持,返回Invalid Date
进而造成保存时报错,sf也不支持,但是那边会返回空,不报错且详细记录界面也未见异常信息。 -
公式
DATEVALUE('2018-12-12 06:06:06')
、DATEVALUE('2018-12-12T06:06:06Z')
将分别会存入ISODate("2018-12-11T00:00:00.000Z")
和ISODate("2018-12-12T00:00:00.000Z")
到数据库,但是sf中该函数不支持这些写法,因为它只支持不带时间字符串的格式。 -
公式
DATEVALUE('2018-12-12')
或DATEVALUE(DATETIMEVALUE('2018-12-12 06:06:08'))
将存入ISODate("2018-12-12T00:00:00.000Z")
到数据库,跟sf一样。 -
DATETIMEVALUE参数只接受text文本作为参数,这点与sf只授受日期作为参数而不接受文本作为参数正好相反,以下是报错信息,即上面sf对应的公式
DATETIMEVALUE(TODAY())
和DATETIMEVALUE(DATEVALUE(NOW()))
要换成DATETIMEVALUE(TEXT(TODAY()))
和DATETIMEVALUE(TEXT(DATEVALUE(NOW())))
才不会报错。
我们的公式引擎比较要注意的地方是:DATETIMEVALUE不支持带TZ的字符串写法,其返回值本身就按utc值来的,而DATEVALUE是同时支持带TZ和不带TZ字符串两种写法的,而且不带TZ的会按本地时区规则返回日期值(即可能返回前一天的日期值)。
时区问题单独另外建任务了:公式引擎TODAY函数存在时区问题。 #940