数据类型

听闻少年二字,当与平庸相斥。这篇文章主要讲述数据类型相关的知识,希望能为你提供帮助。


文章目录

  • ??第四章 数据类型(三)??
  • ??日期、时间、PosixTime 和时间戳数据类型??
  • ??1840 年 12 月 31 日之前的日期??
第四章 数据类型(三) 日期、时间、PosixTime 和时间戳数据类型可以定义日期、时间和时间戳数据类型,并通过标准 SQL 日期和时间函数相互转换日期和时间戳。例如,可以使用 ??CURRENT_DATE??? 或 ??CURRENT_TIMESTAMP??? 作为使用该数据类型定义的字段的输入,或者使用 ??DATEADD???、??DATEDIFF???、??DATENAME??? 或 ??DATEPART?? 来操作使用该数据类型存储的日期值。
数据类型类 ??%Library.Date???、??%Library.Time???、??%Library.PosixTime???、??%Library.TimeStamp??? 和 ??%MV.Date??? 对于 ??SqlCategory?? 的处理方式如下:
  1. ??%Library.Date??? 类以及逻辑值为??+$HOROLOG???(??$HOROLOG??? 的日期部分)的任何用户定义数据类型类都应使用??DATE??? 作为??SqlCategory???。默认情况下,??DATE??? 和对应的??%Library.Date??? 数据类型只接受正整数,??0??? 代表??1840-12-31???。要支持早于??1840-12-31??? 的日期,必须在表中定义数据类型为??%Library.Date(MINVAL=-nnn)??? 的日期字段,其中??MINVAL??? 是从??1840-12-31??? 倒数的负天数最大为?? -672045 (0001-01-01)???。??%Library.Date??? 可以将日期值存储为??-672045??? 到??2980013?? 范围内的无符号或负整数。日期值可以按如下方式输入:
  • 逻辑模式接受??+HOROLOG??? 整数值,例如??65619??(2020 年 8 月 28 日)。
  • 显示模式使用??DisplayToLogical()??? 转换方法。它接受当前语言环境的显示格式的日期,例如??“8/28/2020”???。它还接受逻辑日期值(??+HOROLOG?? 整数值)。
  • ODBC 模式使用??ODBCToLogical()??? 转换方法。它接受 ODBC 标准格式的日期,例如??“2020–08–28”???。它还接受逻辑日期值(??+HOROLOG ??整数值)。
  1. ??%Library.Time??? 类和任何逻辑值为??$PIECE($HOROLOG,”,”,2)??? (??$HOROLOG??? 的时间部分)的用户定义数据类型类都应使用??TIME??? 作为??SqlCategory???。??%Library.Time??? 将时间值存储为??0??? 到??86399?? 范围内的无符号整数(自午夜以来的秒数)。时间值可以按如下方式输入:
  • 逻辑模式接受??$PIECE($HOROLOG,”,”,2)??? 整数值,例如??84444 (23:27:24)??。
  • 显示模式使用??DisplayToLogical()??? 转换方法。它接受当前语言环境的显示格式的时间,例如??“23:27:24”??。
  • ODBC 模式使用??ODBCToLogical()??? 转换方法。它接受 ODBC 标准格式的时间,例如??“23:27:24”???。它还接受逻辑时间值(??0??? 到??86399?? 范围内的整数)。
??TIME??? 支持小数秒,因此此数据类型也可用于 ??HH:MI:SS.FF??? 到用户指定的精度 (F) 小数位数,最多为 ??9???。要支持小数秒,请设置 ??PRECISION???范围。例如,??TIME(0) (%Time(PRECISION=0))??? 舍入到最接近的秒数;??TIME(2) (%Time(PRECISION=2))?? 将(或零填充)四舍五入到精度的两位小数。
如果提供的数据还指定了精度(例如,??CURRENT_TIME(3)??),则存储的小数位数如下:
  • 如果??TIME?? 未指定精度,而数据指定了精度,则使用数据的精度。
  • 如果??TIME?? 未指定精度且数据未指定精度,则使用系统范围配置的时间精度。
  • 如果??TIME?? 指定精度而数据未指定精度,则使用系统范围配置的时间精度作为数据精度。
  • 如果??TIME??? 指定了精度并且数据精度小于??TIME?? 精度,则使用数据精度。
  • 如果??TIME??? 指定了精度并且数据精度大于??TIME??? 精度,则使用??TIME?? 精度。
