quinekxi
quinekxi

Reputation: 889

Convert date in YYYY-MM-DD in Perl?

I have search the internet for some time now but I can't seem to find the right answer (maybe there is but I don't understand it).

I have this code to read a file and get the date time (from Task Scheduler query).

File.txt holds the Task Scheduler query.

"TaskName","Next Run Time","Status"
"CheckFile","20:33:00, 17/1/2013",""

=======================================

Script to read a get the next run time value.

open (FILE, "<", $file) || print "WARN: Cannot open $file: $!";
@logLines = <FILE>;
if (@list = grep(/\b$keyword\b/, @logLines)) {
    foreach(@list){$result = $_;}
    my @sresult = split(/(?<="),(?=")/, $result);
    $name = $sresult[0];
    $name =~ tr/"//d;

    $next_run = $sresult[1];
    $next_run =~ tr/"//d;
    print $next_run;
}
@list=();
@dFormat=();
@logLines=();
close FILE;

Output will be:

20:33:00, 17/1/2013

I want to modify the output into:

20:33:00, 2013-1-17 #note that I can do this just by splitting up and rearranging the numbers.

But the problem is, 17/1/2013 in Task Scheduler query is locale dependent. It could be in the following:

  1. 1/17/2013
  2. 17/1/2013
  3. 2013/1/17
  4. 1/17/13
  5. 17/1/13
  6. 13/1/17
  7. 1-17-2013
  8. 17-1-2013
  9. 2013-1-17
  10. 1-17-13
  11. 17-1-13
  12. 13-1-17
  13. 1.17.2013
  14. 17.1.2013
  15. 2013.1.17
  16. 1.17.13
  17. 17.1.13
  18. 13.1.17

Is there any cpan module that could do what I want? Could you give a script on how to achieve this?

Please no harsh comment. Thanks.

Upvotes: 0

Views: 1514

Answers (3)

ikegami
ikegami

Reputation: 385657

The following should get you the format:

use Win32::OLE::NLS qw( GetLocaleInfo GetSystemDefaultLCID LOCALE_SSHORTDATE );
say GetLocaleInfo(GetSystemDefaultLCID(), LOCALE_SSHORTDATE);  # yyyy-MM-dd

You could try to find a date parser that understands that format, or you could use something like the following to create a format many parsers to understand.

my %subs = (
   'yyyy' => '%Y',
   ...
);

my $pat = join '|', map quotemeta, sort { length($b) <=> length($a) } keys %subs;

$format =~ s{($pat)}{ $subs{$1} // $1 }eg;

Upvotes: 2

user1919238
user1919238

Reputation:

Update: see this discussion. It appears that the date format may be a regional setting based on the user who runs the task. If so, all you have to do is figure out how to get that regional setting...

As others have pointed out, there is no way of resolving the ambiguities in the potential date formats.

What I would explore is some way of querying the system with a known date and see what format it returns. For example, perhaps you could schedule a fake task at a (non-ambiguous) date far in the future, see what format that task is returned in, then later delete it.

That would be a bit of a messy solution, but perhaps there is a less kludgy way of doing something similar. Is task scheduler's date format the same as the system date format? If so, you could query a known date from the system.

Upvotes: 1

gaussblurinc
gaussblurinc

Reputation: 3682

I can tell you answer(algorithm) about your problem:

Once upon a time

Let's think about your problem:
You want to get date from every format.
But this is not possible, because it can be 12-11-10

Okay, now you must determine (somehow) which format is used.
If you can do that, you can rule the world.

Let's think about your problem more deeper:
First you must choose delimiter. (or not, if you don't want it)
it is possible to use something like this: (\d{1,4})(\D)(\d{1,4})(\D)(\d{1,4})

After that, you have:
$1,$3,$5 # parts of data
$2,$4 # delimiters

I took 4 because i don't know where year can be placed.

After that, you must understand, which format you have:

  • dd-mm-yy
  • mm-dd-yy
  • yy-mm-dd
  • yy-dd-mm

You can add checks for that like days or months, but, as I said before:
12-11-10 = -9 <- not possible to determine, right?

So, you must have some external info about date format, for example:

  • which country
  • which branch of science
  • which family
  • etc

it belongs to.

If you can do that, you can (probably can) determine format and 12-11-10 = 12 nov 2010

The End

Upvotes: 1

Related Questions