#sql #sas #dst
Вопрос:
Я пытаюсь выполнить преобразование часового пояса в своей программе и сталкиваюсь с некоторыми трудностями. Ниже у меня есть
data GMT_conv;
set table;
if city in ('Atlanta', 'Baltimore' , 'New York') then conv = -5;
if city in ('Minneapolis') then conv = -6;
if city in ('Salt Lake City') then conv = -7;
if city in ('San Francisco') then conv = -8;
run;
однако это верно только в не летние месяцы. Летнее время меняется на 2-е воскресенье марта и Первое воскресенье ноября. Я не могу придумать, как это сделать, если оператор (либо в SAS, либо в proc sql)
чего я хочу:
if (between 2nd sunday in march and 1 sunday of november)
then conv 1;
какие-нибудь советы?
Ответ №1:
Мое предложение состояло бы в том, чтобы использовать встроенные функции часового пояса SAS и форматы/информацию, а не использовать свои собственные.
Во-первых, на странице справки SAS по часовым поясам показано, как указать время с помощью часового пояса. Затем вы можете увидеть, как использовать функцию TZONES2U для преобразования времени SAS в UTC или TZONEU2S для обратного преобразования. Это автоматически приведет к переходу на летнее время!
Например:
data time_data;
format dtval datetime17.;
input city $ dtval :datetime17.;
datalines;
Atlanta 08JUN2021:11:00:00
Baltimore 08JAN2021:11:00:00
Chicago 08JUN2021:11:00:00
Dallas 08JAN2021:11:00:00
;;;;
run;
data want;
set time_data;
length tz $32;
if city in ('Atlanta','Baltimore') then tz='America/New_York';
if city in ('Chicago','Dallas') then tz='America/Chicago';
format dtval_utc datetime17.;
dtval_utc = tzones2u(dtval,tz);
time_diff = dtval-dtval_utc;
format time_diff time8.;
run;
Это показывает разницу в DST (обратите внимание, что в Атланте летом 4 часа свободного времени, а в Балтиморе зимой-5 часов).
Конечно, вам все равно нужно знать, какой часовой пояс правильный; вы можете сделать это вручную, как вы делаете изначально и как я сделал в примере, или вы можете посмотреть его в некоторой степени (возможно, используя почтовый индекс и SASHELP.ZIPCODE).
Комментарии:
1. Поэтому причина, по которой я пытался изложить это так, как я это сделал, заключалась в том, как представлены мои данные. Во — первых, меня здесь интересует только время суток, а не дата вообще. Мои данные представлены в виде одного столбца, в котором указана дата по Гринвичу, а другой столбец-минутное время по Гринвичу (количество минут после полуночи по Гринвичу). Я мог бы сделать этот метод, но я не уверен, как соединить минутное время с датой и сделать его датой SAS, а затем мне все равно пришлось бы сократить время в конце. Выполнимо, но может быть сложнее, так как я все равно работаю только с примерно 8 городами.
2. Время суток и дата — время здесь не имеют значения-но, конечно, для компонента летнего времени! Если все указано в UTC (это термин, который вы должны использовать, если вы имеете в виду дату/время без часового пояса), затем поместите его в одно поле, используйте TZONEU2S, а затем разделите его обратно так, как вы хотите. Используйте
dhms()
для их объединения (dt = dhms(date,0,0,time);
). Не пишите код, чтобы сделать это вручную, поверьте мне — особенно через 5 или 10 лет правила DST изменятся, и вы не помните, что написали этот код! SAS исправит их функции, вы об этом не вспомните.