Convert dates into a new format - php

I have a document with a bunch of dates, always wrapped in tags and always in a specific format.
$text = '...<dt>31 DEC 1793</dt>... ...<dt>14 JAN 1934</dt>...';
I'm trying to replace this text to include the day of the week:
$text = '...<dt>Tuesday, 31 DEC 1793</dt>... ...<dt>Sunday, 14 JAN 1934</dt>...';
Right now I'm trying to use preg_replace to achieve this, but it just gives me the current date.
$text = preg_replace('/<dt>(\d{1,2} [A-Z]{3} \d{4})<\/dt>/i', "<dt>".date('l', strtotime("$1")).", $1</dt>", $text);
It seems like the date function just runs once, instead of each time a replace happens. How could I make this work?

You need to run the date and strtotime functions inside a callback:
$text = '...<dt>31 DEC 1793</dt>... ...<dt>14 JAN 1934</dt>...';
$text = preg_replace_callback(
'/<dt>(\d{1,2} [A-Z]{3} \d{4})<\/dt>/i',
function ($matches) {
$date = $matches[1];
return "<dt>".date('l', strtotime($date)).", ".$date."</dt>";
},
$text
);
// $text = '...<dt>Tuesday, 31 DEC 1793</dt>... ...<dt>Sunday, 14 JAN 1934</dt>...';

Related

Detecting a specific date type in PHP string

Ok, i'm using a library to get some strings from X website, this string looks like:
Mar 17 2019, 16:08:43 CET Died at Level 418 by Gaz'haragoth.
if($player->getDeaths()) {
$mystring = $player->getDeaths()[0];
$dateString = preg_replace("/\([^)]+\)/","",$mystring);
$date = new DateTime($dateString);
echo $date->format('Y-m-d H:i:s');
}
This is how my code looks looks like right now, how can I get only "Mar 17 2019, 16:08:43"?
Thanks!
echo substr("Mar 17 2019, 16:08:43 CET Died at Level 418 by Gaz'haragoth.", 0, 21);
Can use regex search of
(.*?)[0-9]+[:][0-9]+[:][0-9]+
on the string. Gets everything before the hh:mm:ss tag and nothing after
Getting substring upto a certain position too would work if it will be the same length every time.
If the first half of the string (the date) is standard you can also use this without any regex needed:
$output_str = implode(" ",array_splice(explode(" ",$input_str),0,4));
You can use DateTime::createFromFormat to create a DateTime object from that string.
$string = "Mar 17 2019, 16:08:43 CET Died at Level 418 by Gaz'haragoth.";
$date = DateTime::createFromFormat('M d Y, H:i:s T+', $string);
Then you can output from that in whatever format you like.
You may not really need a DateTime object though. If all you need to do is strip off the trailing text it seems like substr would be the simplest way, as long as your day is formatted with a leading zero the date part of the string should always be the same length.
Try
<?php
$str = "Mar 17 2019, 16:08:43 CET Died at Level 418 by Gaz'haragoth";
echo preg_replace('/^(.+\d+:\d+:\d+).+$/', '$1', $str);
?>

Adding and removing from a string containing dates using PHP

I have to edit a whole bunch of date intervals. But they are all mixed up. Most are in the form Month YearMonth Year
eg January 2014March 2015
How would I insert a hyphen in between so I end up with
January 2014 - March 2015
I also have the problem where these dates occur in the same year.
eg April 2012September2012
In such a case I would need to insert the hyphen and remove the year so that I'm left with
April - September
There must be some PHP string operators for stuff like this. Well thats what I'm hoping.
Would appreciate some guidance. Thanks in advance.
Thanks, sorry for my delayed reply
$string = "January 2014March 2015";
preg_match('/([a-z]+) *(\d+) *([a-z]+) *(\d+)/i', $string, $match);
print "$match[1] $match[2] - $match[3] $match[4]";
outputs,
January 2014 - March 2015
You could do it using lookaround:
$string = "January 2014March 2015";
$res = preg_replace('/(?<=\d)(?=[A-Z])/', ' - ', $string);
echo $res,"\n";
Output:
January 2014 - March 2015

