-3

I am trying to convert to some date format from the below hash output. I am in need of convert many hash output to this date format below. I am using this below code now. it seems this code is not proper way I used.

Please share your thoughts to get that time format as simple way from the each hash output

my $status_update_time = "$row->{'update_time'}";
$status_update_time =~ m/(\d{4})-(\d{2})-(\d{2})\ (\d{2}):(\d{2}):(\d{2})$/;
my ($year, $month, $date,$hours,$minute,$second) = ($1, $2, $3, $4, $5, $6);
my $date_time = "$1-$2-$3T$4:$5:$6TZ"; #2015-08-11T04:31:41Z# expecting this time output

my $next_check = "$row->{'next_check'}";
$next_check =~ m/(\d{4})-(\d{2})-(\d{2})\ (\d{2}):(\d{2}):(\d{2})$/;
my ($year, $month, $date,$hours,$minute,$second) = ($1, $2, $3, $4, $5, $6);
my $next_check_time = "$1-$2-$3T$4:$5:$6Z"; #2015-08-11T04:31:41Z# expecting this time output

Thanks

coolent
  • 21
  • 10
  • 1
    Why aren't you using Time modules available on CPAN? – Chankey Pathak Aug 18 '15 at 04:23
  • I can use the module to convert. however, I need to change the resulted date format again like my $date_time = "$1-$2-$3T$4:$5:$6Z";(2015-08-11T21:17:41Z), so I am trying to manage code in simple lines instead of multiple lines like above code posted. since I need to convert this format to many individual hash output . thanks – coolent Aug 18 '15 at 04:42
  • You could use `DateTime::Format::ISO8601` for that. – Chankey Pathak Aug 18 '15 at 04:45
  • thanks for your suggestion – coolent Aug 18 '15 at 05:20
  • Trying to put too much stuff into a "simple line" will likely result in code that is very hard to read. Instead you should organize it in a `sub` and use clear names for your variables. It's better to have a few more lines of code, but concise and easy to understand blocks of those. Add some comments explaining why you need to do that conversion between formats back and forth. – simbabque Aug 18 '15 at 07:46

2 Answers2

3

Use Time::Piece. It's a standard part of the Perl distribution. Use strptime (string parse time) to parse your string into a Time::Piece object. Then use strftime (string format time) to display your Time::Piece object in whatever format you want.

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Time::Piece;

my $in_format  = '%Y-%m-%d %H:%M:%S';
my $out_format = '%Y-%m-%dT%H:%M:%SZ';

my $in_date = '2015-08-18 08:51:00';

my $date = Time::Piece->strptime($in_date, $in_format);

say $date->strftime($out_format);
Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • hi , now able to convert this format , however, I would like to assign the output time format to some varabile , if I assign the output , I am not getting , please let me know how to fix this say format_custom_to_iso($row->{update_time}); say format_custom_to_iso($row->{next_check}); 2015-05-11T21:17:41Z 2015-05-12T09:17:41Z like $old_time = say format_custom_to_iso($row->{update_time}); $new_time = say format_custom_to_iso($row->{next_check}); – coolent Aug 20 '15 at 10:36
  • Putting code into a StackOverflow comment is a really bad idea. If you have a new question then please ask a new question. – Dave Cross Aug 20 '15 at 10:38
  • `$new_time = say format_custom_to_iso($row->{next_check}` makes no sense at all. You're storing the return value from `say` (which will just be a true or false value). If you want to display the result and copy the value in the same line then use `say $new_time = format_custom_to_iso($row->{next_check}` instead. But this is pretty basic programming. – Dave Cross Aug 20 '15 at 10:44
  • hi, thank you so much. I didn;t use that 'say' before. sorry for that. Now I am able to get it, thanks again – coolent Aug 20 '15 at 11:44
0

Your timestamps are already almost in the right format. There are only two or maybe three things that are not.

  • Your regex has a $ in the end but not a ^ in the beginning, so maybe the timestamp fields are starting with garbage. If yes, that needs to be removed. If not, ignore this point.
  • The space should be a T
  • There should be a Z in the end

You are also repeating the same pattern twice. That is an indication that you really want a subroutine so you only need to write the code once.

Then you are assigning a bunch of variables ($year, $month, ...) that you are never using. That's very inefficient if this is in a loop with lots of iterations. There would also be a warning saying you redeclared all of those, because you declare them again with my a few lines down. use warnings would tell you about that.

Especially if this is run a lot of times, rolling your own for this simple substitution is faster than using a full-featured parser.

use strict;
use warnings;
use feature 'say';

my $row = {
  update_time => 'foo 2015-05-11 21:17:41',
  next_check => '2015-05-12 09:17:41',
};

say format_custom_to_iso($row->{update_time});
say format_custom_to_iso($row->{next_check});

sub format_custom_to_iso {
  my ($timestamp) = @_;

  # remove non-digits from the front (maybe this can be omitted)
  $timestamp =~ s/^[^0-9]+//;

  # replace the space with a T in the middle
  $timestamp =~ tr/ /T/;

  # and add a Z in the end
  return  $timestamp . 'Z';
}

Output:

2015-05-11T21:17:41Z
2015-05-12T09:17:41Z
simbabque
  • 53,749
  • 8
  • 73
  • 136