2016-04-22 12 views
0

我有一個.CSV文件中的兩個字段,我通過解析來表示時間。目前,它們是5位或6位數字(即85323將是8:53:23,或163211將是16:32:11)。我需要把冒號(:)放在那裏。會像使用類似的東西Perl格式編號的時間?

Time::Piece 

工作

strptime->strftime 

?或者可能不是,因爲它們目前被視爲一個VARCHAR加載到MySQL表中,而應該改爲TIME類型。

+0

墊出6位數字('85323' - >'085323'),分割在每個第二字符:'[08,53,23]',重組用':' - >'08:53:23' –

+2

你真的應該在你的數據庫中存儲時間作爲appropria 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

嘗試:

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/for $ 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

提供不佔添加前導零的正則表達式的其他解決方案。

這將正常工作,如果你有一個支持的s///換人

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

替換$_與您的變量名/r回報選項新的Perl。

另外,如果你的Perl沒有/r選項,這將做同樣的事情......

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

當然,你可以達到同樣的事情Time::Piece但對於這個特殊的任務,我向你保證它是較慢的(並且更詳細)

$_ = Time::Piece->strptime(sprintf('%06s', $_), '%H%M%S')->hms;