SAS преобразование летнего времени SAS

#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 исправит их функции, вы об этом не вспомните.