2014-09-17 3 views
2

У меня есть значение даты и времени в часовом поясе GMT. Как я могу преобразовать его в свой местный часовой пояс? Я бы ожидал, что для этого будет функция. Обратите внимание, что я не могу просто добавить или вычесть разницу из-за летнего времени. Например, функция может работать следующим образом:Конвертировать GMT datetime в local

data _null_; 
    gmtdatetime="17SEP14:09:42:10"dt; 
    localdatetime=tz2local(gmtdatetime,"GMT"); 
run; 

я попробовал некоторые комбинации форматов и informats без везения:

data _null_; 
    gmtdatetime="17SEP14:09:42:10"dt; 
    a=put(gmtdatetime,E8601DZ20.0);*Converts the value to "2014-09-17T09:42:10Z" to indicate that it is GMT; 
    localdatetime=input(a,B8601DT.);*Reads the GMT value; 
    put localdatetime datetime.;*This still prints the value as the original GMT value...; 
run; 

Спасибо, Стиг

+0

Действительно ли это GMT или UTC? (Подсказка, Великобритания использует GMST в настоящее время). Использование «Z», время Zulu означает, что вы считаете это UTC, но UTC и GMT не то же самое :) – oerkelens

+0

Спасибо, я не знал, что между GMT и UTC существует разница. Согласно [этой странице] (http://www.timeanddate.com/time/aboututc.html) «UTC обычно упоминается как среднее время по Гринвичу (GMT), когда не учитывается точная точность в отношении долей секунды» –

+1

Добавлено Преимущество GMT заключается в том, что вы не попадете в ловушку, думая, что ваши лондонские пользователи используют GMT. 09:40 этим утром в Лондоне было 08:40 Зулу. Вы спрашиваете у французского пользователя, в каком часовом поясе он находится, он может отвечать GMT + 1 или CET. В настоящее время он ни в одном (он в CEST, CET + 1, GMT + 2 или GMST + 1 - или просто в настоящее время в UTC + 2). Это преимущество UTC, не DST и вещи :) – oerkelens

ответ

2

Я сделал функцию, которая вернет GMT смещение, но когда я собирал его, я получил эту ошибку:

ERROR: Built-in SAS FUNCTION or SUBROUTINE already exists with name 'GMToff'. 

Оказывается, есть недокументированная функция в SAS, которая возвращает GMT, и, к счастью, я выбрал одно и то же имя! Here - некоторые примеры использования. В любом случае, он не вернет смещение в определенное время, как я и хотел, только для текущего времени. Вот функция, которая преобразует DateTime в «местное» время, учитывая часовой пояс (поддерживает только GMT, но добавление дополнительных часовых поясов при необходимости должны быть тривиальными):

proc fcmp outlib = Apfmtlib.funksjoner.localtime; 
function localtime(datetime,tz$); 
    if upcase(tz)="GMT" then do; 
     offset_normal=3600; 
     offset_summer=7200; 
    end; 
    localtime=datetime+offset_normal; 
    /*If datetime is between 1 AM the last Sunday of March and 1 AM the last Sunday of October it is "summertime" in central Europe:*/ 
    if intnx('week',mdy(3,31,year(datepart(datetime))),0)*86400 + 3600 le datetime le intnx('week',mdy(10,31,year(datepart(datetime))),0)*86400 + 3600 then localtime=datetime+offset_summer;; 
    return(localtime); 
endsub; 
quit; 
options cmplib = Apfmtlib.funksjoner; 
/*Usage examples:*/ 
data _null_; 
    gmtdatetime="17SEP14:09:42:10"dt; 
    localdatetime=localtime(gmtdatetime,"GMT"); 
    put localdatetime datetime.; 
    gmtdatetime="17DEC14:09:42:10"dt; 
    localdatetime=localtime(gmtdatetime,"GMT"); 
    put localdatetime datetime.; 
run; 
1

Я сделал формат, который даст мне смещение от GMT к моему часовому поясу (в секундах). В центральной Европе летнее время начинается последнее воскресенье марта в 1:00 по Гринвичу и заканчивается в последнее воскресенье октября в 1:00 по Гринвичу.

data fmt(drop=year); 
    attrib hlo length=$1 
     start end format=datetime.;; 
    fmtname="gmtoff"; 
    type="N"; 
    do year=1980 to 2080; 
    start=intnx('week',mdy(3,31,year),0)*86400 + 3600;*Last Sunday in March 1 AM; 
    end=intnx('week',mdy(10,31,year),0)*86400 + 3600;*Last Sunday in October 1 AM; 
    label=7200;*Two hours offset in summertime; 
    output; 
    end; 
    start=.;end=.; 
    hlo="O"; 
    label=3600;*When it is not summertime, it is one hour offset; 
    output; 
run; 
proc format cntlin=fmt; 
run; 

/*Example of usage:*/ 
data _null_; 
    gmtdatetime="17SEP14:09:42:10"dt; 
    localdatetime=gmtdatetime + put(gmtdatetime,gmtoff.); 
    put localdatetime datetime.; 
    gmtdatetime="17DEC14:09:42:10"dt; 
    localdatetime=gmtdatetime + put(gmtdatetime,gmtoff.); 
    put localdatetime datetime.; 
run; 
1

В SAS 9.4 функция tzonesoff доступна что, я думаю, может быть ответом на ваш вопрос. Функция возвращает разницу между вашим часовым поясом и GMT.

data _null_; 
    gmtdatetime="17SEP14:09:42:10"dt; 
    tzoffset = tzoneoff('Europe/Copenhagen'); 
    localdatetime=gmtdatetime+tzoffset; 
    put localdatetime= datetime.; 
run; 
Смежные вопросы