Анимация
JavaScript
|
Главная Библионтека 3.7. Анализ даты и времени в строках Проблема Спецификация даты или времени читается в произвольном формате, однако ее требуется преобразовать в отдельные компоненты (год, месяц и т. д.). Решение Если дата уже представлена в виде числа или имеет жесткий, легко аналнзируе-Mbiir формат, воспользуйтесь регулярным выражением (и, возможно, хэшем, связывающим пазвапия месянев с номерами) для извлечения отдельных значепи!! дня, месяца и года. Затем п])еобразуйге их в секунды с начада эпохи с ио.мощью функци!! timelocal и timegm стандарпюго модуля Time::Local. use Time Local, # $date хранится в формате 1999-06-03 (ГГГГ-ММ-ДД) ($уууу, %т $dd) = ($date ="• /(\d+)-(\d+)-(\d+)/ # Вычислить секунды с начала эпохи для полночи указанного дня # в текущем часовом поясе $epoch seconds = timelocal(0 О, О $dd, $т $уууу) Более гибкое решение - примекеппе фупкнип ParseDate из модуля Date;:Manip с CPAN и иоследуюп1ее извлечение отдельных компонентов с помощью UnixDate. use Date Manip qw(ParseDate UnixDate), $date = ParseDate($STRING) If (t$date) { # Неверная дата } else { (BVALUES = UnixDate($date (SFORMATS) Комментарий Универсальная функция ParseDate поддерживает различные форматы дат. Она даже преобразует такие строки, как «today» («сегодня»), «2 weeks ago Friday* («в пятницу две недели назад») и «2nd Sunday in 1996» («2-е воскресенье 199G года»), а также понимает форматы даты/времени в заюловках почты и новостей. Расши({)роваппая дата возвращается в собственном формате - строке вида «ГГГГММДДЧЧ:ММ:СС». Сравнение двух строк позволяет узнать, совпадают ли представленные ими даты, однако арифметические операции выполняются иначе. Поэтому мы воспользовались функцией UnixDate для извлечения года, месяца и дня в нужном формате. Функция UnixDate получасг дату в виде строки, возвращаемой ParseDate, и список форматов. Она последовательно применяет каждый формат к строке и возвращает результат. Формат представляет собой строку с описанием одного или нескольких элементов даты/времени и способов оформления этих элементов. Например, формат %Y соответствует году, состоящему из четырех цифр. Приведем пример: 3.8. Вывод даты 105 use Date Manip qw(ParseDate UnixDate) while (<>) { $date = ParseDate($ ) if (i$date) { warn Bad date string $ \n , next, } else { ($year, $month, $day) = UnixDate($date, %Y , %n , %d ), print Date was $month/$day/$year\n l> Смотри также- Докзмеитация для модуля Date::Manip с CPAN; пример ислользовапия приведен в рецеиге 3.11, 3.8. Вывод даты Проблема Требуется иреобра.зовать дату и вре.чя, выраженные в секундах с 1гачала эпохи, в более понятную для человека форму Решение Вызовите localtime или gmtime в скалярном контексте - в эюм случае функция получает количество секунд с начала эпохи и возвращает сфоку вида Tue May 26 05:15-20 1998: $STR1NG = localtime($EP0CH SEC0NDS), Кроме того, функция strftime из стандартного модуля POSIX позволяет лучше 1Гасгроить формат вывода и работает с отдель)гы.\и1 колиюнептами полного времени: use POSIX qw(strftime), SSTRING = strftime($FORMAT SSECONDS, SMINUTES, SHOUR, $DAY 0F M0NTH SMONTH, SYEAR, SWEEKDAY, SYEARDAY, $DST), В модуле Date::Manip с CPAN есть функция UnixDate - нечто вроде спецпаашзи-рованного варианта sprintf, ирсдпазпаченного для работы с датам1Г. Ей передается дата в формате Date::Manip. Применение DaLe::Manip вместо POSIX::strftime имеет дополнительное преимущество, так как для этого от системы не требуется совместимость с POSIX, use Date Manip qw(UnixDate) SSTRING = UnixDate($DATE, SFORMAT), Комментарий Простейшее решение - (1)у1п<:ция localtime - относится к встрос1И1ым средствам Perl. В скалярном контексте эта фу1исцня возв])ащает строку, отформатированную особым образом: Sun Sep 21 15:33:36 1999 Программа получается простой, хотя формат строки сильно ограинче]!: use Time Local, Stime = tifflelocal(50, 45, 3, 18, 0, 73) print Scalar localtime gives scalar(localtime($time)), \n , Scalar localtime gives: Thu Jan 18 03:45:50 1973 Разумеется, дата и время для localtime должны исчисляться в секундах с начала эпохи. Функция POSIX strftime получает набор компопе]1Гов полного времени н форматную строку, ана.10гнчпую printf, и возвращает также строку. Поля в выходной строке задаются директивами %. Полный список директив приведен в документации по strftime для вашей системы. Фу]Н<ция strftime ожидает, что от-делыняе компо]1е]1ТЫ дагы/времепи принадлежат тем же И1ггервалам, что и значения, возвращаемые localtime: use POSIX qw(strftime), use Time Local $time = timelocal(50, 45 3, 18 0, 73), print Scalar localtime gives , scalar(localtime($time)) \n , Scalar localtime gives: Thu Jan 18 03:45:50 1973 Разумеется, дата и время для localtime /[олжны исчисляться в секундах с ]1ача-ла эпохи. Функция POSIX strftime получает набор компонентов полного времени п форматную строку, апалогиЧ]1ую printf, и возвраи1аег также строку. Поля в выходной строке задаются дпрсктивали] %. ПолпьЙ! список директив приведен в докумептащн! но strftime для вашей системы. Фу1н<.ция strftime ожидает, что отдельные компоненты даты/времени пртшдлежаг тем же интервалам, что и значения, возвращаемые localtime: use POSIX qw(strftime), use Time Local, $time = timelocal(50, 45 3, 18, 0, 73), print strftime gives , strftime( %A %D , localtime($time)) \n , strftime gives; Thursday 01/18/73 При исиользовании POSIX -strftime все значения выводятся в соответствии с цацнопальными стандаргамп. Так, во Фра]гции ваша программа вместо "Sunday" выведет "Oimanche". Од]1ако учтите: интерфейс Perl к функцпн strftime модуля POSIX всегда преобра.зует дату в ]федполол<епии, что она относится к текущему часовому ноясу. Если функция strftime .модуля POSIX недоступна, у вас всегда остается верный модуль Date::Manip, опнса]1ный в рецепте 3.6. use Date Manip qw(ParseDate UnixDate), $date = ParseDate( 18 Jan 1973, 3 45 50 ), 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [ 29 ] 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |