-1

I have a date in the following format which is how it is stored in an external application

06/12/2014 6:31 PM IST

I want to change this format to which needs to check AM and PM also and rest of the minutes to be hardcoded as :00+5:30

2014-06-12 18:31:00+05:30

Since it is not a simple GMT to PDT change I tried with epoch, but the problem here is that the date is in different format.

Zach Lysobey
  • 14,959
  • 20
  • 95
  • 149
user3264858
  • 51
  • 1
  • 8

3 Answers3

2

you can just do it with regex and a printf. in your particular case i suggest:

my $yourstring = '06/12/2014 6:31 PM IST';
my ($mm,$dd,$yy,$hh,$mi,$ampm) = $yourstring =~ m~(\d+)/(\d+)/(\d+)\s+(\d+):(\d+)\s+(AM|PM)\s+~;
if ($ampm eq 'PM' && $hh < 12) { $hh += 12 }
printf ('%04d-%02d-%02d %02d:%02d:00+05:30', $yy, $mm, $dd, $hh, $mi);

or look into DateTime::Format::DateParse

Brett Schneider
  • 3,993
  • 2
  • 16
  • 33
1

The best thing to do is to use Perl's now built in Date/Time functions in Time::Piece. Once you convert your time into a true Perl time, you can format it any way you please.

The problem is that Time::Piece doesn't do a very good job at handling timezones. The easiest way of handling timezones on strings is to simply remove them:

use strict;
use warnings;

use Time::Piece;

# This is what you have given
my $input_time="6/12/2014 6:31 PM IDT";

# Remove timezone (the last four characters)
my $munged_time = substr $input_time, 0, -4;

# This is a description of your "format" above
# You can find this by doing a "man date" on Unix.
# Sometimes it's "man strftime".
#
# The various %x are bits that represent the time
# in various formats.
# %m = month         %d = month date   %Y = four digit year
# %I = hour 01-12    %M = Minutes      %p = AM/PM  
my $time_format="%m/%d/%Y %I:%M %p";

# Now convert the time from the format to a Time::Zone
# Date Object.
my $time = Time::Piece->strptime($munged_time, $time_format);

# Now that the time is in a Time::Piece object, we can easily
# manipulate it to do whatever we want. We could add or subtract
# date times from each other, add or subtract hours, months, etc.

# Here, I'm just printing out the various bits and pieces of
# "datetime" that I am interested in. Note I'm using time->second
# even though I never specified seconds. It's okay, Time::Piece
# simply assumes that seconds are zero.
#
printf "%04d-%02d-%02d %02d:%02d:%02d+05:30\n",
    $time->year, $time->mon, $time->mday,
    $time->hour, $time->minute, $time->second;
David W.
  • 105,218
  • 39
  • 216
  • 337
0

The question does not contain any information about which time formats are possible at all. Are day of month and month always with 2 digits? Is the hour in range 0 to 9 always without a leading 0? Is it possible that the minutes 0 to 9 are without a leading 0? Which time zones are possible, just IST or others as well?

Here is a list of Perl regular expression search and replace strings which must be applied all to reformat date and time strings for time zone IST to get the date and time in format YYYY-MM-DD hh:mm:00+05:30

Reformat all times with AM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +([01]?\d:[0-5]?\d) AM IST
Replace: $3-$1-$2 $4:00+05:30

Reformat all times with 12:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +(12:[0-5]?\d) PM IST
Replace: $3-$1-$2 $4:00+05:30

Reformat all times with 01:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +0?1(:[0-5]?\d) PM IST
Replace: $3-$1-$2 13$4:00+05:30

Reformat all times with 02:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +0?2(:[0-5]?\d) PM IST
Replace: $3-$1-$2 14$4:00+05:30

Reformat all times with 03:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +0?3(:[0-5]?\d) PM IST
Replace: $3-$1-$2 15$4:00+05:30

Reformat all times with 04:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +0?4(:[0-5]?\d) PM IST
Replace: $3-$1-$2 16$4:00+05:30

Reformat all times with 05:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +0?5(:[0-5]?\d) PM IST
Replace: $3-$1-$2 17$4:00+05:30

Reformat all times with 06:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +0?6(:[0-5]?\d) PM IST
Replace: $3-$1-$2 18$4:00+05:30

Reformat all times with 07:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +0?7(:[0-5]?\d) PM IST
Replace: $3-$1-$2 19$4:00+05:30

Reformat all times with 08:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +0?8(:[0-5]?\d) PM IST
Replace: $3-$1-$2 20$4:00+05:30

Reformat all times with 09:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +0?9(:[0-5]?\d) PM IST
Replace: $3-$1-$2 21$4:00+05:30

Reformat all times with 10:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +10(:[0-5]?\d) PM IST
Replace: $3-$1-$2 22$4:00+05:30

Reformat all times with 11:xx PM in string.

Search: ([01]?\d)/([0-3]?\d)/([12][09]\d\d) +11(:[0-5]?\d) PM IST
Replace: $3-$1-$2 23$4:00+05:30

Insert leading 0 where missing in date (month, day of month) or time (hour, minute) string using an expression with a positive lookbehind and a positive lookahead:

Search: (?<=[ \-:])(\d)(?=[ \-:])
Replace: 0$1

In case of above expression does not work because of lookbehind/lookahead, it would be also possible to use less restrictive regular expression:

Search: \b(\d)\b
Replace: 0$1

Mofi
  • 46,139
  • 17
  • 80
  • 143