Remove certain characters of array variable?

I would like to remove the last certain characters of following array api variable 'min_date_created' like
$filter = array('min_date_created' => "$start_date");//query filter
Here the values of
'min_date_created'=Mon, 24 Sep 2012 00:53:26 +0000
So i want to remove the last 15 characters, so i expect the following format
'min_date_created'=Mon, 24 Sep 2012
So please any one help me how can i change this array variable 'min_date_created' in required format.
You can format using the date & strtotime function like below
http://in3.php.net/strtotime
<?php
//format the date
$min_date_created = date('D, d M Y', strtotime($start_date));
$filter = array('min_date_created'=>$min_date_created);
Expanding Sundar's Answer , You can achieve simpler using an array_walk to do modify all the array elements in a single go.
<?php
$startdate="Mon, 24 Sep 2012 00:53:26 +0000"; // Usually you will be getting from a POST variable.
$filter = array('min_date_created' => $startdate);
array_walk($filter,'formatDT');
function formatDT(&$v,$k)
{
$v=date('D, d M Y', strtotime($v));
}
print_r($filter);
OUTPUT :
Array
(
[min_date_created] => Mon, 24 Sep 2012
)
You could use substr to remove the last 15 characters from $start_date before using it in the array.
$filter = array('min_date_created' => substr($start_date, 0, -15));
Output
array (
'min_date_created' => 'Mon, 24 Sep 2012',
)

Extract dates, times and date ranges from text in PHP

I'm building a local events calendar which takes RSS feeds and website scrapes and extracts event dates from them.
I've previously asked how to extract dates from text in PHP here, and received a good answer at the time from MarcDefiant:
function parse_date_tokens($tokens) {
# only try to extract a date if we have 2 or more tokens
if(!is_array($tokens) || count($tokens) < 2) return false;
return strtotime(implode(" ", $tokens));
}
function extract_dates($text) {
static $patterns = Array(
'/^[0-9]+(st|nd|rd|th|)?$/i', # day
'/^(Jan(uary)?|Feb(ruary)?|Mar(ch)?|etc)$/i', # month
'/^20[0-9]{2}$/', # year
'/^of$/' #words
);
# defines which of the above patterns aren't actually part of a date
static $drop_patterns = Array(
false,
false,
false,
true
);
$tokens = Array();
$result = Array();
$text = str_word_count($text, 1, '0123456789'); # get all words in text
# iterate words and search for matching patterns
foreach($text as $word) {
$found = false;
foreach($patterns as $key => $pattern) {
if(preg_match($pattern, $word)) {
if(!$drop_patterns[$key]) {
$tokens[] = $word;
}
$found = true;
break;
}
}
if(!$found) {
$result[] = parse_date_tokens($tokens);
$tokens = Array();
}
}
$result[] = parse_date_tokens($tokens);
return array_filter($result);
}
# test
$texts = Array(
"The focus of the seminar, on Saturday 2nd February 2013 will be [...]",
"Valentines Special # The Radisson, Feb 14th",
"On Friday the 15th of February, a special Hollywood themed [...]",
"Symposium on Childhood Play on Friday, February 8th",
"Hosting a craft workshop March 9th - 11th in the old [...]"
);
$dates = extract_dates(implode(" ", $texts));
echo "Dates: \n";
foreach($dates as $date) {
echo " " . date('d.m.Y H:i:s', $date) . "\n";
}
However, the solution has some downsides - for one thing, it can't match date ranges.
I'm now looking for a more complex solution that can extract dates, times and date ranges from sample text.
Whats the best approach for this? It seems like I'm leaning back toward a series of regex statements run one after the other to catch these cases. I can't see a better way of catching date ranges in particular, but I know there must be a better way of doing this. Are there any libraries out there just for date parsing in PHP?
Date / Date Range samples, as requested
$dates = [
" Saturday 28th December",
"2013/2014",
"Friday 10th of January",
"Thursday 19th December",
" on Sunday the 15th December at 1 p.m",
"On Saturday December 14th ",
"On Saturday December 21st at 7.30pm",
"Saturday, March 21st, 9.30 a.m.",
"Jan-April 2014",
"January 21st - Jan 24th 2014",
"Dec 30th - Jan 3rd, 2014",
"February 14th-16th, 2014",
"Mon 14 - Wed 16 April, 12 - 2pm",
"Sun 13 April, 8pm",
"Mon 21 - Wed 23 April",
"Friday 25 April, 10 – 3pm",
"The focus of the seminar, on Saturday 2nd February 2013 will be [...]",
"Valentines Special # The Radisson, Feb 14th",
"On Friday the 15th of February, a special Hollywood themed [...]",
"Symposium on Childhood Play on Friday, February 8th",
"Hosting a craft workshop March 9th - 11th in the old [...]"
];
The function I'm currently using (not the above) is about 90% accurate. It can catch date ranges, but has difficulty if a time is also specified. It uses a list of regex expressions and is very convoluted.
UPDATE: Jan 6th, 2014
I'm working on code that does this, working on my original method of a series of regex statements run one after the other. I think I'm close to a working solution that can pretty much extract almost any date/time range / format from a piece of text. When I'm done I'll post it here as an answer.
I think you can sum up the regex in your question like the one below.
(?<date_format_1>(?<day>(?i)\b\s*[0-9]+(?:st|nd|rd|th|)?)(?<month>(?i)\b\s*(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|etc))(?<year>\b\s*20[0-9]{2}) ) |
(?<date_format_2>(?&month)(?&day)(?!\s+-)) |
(?<date_format_3>(?&day)\s+of\s+(?&month)) |
(?<range_type_1>(?&month)(?&day)\s+-\s+(?&day))
Flags: x
Description
Demo
http://regex101.com/r/wP5fR4
Discussion
By using recursive subpatterns, you reduce the complexity of the final regex.
I have used a negative lookahead in the date_format_2 because it would match partially range_type_1. You may need to add more range type depending on your data. Don't forget to check other partterns in case of partial match.
Another solution would consist in build small regexes in different string variables and then concatenate them in PHP to build a bigger regex.

