Perl equivalent of PHP's strtotime()? - perl

I realize that Perl has strftime, which allows you to pass a formatting object. The functionality I'm wondering if I can find is more like the following (from PHP):
$string1 = "Jun 6, 2012";
$string2 = "June 06 2012";
if (strtotime($string1) == strtotime($string2)) {
echo "BLAMMO!";
}
// will echo "BLAMMO!"
The reason for this is a business need in which user-provided dates need to be compared for validation and extended logic (does this date fall within another daterange also provided, etc). Now, I realize I can write an entire library devoted to doing this, and I realize there are any number of potential pitfalls with date-parsing and you should never trust user input, but here are some basic assumptions.
The input is actually output from any number of software packages that conform to their own internal specifications for date formatting. They all follow some standard, but those standards are not uniformly normalized between programs. That being said, I should always be comparing two dates from the same program, but I may never know what format they may follow.
I realize the standards of any given system are likely to be different, but the assumption here is that we're feeding ALL of our dates into the same thing, so we can trust a consistent implementation, hopefully something in CPAN or another easily updated module.

Date::Parse supplies str2time, which does this.
The documentation lists some examples that the module can parse:
1995:01:24T09:08:17.1823213 ISO-8601
1995-01-24T09:08:17.1823213
Wed, 16 Jun 94 07:29:35 CST Comma and day name are optional
Thu, 13 Oct 94 10:13:13 -0700
Wed, 9 Nov 1994 09:50:32 -0500 (EST) Text in ()'s will be ignored.
21 dec 17:05 Will be parsed in the current time zone
21-dec 17:05
21/dec 17:05
21/dec/93 17:05
1999 10:02:18 "GMT"
16 Nov 94 22:28:20 PST

The standard for date/time manipulation in Perl is the DateTime project.
https://metacpan.org/pod/DateTime

strptime for Perl can be obtained in the core module Time::Piece. This offer a core module solution whereas the rich DateTime module unfortunately isn't part of core Perl.

Related

Is there any function that easy converts MBox date format to Delphi TDateTime format?

MBox files, like Google Gmail export mailbox contains various types of data, among other things, the date of the mail message that interests me. The date of the message is in the format:
DayOfWeek, dd monthname yyyy hh:mm:ss +timezone
Mon, 03 Jun 2019 15:32:25 +0200
I was looking for some ready-made function in Delphi that I could translate a date string into TDateTime. If the whole string is impossible to parse to TDateTime, I can only try parse this part:
dd monthname yyyy hh:mm:ss
03 Jun 2019 15:32:25
but I admit that it is a bit of a hassle in my language to parse the month name. Could I ask for such a function if it exists? If such a ready-made function does not exist, I will make my own (or at least try).
Thank you in advance!
EDIT: SOLUTION
My guess is that this may not be useful to anyone, but if someone will have a similar problem, have a solution here. You can probably write it more elegantly, but it works.
// You can make your own formats here
const months : array[1..12,1..2] of string =
(('-01-',' Jan '),
('-02-',' Feb '),
('-03-',' Mar '),
('-04-',' Apr '),
('-05-',' May '),
('-06-',' Jun '),
('-07-',' Jul '),
('-08-',' Aug '),
('-09-',' Sep '),
('-10-',' Oct '),
('-11-',' Nov '),
('-12-',' Dec '));
function ChangeDateFormat(input: String): String;
var i: Integer;
begin
// day name and timezone is not needed, so we cut it
delete(input,1,Pos(',',input)+1);
delete(input,Pos('+',input)-1, Length(input));
for i := 1 to 12 do
input := StringReplace(input,
months[i,2],months[i,1],
[rfReplaceAll, rfIgnoreCase]);
result := Trim(input);
end;
For 'Date: Mon, 03 Jun 2019 15:32:25 +0200' mbox date string it looks like
WriteLn(ChangeDateFormat('Date: Mon, 03 Jun 2019 15:32:25 +0200'));
it gives back
03-06-2019 15:32:25
which is already recognized e.g. by Excel and allows sorting or other operations.
At the moment I haven't found any ready-made functions in Delphi.
It is also called RFC1123 format:
https://www.ietf.org/rfc/rfc1123.txt
kbmMW's date time features supports that and many other formats.
Eg.
var
dt:TkbmMWDateTime;
ndt:TDateTime;
begin
dt.RFC1123DateTime:='Mon, 03 Jun 2019 15:32:25 +0200';
ndt:=dt.Local; // ndt will contain the local time variant.
// If you want to get the UTC time variant use
// ndt:=dt.UTC
end;
This feature is included in kbmMW Community Edition, which is free and is available for various versions (incl. 10.4.2) of Delphi.
When Delphi 11 Community Edition is released, kbmMW Community Edition will follow. Notice that kbmMW Community Edition installs in all Delphi variants, also Pro, Ent and Architect.
kbmMW Community Edition is free to use, also for commercial use (within license limits).
Download kbmMW CE after registering at https://portal.components4developers.com

How to enter a YYYYMM date in Jekyll?

How should dates be entered in Jekyll?
I would like to enter the date "August 2018" in a YAML file to be used in Jekyll. I find lots of information on how to format already-existing dates, but pretty much nothing on how to enter them.
The best I have managed to find is Date formatting, which implies that dates entered in ISO 8601 format should be valid. If I run with this, then Wikipedia explicitly states
"2004-05" is a valid ISO 8601 date, which indicates May (the fifth
month) 2004.
This implies that "August 2018" could be entered as 2018-08.
However, when I use my YAML file my_data.yml in my _data folder
date: 2018-08
then Jekyll doesn't recognize it as a date as
{{ site.data.my_data.date | time: '%B %Y' }}
outputs "2018-08" and not "August 2018".
TL;DR: Enter YYYYMM dates such as "August 2018" as Aug 2018.
Searching through the Jekyll repo, I found the date filters. The Ruby on Rails method .to_formatted_s (source) seem to be key to most of them. In the source to that method dates are written as Tue, 04 Dec 2007 00:00:00 +0000 from which I guessed that I should write Aug 2018. Doing so in my_data.yml, the code outputs the expected “August 2018”.

Time::Piece is returning a wrong value

I am trying to convert date from yymmdd to YYYY-MM-DD with Time::Piece module. With the input as Nov 31, 2000 (20001131), I am getting output as 2000-12-01. In reality, Nov 31 doesn't even exists.
use Time::Piece;
my $dt_str = Time::Piece->strptime('20001131', '%Y%m%d')->strftime('%Y-%m-%d');
print $dt_str;
Am I missing something here?
Internally, it does only rough validation and error reporting, and then performs the same transformations as POSIX::mktime does; any days beyond the end of a month will just cause it to advance the produced date into the next month. This does seem a little inconsistent; since it allows that for days, I'd also expect it to treat '20005931' as '2004-12-01', but instead it errors out.

Date value as float - Apple's iWork Numbers 09 - internal XML

I am writing a script in PHP which will convert Numbers file into HTML table, but I can not figure out which format is used for date storage. The date cell tag looks like
<sf:d
sf:s="SFTCellStyle-128"
sf:w="84.074219"
sf:h="14"
sf:cell-date="371397519.99999952" />
so the date must be in sf:cell-date attribute, but I can not figure out how to convert it into human readable format. Any ideas? I have never seen date value as float number.
As written in a comment, it is the number of seconds since 01/01/2001 at 00:00:00. Equipped with that knowledge and because this goes hand in hand with the UNIX Epoch all you need to do is to define and use the offset. It should be compatible with nearly every of the existing PHP date functions and objects, for example with date:
define('CELL_DATE_EPOCH_OFFSET', 978307200);
$sf_cell_date = 371397519.99999952;
echo date('r', CELL_DATE_EPOCH_OFFSET + $sf_cell_date);
The output of this little script is (in my timezone):
Mon, 08 Oct 2012 15:58:39 +0200
I hope this is helpful. 978307200 is the unix timestamp for 01/01/2001 00:00:00 UTC, you can get with PHP for example with the following code-example:
$base = new DateTime('01/01/2001 00:00:00 UTC');
echo $base->getTimestamp(), "\n";
in case that was your problem.

Convert seconds to date from Jan 01 1901 in unix/linux

im trying to convert a time stamp in seconds from Jan 01 1901 to the current date.
for example,
time stamp 3465468225 translate to a date in 2010. does anyone know of a way to do this in unix/linux? thanks.
In R, it is as simple as this:
> as.POSIXct(3465468225, origin="1901-01-01")
[1] "2010-10-25 15:03:45 CDT"
>
This uses appropriate wrappers around C-level calls gmtime() / localtime() plus time formatting via strftime().
On GNU and POSIX systems you can obtain the date string using seconds since Epoch (1970-01-01 00:00:00 UTC) as:
$ date --date=#1289495920
Thu Nov 11 12:18:40 EST 2010
You should handle the offset since Jan 01 1901 yourself.