使用DHMS拼接日期时间生成日内时序时,9:30:00结果异常求助
排查dhms拼接日期时间出错(仅9:30:00异常)的问题
首先,你的核心问题大概率出在变量类型不匹配——dhms()函数对输入参数的类型有严格要求,而你直接传入原始的date(YYYYMMDD格式)和time(HH:MM:SS格式)变量,可能不符合它的预期。
为什么9:30:00会单独出错?
先明确dhms(date, hour, minute, second)的参数规则:
- 第一个参数
date必须是SAS日期值(即从1960-01-01开始累计的天数,比如2024-05-20对应的SAS日期是23506),而不是字符型的"20240520"或数值型的20240520。 - 第四个参数
second必须是秒数(可以是SAS时间值,因为SAS时间本身就是以秒为单位存储的数值,比如9:30:00对应的秒数是34200)。
如果你的time是字符型变量,当它的值是"9:30:00"时,SAS尝试把它转成数值传给dhms()的第四个参数,会只识别冒号前的数字(也就是9),最终拼接出的时间会变成00:00:09,自然完全错误;而其他时间比如"10:00:00",可能因为转成数值是10,看起来只是时间不对,但你可能没注意到。
另外,如果你的date是字符型或非SAS日期的数值,dhms()会把它当成天数处理,比如数值20240520会被当成距离1960-01-01的200多万天,对应的日期是几万年之后,结果肯定不对。
正确的处理步骤
1. 先确认变量类型
先跑一段代码查看date和time的类型与实际值:
data check_types; set your_dataset; put "date变量类型: " vtype(date) ", 实际值: " date; put "time变量类型: " vtype(time) ", 实际值: " time; /* 测试单独转换time为SAS时间 */ if time = "9:30:00" then do; test_time = input(time, time8.); put "9:30:00转换为SAS时间(秒): " test_time; end; run;
如果输出里test_time不是34200,说明time的转换有问题。
2. 正确生成datetime变量
根据变量类型选择对应的转换方式:
情况A:date是字符型(如"20240520"),time是字符型(如"09:30:00")
data want; set your_dataset; /* 把字符型date转成SAS日期 */ sas_date = input(date, yymmdd8.); /* 把字符型time转成SAS时间(秒数) */ sas_time = input(time, time8.); /* 生成datetime */ datetime = dhms(sas_date, 0, 0, sas_time); /* 或者更简洁的方式:日期+时间(转成天,因为SAS日期以天为单位) */ datetime = sas_date + sas_time / 86400; /* 格式化为你需要的YYYYMMDDTHH:MM:SS样式 */ format datetime e8601dt19.; run;
情况B:date是数值型(如20240520,存储的是YYYYMMDD数字)
先把数值转成字符,再转SAS日期:
sas_date = input(put(date, 8.), yymmdd8.);
情况C:time是数值型(如93000,存储的是HHMMSS数字)
转成字符再转SAS时间:
sas_time = input(put(time, 6.), time6.);
额外排查点
- 如果只有9:30:00出错,检查这个值的
time变量是否有隐藏字符(比如空格、制表符),可以用trim(time)或者compress(time)先清理字符型变量再转换。 - 验证转换后的SAS日期和时间是否正确:用
format sas_date yymmdd10. sas_time time8.;查看是否和原始值匹配。
内容的提问来源于stack exchange,提问作者eternity1
相关产品推荐
相关产品推荐