Unrecognized Date format

Good !
I am having some difficulties with extracting data from a date. The thing is that I get a number from an undocumented API.
"created": 734394
"last_chapter_date": 734883
I tried dividing it by 365,242 days (exact amount of days a year)
2010,705231052289
So apparently these are the number of days passed since 0.0.0000
I am currently trying something like that:
http://jsfiddle.net/LRUy5/4/
function zero21970(nDays) {
// 0 70 2013
// |-----|-----|
// 0 to date
var dateMils = nDays*24*60*60*100;
// 0 to 1970
zeroTo1970 = (1970*365.242)*24*60*60*100;
//subtract time from 0-1970 from the time 0-date
//to cut out the part from 1970-today
return new Date(dateMils-zeroTo1970);
}
//http://www.mangaeden.com/api/manga/4e70e9f6c092255ef7004344/
zero21970(734394) //-> Jan 26 1974
I need to save it in a database and work with it via php or javascript..
Does anyone recognize this kind of format or do you know a convenient way of formatting it?
Edit: I should add that the last chapter came out around 15.01.2013.. just to have something to grab.
Updated version:
I guess if the last chapter was from 2013, then the value is a number of days from 01.01.0001. So we can update the initial date as well as change setHours to setDate method for more accuracy:
var date = new Date("0001");
date.setDate(734883);
date.toGMTString(); // "Tue, 15 Jan 2013 00:00:00 GMT"
DEMO: http://jsfiddle.net/LRUy5/6/
Old version:
I found one solution that successfully works at my computer:
var date = new Date("0000");
date.setHours(734394 * 24);
date.toGMTString(); // "Mon, 13 Sep 2010 21:00:00 GMT"
DEMO: http://jsfiddle.net/LRUy5/5/
If you're using PHP, then you should replace
return new Date(dateMils-zeroTo1970);
with
return date('Y-m-d', (dateMils-zeroTo1970));

Categories