perl将H:MM:SS转换为MM.MMMM
我需要使用perl从文本文件DOW YYYY-MM-DD H:MM:SS.S中读入,然后输出十进制分钟数MM.MMMM。给定输入文本文件perl将H:MM:SS转换为MM.MMMM,perl,Perl,我需要使用perl从文本文件DOW YYYY-MM-DD H:MM:SS.S中读入,然后输出十进制分钟数MM.MMMM。给定输入文本文件 Fri 2013-06-14 0:59:15.3 Sat 2013-06-15 1:01:30.6 Sun 2013-06-16 1:03:45.9 我想计算十进制的分钟数 (60*0)+59+(15.3/60) = 59.2550 (60*1)+01+(30.6/60) = 61.5100 (60*1)+03+(45.6/60) = 63.7600 然后
Fri 2013-06-14 0:59:15.3
Sat 2013-06-15 1:01:30.6
Sun 2013-06-16 1:03:45.9
我想计算十进制的分钟数
(60*0)+59+(15.3/60) = 59.2550
(60*1)+01+(30.6/60) = 61.5100
(60*1)+03+(45.6/60) = 63.7600
然后输出
(59.2550, 61.5100, 63.7600)
假设文本文件上的每一行都是它自己的日期,并且您正在读取的文件位于同一目录下,名为
input.txt
,我会这样做:
use strict;
use warnings;
my @result = ();
{
open (my $file, "<", "input.txt") or die "cannot open < input.txt: $!";
while(<$file>){
my @current = split(/:/,substr($_,15));
push(@result, (60*$current[0]) + $current[1] + ($current[2]/60));
}
}
print "(" . join(',',@result) . ")";
使用严格;
使用警告;
我的@result=();
{
open(my$file,“输入文件的格式不是很清楚,但这似乎产生了您想要的内容。它需要输入文件的路径作为命令行参数
use strict;
use warnings;
my @minutes;
while (<>) {
push @minutes, $1*60 + $2 + $3/60 if /(\d+):(\d+):([\d.]+)/;
}
printf "(%s)\n", join ', ', map sprintf('%.4f', $_), @minutes;
首先,您必须捕获您的输入:
my $time = "Fri 2013-06-14 0:59:15.3";
$time =~ /(\d+?):(\d+?):(.+)$/ #The time captured in three components
my $hours = $1;
my $minute = $2;
my $seconds = $3;
描述您希望在行中匹配的内容。$
表示将我的表达式锚定在行的末尾。(..)
是捕获组。这些组捕获在我的正则表达式中匹配的内容,并通过$1
、$2
和$3
变量使它们可用
如果您从未学习过正则表达式,您应该学习。正则表达式非常强大,您应该在上面的链接中阅读它们,或者尝试使用
现在,我已经捕获了我的各种时间片段(假设60秒分钟和60分钟小时),我现在可以进行计算:
my $time_in_seconds = ( $hours * 3600 ) + ( $minutes * 60 ) + $seconds;
my $time_in_minutes = $time_in_seconds / 60;
计算机上的除法存在精度问题,因为很难用小数点后的小数表示为基数2。因此,我更喜欢将其全部相乘,然后除以60
一旦你有时间,你需要以你想要的格式打印出来。这需要:
%9.4f
指定了格式。f
表示这是一个浮点数(基本上是一个非整数)。4
表示小数位数。9
表示字段宽度,其中包括小数、小数另一侧的四个和减号。因此,这将允许宽度高达-9999.999
,这就足够了
总而言之
#! /usr/bin/env perl
#
use warnings;
use strict;
use feature qw(say);
while ( my $time = <DATA> ) {
chomp $time;
$time =~ /(\d+?):(\d+?):(.+)$/; #The time captured in three components
my $hours = $1;
my $minutes = $2;
my $seconds = $3;
my $time_in_seconds = ( $hours * 3600 ) + ( $minutes * 60 ) + $seconds;
my $time_in_minutes = $time_in_seconds / 60;
printf qq(%9.4f\n), $time_in_minutes;
}
__DATA__
Fri 2013-06-14 0:59:15.3
Sat 2013-06-15 1:01:30.6
Sun 2013-06-16 1:03:45.9
看起来不错。你应该使用词法文件句柄和三个参数打开。@simbabque很好,我只是根据你的好建议改进了我的答案,使代码更好…你还应该使用严格的和使用警告;检查打开的成功情况如果失败,请检查是否打开包含$!
;并使用正则表达式/:/
作为split
@Borodin的第一个参数,谢谢。我理解其他事情的原因,但为什么使用正则表达式/:/
作为split
更好?@darkajax:因为它被用作正则表达式,但你引用它,最好是clear.$1*24
应该是$1*60
,因为小时->minute@doubleDown:你说得对。谢谢。$cat./eassed_01.txt Fri 2013-06-14 0:59:15.3 Sat 2013-06-15 1:01:30.6 Sun 2013-06-16 1:03:45.9$./convert_to_min_03.pl./eassed_01.txt$cat./eassed_01.txt Fri 2013-06-14 0:59:15.3 Sat 2013-06-15 1:01:30.6 Sun2013-06-16 1:03:45.9 Gregs Mac mini:scripts gregcoats$/转换为\u min\u 03.pl./经过的\u 01.txtI没有任何输出$cat./经过的\u 01.txt Fri 2013-06-14 0:59:15.3 Sat 2013-06-15 1:01:30.6 Sun 2013-06-16 1:03:45.9 Gregs Mac mini:scripts gregcoats$/转换为\u min\u\u 03.pl./经过的时间并非所有分钟都有60秒,所以你的答案可能是用你的方法离开一秒钟。
printf "%9.4f\n", $time_in_minutes;
#! /usr/bin/env perl
#
use warnings;
use strict;
use feature qw(say);
while ( my $time = <DATA> ) {
chomp $time;
$time =~ /(\d+?):(\d+?):(.+)$/; #The time captured in three components
my $hours = $1;
my $minutes = $2;
my $seconds = $3;
my $time_in_seconds = ( $hours * 3600 ) + ( $minutes * 60 ) + $seconds;
my $time_in_minutes = $time_in_seconds / 60;
printf qq(%9.4f\n), $time_in_minutes;
}
__DATA__
Fri 2013-06-14 0:59:15.3
Sat 2013-06-15 1:01:30.6
Sun 2013-06-16 1:03:45.9
$ ./test.pl
59.2550
61.5100
63.7650