2016-04-22 2 views
0

У меня есть два поля в файле .CSV. Я разбираюсь в том, что должно представлять время. В настоящее время они представляют собой 5 или 6 цифр (т. Е. 85323 будет 8:53:23, или 163211 будет 16:32:11). Мне нужно бросить двоеточия (:) там. Будет что-то вродеЧисло времени в формате Perl?

strptime->strftime 

с использованием

Time::Piece 

работать на что-то подобное? Или, может быть, нет, поскольку в настоящее время они обрабатываются как VARCHAR для загрузки в таблицу MySQL и, вероятно, должны быть заменены на тип TIME.

+0

подушечка из 6 цифр ('85323' ->' 085323'), расщепленных на каждом 2-ом полукокса: '[08,53,23]', сливают с ':' -> '08: 53: 23' –

+2

Вы действительно должны хранить время в своей базе данных в качестве подходящего te [временный тип] (http://dev.mysql.com/doc/refman/5.7/en/date-and-time-types.html) вместо VARCHAR. Это позволит вам выполнить проверку (например, отклонить значения типа «00: 00: 60') и математику даты/времени (например, 12:00:00 - 11:59:59 = 00:00:01 вместо 4041), среди другие вещи. – ThisSuitIsBlackNot

+0

Я думаю, что он должен быть изменен на тип TIME, но TPTB говорят, чтобы придерживаться VARCHAR, поскольку некоторые другие различные программы (к которым я не имею никакого отношения) будут использовать эти данные. Поэтому мне, возможно, даже не нужно менять его в соответствующий формат TIME. Ожидаем подтверждения на этом – BigRedEO

ответ

1

Try:

s/(\d{1,2})(\d{2})(\d{2})/$1:$2:$3/; 

Нет необходимости использовать модуль :)

+0

's /(..)(..)$/:$ 1: $ 2 /;' – toolic

+0

Добавил это моему сценарию в мой оператор WHILE как '$ _ = s/(\ d {1,2}) (\ d {2}) (\ d {2})/$ 1: $ 2: $ 3/для $ fields [15,26]; 'и хотя он не выдавал ошибку, он также не форматировался. Я что-то упустил? – BigRedEO

+0

Чем больше источников вы укажете в исходном вопросе, тем лучше вы получите ответы. Попробуйте: '$ fields [15] = ~ s/...; $ fields [26] = ~ s/...; ' – Sebastian

1
$ perl -wle 'print join(":", unpack("(A2)*", sprintf("%06d", $ARGV[0])))' 85323 
08:53:23 

$ perl -wle 'print join(":", unpack("(A2)*", sprintf("%06d", $ARGV[0])))' 163211 
16:32:11 
0

Другое решение Regex при условии не учитывает добавления ведущего нуля.

Это будет работать хорошо, если у вас есть новый Perl, который поддерживает возможность /r возврата на s/// замен

$_ = sprintf('%06s', $_) =~ s/(..)(..)$/:$1:$2/r; 

$_ Replace с именем переменной.

В качестве альтернативы, если ваш Perl не имеет опцию /r, это будет делать то же самое ...

($t = sprintf('%06s', $t)) =~ s/(..)(..)$/:$1:$2/; 

Конечно, вы могли бы достичь того же с Time::Piece, но для этой конкретной задачи я вас уверяю это медленнее (и более многословным)

$_ = Time::Piece->strptime(sprintf('%06s', $_), '%H%M%S')->hms; 
Смежные вопросы