I am working with a date which is formatted like so:
25/02/1994 - 15/03/2000
To get each date I am using the explode function to separate each date between dash
$newdate = explode("-",$olddate);
Now my problem is, if it was just one date I could split it up in to 3 parts, the day, month, year and use the checkdate function to validate the month, but because I am using explode I cannot split it up like that (to my knowledge)
What would be the best way to validate the date for legitimacy?
You have a good start, after you exploded your string by -, just simply loop through each date with array_reduce() and reduce it to 1 value.
In the anonymous function you just explode() each date and check with checkdate() if it is a valid date, e.g.
<?php
$str = "25/02/1994 - 15/03/2000";
$dates = explode("-", $str);
if(array_reduce($dates, function($keep, $date){
list($day, $month, $year) = array_map("trim",explode("/", $date));
if(!checkdate($month, $day, $year))
return $keep = FALSE;
return $keep;
}, TRUE)) {
echo "all valid dates";
}
?>
$date = '25/02/1994 - 15/03/2000';
$date_array = explode("-", $date);
$first_date = explode("/", trim($date_array[0]));
$second_date = explode("/", trim($date_array[1]));
if(checkdate($first_date[1],$first_date[0],$first_date[2])){
//do stuff
}
if(checkdate($second_date[1],$second_date[0],$second_date[2])){
//do stuff
}
or, what Daan suggested using the DateTime object.
$date = '25/02/1994 - 15/03/2000';
$date_array = explode("-", $date);
$date1 = DateTime::createFromFormat('j-M-Y', $date_array[0]);
$date2 = DateTime::createFromFormat('j-M-Y', $date_array[1]);
if($date1){
//do stuff
}
if($date2){
//do stuff
}
Related
Im pulling column from excel with dates, and with the code i have to verify if row has date in it works fine for when dates in mm/dd/yyyy (07/05/2015) format. it passes date verify function and I'm able to grab that date and store it in mysql date formate column. but problem comes in when I'm reading excel file that has date format m/d/yy (7/5/15) I'm not sure at what point its failing but when i look at it database the dates are converted to weird dates and its skipping most of the dates from failing at date verify function. what i would like to do is convert the string I'm fetching from excel from m/d/yy to mm/dd/yyyy before it gets to date verify function. can anyone tell me how can i achieve that?
this is my function to verify if its date.
public function is_date( $str ) /// function to check if its date
{
$stamp = strtotime( $str );
if (!is_numeric($stamp))
return FALSE;
$month = date( 'm', $stamp );
$day = date( 'd', $stamp );
$year = date( 'Y', $stamp );
if (checkdate($month, $day, $year))
return TRUE;
return FALSE;
}
this is the part where it gets the date and sends to database
foreach(array_slice($sheetData, $dateRow-1) as $item)
{
$value = trim($item["{$revCol}"], "$");
$value = str_replace(",", "", $value);
$value = str_replace("?", "", $value);
//check if its date or garbage data
if ($this->is_date( $item["{$dateCol}"]) /* && $this->isCurrency($temp) */)
{
$key = $item["{$dateCol}"];
$key = date('Y-m-d', strtotime($key));
$sold = $item["{$soldCol}"];
$params = array('key' => $key);
$oldVal->execute($params);
$results = $oldVal->fetch(); // fetch old value before replacing with new
$old_rev = $results['rev'];
$old_sold = $results['sold'];
$diff_rev = $value - $old_rev;
$diff_rev = number_format($diff_rev, 2, '.', '');
$diff_sold = $sold - $old_sold;
//$insertDiff->execute(array($key, $diff_rev, $diff_sold));
$newVal->execute(array($key, $value, $diff_rev, $sold, $diff_sold));
}
}
Try this code to convert it ...
$date = "7/5/15";
$your_date = date("m/d/Y", strtotime($date));
echo $your_date;
It will echo 07/05/2015
Here you have the example online
You can format the column in Excel as a date with leading zeroes. That seems the quickest solution.
is this what you want? strtotime undestands such format
$str = '7/5/15';
echo date("m/d/Y", strtotime($str)); // 07/05/2015
strtotime should do the work.
Try replacing '/' by '-'
$stamp = strtotime( str_replace('/', '-' ,$str ) );
If not, the problem happen all time with the format m/d/yy or just in some cases (for example for days greater than 12 or something like that ?
I have a problem with comparing dates. I pull one date from a database through an API. These dates are stored in an array because one column contains multiple dates and I have to cycle through them to find the next upcoming date. The dates are in the format: 'dd/mm/yy'
$rawDate = $e->calendarsummary;
$filter = preg_replace("/[a-z]/","", $rawDate);
$createArray = explode(',', $filter);
$dates = array_filter(array_map('trim', $createArray));
foreach($dates as $d)
{
$dateTime = DateTime::createFromFormat('dmy', $d);
if($dateTime >= $now)
{
$finalDate = $dateTime;
$total = $finalDate->format('l j/m/y');
break;
}
}
If I place a var_export of $dateTime after $dateTime = DateTime::createFromFormat('dmy', $d); it returns 'false'. So I'm guessing $dateTime is empty although my array $dates is filled correctly.
a var_export of $dates returns:
array ( 0 => '15/06/13', 1 => '16/06/13', )
and a var export of $now returns todays date: '16/06/13'
So I'm a bit stuck why my variable $DateTime remains empty?
EDIT: Apparantly the return of 'false' means it's an error, so something went wrong when formatting my dates from the array?
If the $dates array contains elements such 15/06/13 so use just use wrong date format. E.g.:
$dateTime = DateTime::createFromFormat('d/m/y', $d);
$dateTime = DateTime::createFromFormat('d/m/y', $d);
not
$dateTime = DateTime::createFromFormat('dmy', $d);
Your dates are in format d/m/y, not dmy. Try the following instead:
$dateTime = DateTime::createFromFormat('d/m/y', $d);
When I do that, I get:
class DateTime#1 (3) { public $date => string(19) "2013-06-15 17:17:12" public $timezone_type => int(3) public $timezone => string(3) "UTC" }
... instead of bool(false).
you could use strtotime as a different method.
$now = date('d/m/y');
foreach($dates as $d)
{
if(strtotime($d) >= strtotime($now))
{
$finalDate = $dateTime;
$total = date('l j/m/y', strtotime($d));
break;
}
}
User enters the date as 8/1/11 or 08/1/11. Regardless of how the user inputs the date in my text field, I want to convert what they enter to my format of mm/dd/yyyy
So if the user enters 8/1/11 it would convert it to 08/01/2011.
Use strtotime() to transfer it into a time value, and then mktime() to transfer it to whatever format you want.
EDIT: Turns out it's not that simple.
You can't just print any date you'd like and transfer it to another, it'll be best to use some sort of UI on the client side to ensure the input matches, a great example is jQueryUI Datepicker
Check this.
It also checks if the date is valid (with checkdate) and converts years from short to long. When using short years, 0-69 is converted to 2000-2069 and 70-99 is converted to 1970-1999.
<?php
function cleanDate($input)
{
$parts = explode('/', $input);
if(count($parts) != 3) return false;
$month = (int)$parts[0];
$day = (int)$parts[1];
$year = (int)$parts[2];
if($year < 100)
{
if($year < 70)
{
$year += 2000;
}
else
{
$year += 1900;
}
}
if(!checkdate($month, $day, $year)) return false;
return sprintf('%02d/%02d/%d', $month, $day, $year);
// OR
$time = mktime(0, 0, 0, $month, $day, $year);
return date('m/d/Y', $time);
}
$test = array(
'08/01/2011', '8/1/11', '08/01/11', // Should all return 08/01/2011
'08/1/87', // Should return 08/01/1987
'32/1/93', '13', // Should fail: invalid dates
'02/29/2011', // Should fail: 2011 is not a leap year
'2/29/08'); // Should return 02/29/2008 (2008 is a leap year)
foreach($test as $t)
{
echo $t.' : '.(cleanDate($t) ?: 'false')."\n";
}
?>
Result:
08/01/2011 : 08/01/2011
8/1/11 : 08/01/2011
08/01/11 : 08/01/2011
08/1/87 : 08/01/1987
32/1/93 : false
13 : false
02/29/2011 : false
2/29/08 : 02/29/2008
<?php
$userInput = '08/1/11'; // or = '8/1/11' or = '08/01/11' or = '01/8/11'
$arr = explode('/', $userInput);
$formatted = sprintf("%1$02d", $arr[0]) . '/' . sprintf("%1$02d", $arr[1]) . '/20' . $arr[2];
?>
<?php
preg_match('#^(0?[1-9]|1[0-2])/(0?[1-9]|[12][0-9]|3[01])/(\d{2})$#',trim($date),$matches);
$month=str_pad($matches[1],2,'0',STR_PAD_LEFT);
$day=str_pad($matches[2],2,'0',STR_PAD_LEFT);
$year=$matches[3];
$result="{$month}/{$day}/{$year}";
?>
While #Truth is right that the user can do a lot to make it difficult, there IS actually a way to do a fairly decent job of parsing a date input box to work. It takes into account a variety of user input issues that may come up.
Note that it does make two assumptions:
That the local uses a date format of m/d/y
If the year is entered in short form, we are dealing with a 2000+ year
<?php
// Trim spaces from beginning/end
$date = trim(request($field));
// Allow for the user to have separated by spaces
$date = str_replace(" ", "/", $date);
// Allow for the user to have separated by dashes or periods
$date = str_replace("-", "/", str_replace(".", "/", trim($date)));
// Explode the date parts out to ensure a year
// Granted, this is geo-centric - you could adjust based on your locale
$dateparts = explode("/", $date);
// Check for a year. If not entered, assume this year
if (!isset($dateparts[2])) {$dateparts[2] = date("Y");}
// Force year to integer for comparison
$dateparts[2] = (int)$dateparts[2];
// Allow for user to use short year. Assumes all dates will be in the year 2000+
if ($dateparts[2] < 2000) {$dateparts[2]+= 2000;}
// Re-assemble the date to a string
$date = implode("/", $dateparts);
// Utilize strtotime and date to convert date to standard format
$date = date("m/d/Y", strtotime($date));
?>
Disclaimer: Yes, this is the verbose way of doing this, however I did so for clarity of the example, not for efficiency.
I have a date in this format 2068-06-15. I want to get the year from the date, using php functions. Could someone please suggest how this could be done.
$date = DateTime::createFromFormat("Y-m-d", "2068-06-15");
echo $date->format("Y");
The DateTime class does not use an unix timestamp internally, so it han handle dates before 1970 or after 2038.
You can use the strtotime and date functions like this:
echo date('Y', strtotime('2068-06-15'));
Note however that PHP can handle year upto 2038
You can test it out here
If your date is always in that format, you can also get the year like this:
$parts = explode('-', '2068-06-15');
echo $parts[0];
I would use this:
$parts = explode('-', '2068-06-15');
echo $parts[0];
It appears the date is coming from a source where it is always the same, much quicker this way using explode.
You can try strtotime() and date() functions for output in minimum code and using standard way.
echo date('Y', strtotime('2068-06-15'));
output: 2068
echo date('y', strtotime('2068-06-15'));
output: 68
public function getYear($pdate) {
$date = DateTime::createFromFormat("Y-m-d", $pdate);
return $date->format("Y");
}
public function getMonth($pdate) {
$date = DateTime::createFromFormat("Y-m-d", $pdate);
return $date->format("m");
}
public function getDay($pdate) {
$date = DateTime::createFromFormat("Y-m-d", $pdate);
return $date->format("d");
}
<?php
list($year) = explode("-", "2068-06-15");
echo $year;
?>
You can achieve your goal by using php date() & explode() functions:
$date = date("2068-06-15");
$date_arr = explode("-", $date);
$yr = $date_arr[0];
echo $yr;
That is it. Happy coding :)
Assuming you have the date as a string (sorry it was unclear from your question if that is the case) could split the string on the - characters like so:
$date = "2068-06-15";
$split_date = split("-", $date);
$year = $split_date[0];
$Y_date = split("-","2068-06-15");
$year = $Y_date[0];
You can use explode also
You wrote that format can change from YYYY-mm-dd to dd-mm-YYYY you can try to find year there
$parts = explode("-","2068-06-15");
for ($i = 0; $i < count($parts); $i++)
{
if(strlen($parts[$i]) == 4)
{
$year = $parts[$i];
break;
}
}
If I've got a date string:
$date = "08/20/2009";
And I want to separate each part of the date:
$m = "08";
$d = "20";
$y = "2009";
How would I do so?
Is there a special date function I should be using? Or something else?
Thanks!
One way would be to do this:
$time = strtotime($date);
$m = date('m', $time);
$d = date('d', $time);
$y = date('Y', $time);
explode will do the trick for that:
$pieces = explode("/", $date);
$d = $pieces[1];
$m = $pieces[0];
$y = $pieces[2];
Alternatively, you could do it in one line (see comments - thanks Lucky):
list($m, $d, $y) = explode("/", $date);
Check out PHP's date_parse function. Unless you're sure input will always be in a consistent format, AND you validate it first, it is much more stable and flexible, (not to mention easier), to let PHP try to parse the format for you.
e.g.
<?php
//Both inputs should return the same Month-Day-Year
print_r(date_parse("2012-1-12 51:00:00.5"));
print_r(date_parse("1/12/2012"));
?>
If you have a given format you should use a date object.
$date = DateTime::createFromFormat('m/d/Y', '08/20/2009');
$m = $date->format('m');
$d = $date->format('d');
$y = $date->format('Y');
Note you can certainly use only one call to DateTime::format().
$newFormat = $date->format('d-m-Y');
Is it always like that? Or will it be in any sort of file format?
Try strtotime.
Something like:
if(($iTime = strtotime($strDate))!==false)
{
echo date('m', $iTime);
echo date('d', $iTime);
echo date('y', $iTime);
}
how about this:
list($m, $d, $y) = explode("/", $date);
A quick one liner.
For internationalized date parsing, see IntlDateFormatter::parse - http://php.net/manual/en/intldateformatter.parse.php
For example:
$f = new \IntlDateFormatter('en_gb', \IntlDateFormatter::SHORT, \IntlDateFormatter::NONE);
$dt = new \DateTime();
$dt->setTimestamp($f->parse('1/2/2015'));
Dominic's answer is good, but IF the date is ALWAYS in the same format you could use this:
$m = substr($date,0,2);
$d = substr($date,3,2);
$y = substr($date,-4);
and not have to use an array or explode
Bill H