SQL 元数据将时间精度的小数位报告为??“scale”???;它使用“??precision???精度”一词来表示数据的总长度。使用 ??TIME??? 数据类型的字段报告精度和比例元数据如下:??TIME(0)??? ??(%Time(PRECISION=0)) ???的元数据精度为 ??8 (nn:nn:nn)???,比例为 ??0???。TIME(2 ) (%Time(PRECISION=2)) 的元数据精度为 ??11 (nn:nn:nn.ff)???,比例为 ??2???。??TIME (%Time 或 %Time(PPRECISION="")??? 采用其小数秒精度来自提供的数据,因此元数据精度为 ??18?? 和未定义的比例。
  1. ??%Library.PosixTime??? 类和任何具有编码的有符号??64??? 位整数逻辑值的用户定义数据类型类都应使用 POSIXTIME 作为??SqlCategory???。??%PosixTime??? 是从??1970–01–01 00:00:00??? 以来的秒数(和小数秒)计算的编码时间戳。该日期之后的时间戳由正??%PosixTime??? 值表示,该日期之前的时间戳由负 %PosixTime 值表示。??%PosixTime??? 支持最多??6??? 位精度的小数秒。??%PosixTime??? 支持的最早日期为??0001-01-01 00:00:00???,其逻辑值为??-6979664624441081856???。支持的最后日期为??9999-12-31????23:59:59.999999???,其逻辑值为??1406323805406846975??。
因为 ??%PosixTime??? 值始终由编码的 ??64??? 位整数表示,所以它始终可以明确地区分于 ??%Date??? 或 ??%TimeStamp??? 值。例如,??1970–01–01 00:00:00??? 的 ??%PosixTime??? 值为 ??1152921504606846976???,??2017–01–01 00:00:00??? 的 ??%PosixTime??? 值为 ??1154404733406846976???,??1969–12–01??? 的 ??%PosixTime??? 值??00:00:00??? 是 ??-6917531706041081856??。
【数据类型】??%PosixTime??? 比 ??%TimeStamp??? 更可取,因为它比 ??%TimeStamp??? 数据类型占用更少的磁盘空间和内存,并且提供比 ??%TimeStamp?? 更好的性能。
可以使用 ODBC 显示模式集成 ??%PosixTime??? 和 ??%TimeStamp?? 值:
  • ??%PosixTime??? 和??%TimeStamp??? 数据类型的逻辑模式值完全不同:??%PosixTime??? 是有符号整数,??%TimeStamp?? 是包含 ODBC 格式时间戳的字符串。
  • 显示方式:??%PosixTime???显示使用当前??locale???时间和日期格式参数(例如??02/22/2018 08:14:11???);??%TimeStamp?? 显示为 ODBC 格式的时间戳。
  • ODBC 模式:??%PosixTime??? 和??%TimeStamp?? 都显示为 ODBC 格式的时间戳。精度的小数位数可能不同。
可以使用 ??TO_POSIXTIME??? 函数或 ??TOPOSIXTIME()??? 方法将 ??%TimeStamp??? 值转换为 ??%PosixTime???。可以使用 ??IsValid()??? 方法来确定数值是否为有效的 ??%PosixTime?? 值。
  1. ??%Library.TimeStamp??? 类和任何具有??YYYY-MM-DD HH:MI:SS.FF??? 逻辑值的用户定义数据类型类都应使用??TIMESTAMP??? 作为??SqlCategory???。请注意,??%Library.TimeStamp??? 的最大精度来自系统平台的精度,最多为??9??? 位小数秒,而??%Library.PosixTime??? 的最大精度为??6??? 位。因此,在某些平台上,??%Library.TimeStamp??? 可能比??%Library.PosixTime??? 更精确。??%Library.TimeStamp??? 规范化会自动将精度超过??9??? 位的输入值截断为??9?? 位小数秒。
  2. ??%Library.DateTime??? 是??%Library.TimeStamp??? 的子类。它定义了一个名为??DATEFORMAT??? 的类型参数,它覆盖了??DisplayToLogical()??? 和??OdbcToLogical()?? 方法来处理 TSQL 应用程序习惯的不精确的日期时间输入。
  3. ??%MV.Date??? 类,或任何具有??$HOROLOG-46385??? 逻辑日期值的用户定义数据类型类,应使用??MVDATE??? 作为??SqlCategory??。
  4. 不适合上述任何逻辑值的用户定义日期数据类型应将数据类型的??SqlCategory??? 定义为??DATE???,并在数据类型类中提供??LogicalToDate()??? 方法以将用户定义的逻辑日期值转换为??%Library.Date??? 逻辑值和??DateToLogical()??? 方法,用于将??%Library.Date?? 逻辑值转换为用户定义的逻辑日期值。
  5. 不适合上述任何逻辑值的用户定义时间数据类型应将数据类型的??SqlCategory??? 定义为??TIME???,并在数据类型类中提供??LogicalToTime()??? 方法以将用户定义的逻辑时间值转换为??%Library.Time???逻辑值和??TimeToLogical()??? 方法,用于将??%Library.Time?? 逻辑值转换为用户定义的逻辑时间值。
  6. 不适合上述任何逻辑值的用户定义时间戳数据类型应将数据类型的??SqlCategory??? 定义为??TIMESTAMP???,并在数据类型类中提供??LogicalToTimeStamp()??? 方法以将用户定义的逻辑时间戳值转换为??%Library.TimeStamp??? 逻辑值和??TimeStampToLogical()??? 方法,用于将??%Library.TimeStamp?? 逻辑值转换为用户定义的逻辑时间戳值。
可以使用 ??=???, ??< > ,??? ??> ???, ??< ??? 运算符将 ??POSIXTIME??? 与 ??DATE??? 或 ??TIMESTAMP?? 值进行比较。
在将 ??FMTIMESTAMP??? 类别值与 ??DATE??? 类别值进行比较时, IRIS 在将其与 ??DATE??? 进行比较之前不会从 ??FMTIMESTAMP??? 值中去除时间。这与比较 ??TIMESTAMP??? 与 ??DATE??? 值以及比较 ??TIMESTAMP??? 与 ??MVDATE??? 值的行为相同。它还与其他 SQL 供应商比较时间戳和日期的方式兼容。这意味着当使用 SQL 相等 (=) 运算符进行比较时,??FMTIMESTAMP 320110202.12??? 和 ??DATE 62124??? 的比较相等。应用程序必须将 ??FMTIMESTAMP??? 值转换为 ??DATE??? 或 ??FMDATE?? 值以仅比较值的日期部分。
1840 年 12 月 31 日之前的日期日期通常由 ??DATE??? 数据类型或 ??TIMESTAMP?? 数据类型表示。
??DATE??? 数据类型以 ??$HOROLOG??? 格式存储日期,作为从 1840 年 12 月 31 日的任意开始日期算起的正整数天数。默认情况下,日期只能由正整数 (??MINVAL=0???) 表示,它对应于到 1840 年 12 月 31 日。但是,可以更改 ??%Library.Date MINVAL??? 类型参数以启用存储 1840 年 12 月 31 日之前的日期。通过将 ??MINVAL??? 设置为负数,可以存储 12 月 31 日之前的日期, ??1840??? 为负整数。最早允许的 ??MINVAL??? 值为 ??-672045???。这对应于第 1 年 (CE) 的 1 月 1 日。 ??DATE?? 数据类型不能表示 BCE(也称为 BC)日期。
??TIMESTAMP??? 数据类型默认为 ??1840–12–31 00:00:00??? 作为最早允许的时间戳。但是,可以更改 MINVAL 参数以定义可以存储 1840 年 12 月 31 日之前的日期的字段或属性。例如??,MyTS %Library.TimeStamp(MINVAL=1492-01-01 00:00:00)???。最早允许的 ??MINVAL??? 值是 ??0001–01–01 00:00:00???。这对应于第 1 年 (CE) 的 1 月 1 日。 ??%TimeStamp?? 数据类型不能表示 BCE(也称为 BC)日期。
注意:请注意,这些日期计算并未考虑公历改革(1582 年 10 月 15 日颁布,但直到 1752 年才在英国及其殖民地采用)引起的日期变化。
可以重新定义语言环境的最短日期,如下所示:
s oldMinDate = ##class(%SYS.NLS.Format).GetFormatItem("DATEMINIMUM")
if oldMinDate = 0
d ##class(%SYS.NLS.Format).SetFormatItem("DATEMINIMUM",-672045)
s newMinDate = ##class(%SYS.NLS.Format).GetFormatItem("DATEMINIMUM")
w "Changed earliest date to ",newMinDate
else
w "Earliest date was already reset to ",oldMinDate

上面的示例将语言环境的

    推荐阅读