| Новости | FAQ | Авторы | Документация | В действии | Библиотека |
| Инструменты | Полезные ссылки | Хостинги | Скачать | Примеры | Форум |
Эдуард Габдуллин 02.05.2006 00:21
Пытаясь использовать RSS каналы на своем сайте долго и упорно бился с датами, функция from822 класса dtf.p упорно не хотела принимать даты форматов:###########################################################################
# $Id: dtf.p,v 1.21 2005/10/20 17:26:14 misha Exp $
#
# доступны методы:
# @create[date;default] из строки/даты конструирует объект типа date
# @format[fmt;date;locale] выводит полученную date, используя форматную строку
# @last-day[date] возвращает дату последнего дня заданного[текущего] месяца
# @from822[string] создает дату из переданной строки-даты в формате RFC822
# @to822[date;timezone] сдвигает дату из текущей TZ в указанную TZ и выводит её в виде строки в формате RFC822
# @setLocale[locale] задает новое значение locale, возвращая старое
# @resetLocale[] сбрасывает locale в default
#
###########################################################################
###########################################################################
# принимает в строку-дату в формате RFC822 и создает из неё объект типа date
# still under construction/testing.
@from822[string][_tmp;_fields;_name;_k;_v;_d2;_diff]
^try{
^if(!def $string){
^throw[dtf.from822;Empty date]
}
# $_tmp[^string.match[(?:([a-z]{3}),\s+)?(\d{1,2})\s+([a-z]{3})\s+(\d{4}|\d{2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})\s+(\w{3,5})?|(?:\s*([-+]?\d{1,2}(\d{2})?))?][i]]
$_tmp[^string.match[(?:([a-z]{3}),\s+)?(\d{1,2})\s+([a-z]{3})\s+(\d{4}|\d{2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})\s+(\w{3,5})?(?:\s*([-+]?\d{1,2})(\d{2})?)?][i]]
^if($_tmp){
# ^if(^_tmp.1.match[\D]){
$_fields[
$.weekday_name[$_tmp.1]
$.day($_tmp.2)
$.month(0)
$.month_name[$_tmp.3]
$.year($_tmp.4)
$.hour($_tmp.5)
$.min($_tmp.6)
$.sec($_tmp.7)
$.tz[$_tmp.8]
$.offset_hour[$_tmp.9]
$.offset_min[$_tmp.10]
]
# }{
# $_fields[
# $.weekday_name[]
# $.day($_tmp.1)
# $.month(0)
# $.month_name[$_tmp.2]
# $.year($_tmp.3)
# $.hour($_tmp.4)
# $.min($_tmp.5)
# $.sec($_tmp.6)
# $.tz[$_tmp.7]
# $.offset_hour[$_tmp.8]
# $.offset_min[$_tmp.9]
# ]
# }
^rem{ *** check month abbr *** }
$_name[^_fields.month_name.lower[]]
^es-locale.month.foreach[_k;_v]{
^if(^_v.lower[] eq $_name){
$_fields.month($_k)
}
}
^if(!$_fields.month){
^throw[dtf.from822;Unknown month '$_fields.month_name']
}
^if(def $_fields.offset_hour && !def $_fields.tz){
$_fields.tz[GMT]
}
$result[^date::create($_fields.year;$_fields.month;$_fields.day;$_fields.hour;$_fields.min;$_fields.sec)]
^rem{ *** check weekday abbr *** }
^if(def $_fields.weekday_name){
^if(^_fields.weekday_name.lower[] ne ^es-locale.weekday.[$result.weekday].lower[]){
^throw[dtf.from822;Incorrect day of week '$_fields.weekday_name' in RFC822 date (must be '$es-locale.weekday.[$result.weekday]')]
}
}
^rem{ *** roll time to timezone *** }
^if(def $tz.[$_fields.tz]){
$_d2[^date::create($result)]
^_d2.roll[TZ;$tz.[$_fields.tz]]
$_diff(^date::create($_d2.year;$_d2.month;$_d2.day;$_d2.hour;$_d2.minute;$_d2.second) - $result)
$result[^date::create($_d2 - $_diff)]
}
^rem{ *** apply timezone offset *** }
^if(def $_fields.offset_hour){
# $result[^date::create($result - ($_fields.offset_hour + ^_fields.offset_min.int(0) / 60) / 24)]
# Вносим поправку на летнее время
$result[^date::create($result - ($_fields.offset_hour + ^_fields.offset_min.int(0) / 60 - ^result.daylightsaving.int(0)) / 24)]
}
}{
^throw[dtf.from822;Wrong RFC822 date format]
}
}{
^if($exception.type ne "dtf.from822"){
$exception.handled(1)
^throw[dtf.from822;Can't create date (${_fields.year}-${_fields.month}-$_fields.day ${_fields.hour}:${_fields.min}:${_fields.sec}).]
}
}
#end @from822[]теперь принимаются даты: