Create Datetime object from string - php

I have a situation where I need to create a Datetime object from a string.
The issue comes when I don't have consistency in the pattern of the string representing the date.
These are examples of my data:
07/17/2012
2013/03/11
17/05/2015
17/17/2015
As you can see, the last one is invalid no matter what, because there is no 17 month, but the first 3 are valid depending on the month position(and of course, the year)
My question: is there any way(pretty sure through regex) to make a function with the date string as parameter that return the datetime object. If the string is not valid, return: 1/1/1970...

The issue comes when I don't have consistency in the pattern of the string representing the date
for this purpose, php offers strtotime(): http://php.net/manual/en/function.strtotime.php
Example usage:
$str1 = "2015-06-04 16:00";
$str2 = "06/04/2015 4 pm";
$str3 = "04.06.2015 16:00";
$actualDate = date("Y-m-d H:i:s", strtotime($str1));
echo $actualDate."<br />";
$actualDate = date("Y-m-d H:i:s", strtotime($str2));
echo $actualDate."<br />";
$actualDate = date("Y-m-d H:i:s", strtotime($str3));
echo $actualDate."<br />";
//all will produce "2015-06-04 16:00:00"
as a bonus, strtotime also supports "insane" expressions like
$actualDate = date("Y-m-d H:i:s", strtotime("06/04/2015 + 1 day - 8 hours"));
echo $actualDate."<br />";
// "2015-06-04 16:00:00"
and many more such as "monday this week", "tuesday next week", "first monday of january 2038" and the like.

You can try to create DateTime Object with your string values. It will throw exception if the date format is not valid, then you can just catch it and return your 1/1/1971
try {
$dateTime = new DateTime('17/17/2015');
return $dateTime;
} catch (Exception $e) {
return '1/1/1971';
}

You can use DateTime.
$myDate = '17/17/2015';
$date = DateTime::createFromFormat('d/m/Y', $myDate);
if (DateTime::getLastErrors()['warning_count'] >= 1) {
// Invalid
} else {
// Valid date
}

Related

loop to go between two dates and output dates in unix format? [duplicate]

How do I get timestamp from e.g. 22-09-2008?
This method works on both Windows and Unix and is time-zone aware, which is probably what you want if you work with dates.
If you don't care about timezone, or want to use the time zone your server uses:
$d = DateTime::createFromFormat('d-m-Y H:i:s', '22-09-2008 00:00:00');
if ($d === false) {
die("Incorrect date string");
} else {
echo $d->getTimestamp();
}
1222093324 (This will differ depending on your server time zone...)
If you want to specify in which time zone, here EST. (Same as New York.)
$d = DateTime::createFromFormat(
'd-m-Y H:i:s',
'22-09-2008 00:00:00',
new DateTimeZone('EST')
);
if ($d === false) {
die("Incorrect date string");
} else {
echo $d->getTimestamp();
}
1222093305
Or if you want to use UTC. (Same as "GMT".)
$d = DateTime::createFromFormat(
'd-m-Y H:i:s',
'22-09-2008 00:00:00',
new DateTimeZone('UTC')
);
if ($d === false) {
die("Incorrect date string");
} else {
echo $d->getTimestamp();
}
1222093289
Regardless, it's always a good starting point to be strict when parsing strings into structured data. It can save awkward debugging in the future. Therefore I recommend to always specify date format.
There is also strptime() which expects exactly one format:
$a = strptime('22-09-2008', '%d-%m-%Y');
$timestamp = mktime(0, 0, 0, $a['tm_mon']+1, $a['tm_mday'], $a['tm_year']+1900);
Warnings:
This function is not implemented on Windows
This function has been DEPRECATED as of PHP 8.1.0. Relying on this function is highly discouraged.
With DateTime API:
$dateTime = new DateTime('2008-09-22');
echo $dateTime->format('U');
// or
$date = new DateTime('2008-09-22');
echo $date->getTimestamp();
The same with the procedural API:
$date = date_create('2008-09-22');
echo date_format($date, 'U');
// or
$date = date_create('2008-09-22');
echo date_timestamp_get($date);
If the above fails because you are using a unsupported format, you can use
$date = DateTime::createFromFormat('!d-m-Y', '22-09-2008');
echo $dateTime->format('U');
// or
$date = date_parse_from_format('!d-m-Y', '22-09-2008');
echo date_format($date, 'U');
Note that if you do not set the !, the time portion will be set to current time, which is different from the first four which will use midnight when you omit the time.
Yet another alternative is to use the IntlDateFormatter API:
$formatter = new IntlDateFormatter(
'en_US',
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
'GMT',
IntlDateFormatter::GREGORIAN,
'dd-MM-yyyy'
);
echo $formatter->parse('22-09-2008');
Unless you are working with localized date strings, the easier choice is likely DateTime.
Be careful with functions like strtotime() that try to "guess" what you mean (it doesn't guess of course, the rules are here).
Indeed 22-09-2008 will be parsed as 22 September 2008, as it is the only reasonable thing.
How will 08-09-2008 be parsed? Probably 09 August 2008.
What about 2008-09-50? Some versions of PHP parse this as 20 October 2008.
So, if you are sure your input is in DD-MM-YYYY format, it's better to use the solution offered by #Armin Ronacher.
This method works on both Windows and Unix and is time-zone aware, which is probably what you want if you work with dates.
If you don't care about timezone, or want to use the time zone your server uses:
$d = DateTime::createFromFormat('d-m-Y H:i:s', '22-09-2008 00:00:00');
if ($d === false) {
die("Incorrect date string");
} else {
echo $d->getTimestamp();
}
1222093324 (This will differ depending on your server time zone...)
If you want to specify in which time zone, here EST. (Same as New York.)
$d = DateTime::createFromFormat(
'd-m-Y H:i:s',
'22-09-2008 00:00:00',
new DateTimeZone('EST')
);
if ($d === false) {
die("Incorrect date string");
} else {
echo $d->getTimestamp();
}
1222093305
Or if you want to use UTC. (Same as "GMT".)
$d = DateTime::createFromFormat(
'd-m-Y H:i:s',
'22-09-2008 00:00:00',
new DateTimeZone('UTC')
);
if ($d === false) {
die("Incorrect date string");
} else {
echo $d->getTimestamp();
}
1222093289
Regardless, it's always a good starting point to be strict when parsing strings into structured data. It can save awkward debugging in the future. Therefore I recommend to always specify date format.
Using mktime:
list($day, $month, $year) = explode('-', '22-09-2008');
echo mktime(0, 0, 0, $month, $day, $year);
Using strtotime() function you can easily convert date to timestamp
<?php
// set default timezone
date_default_timezone_set('America/Los_Angeles');
//define date and time
$date = date("d M Y H:i:s");
// output
echo strtotime($date);
?>
More info: http://php.net/manual/en/function.strtotime.php
Online conversion tool: http://freeonlinetools24.com/
Here is a very simple and effective solution using the split and mtime functions:
$date="30/07/2010 13:24"; //Date example
list($day, $month, $year, $hour, $minute) = split('[/ :]', $date);
//The variables should be arranged according to your date format and so the separators
$timestamp = mktime($hour, $minute, 0, $month, $day, $year);
echo date("r", $timestamp);
It worked like a charm for me.
Use PHP function strtotime()
echo strtotime('2019/06/06');
date — Format a local time/date
Given that the function strptime() does not work for Windows and strtotime() can return unexpected results, I recommend using date_parse_from_format():
$date = date_parse_from_format('d-m-Y', '22-09-2008');
$timestamp = mktime(0, 0, 0, $date['month'], $date['day'], $date['year']);
If you know the format use strptime because strtotime does a guess for the format, which might not always be correct. Since strptime is not implemented in Windows there is a custom function
http://nl3.php.net/manual/en/function.strptime.php#86572
Remember that the returnvalue tm_year is from 1900! and tm_month is 0-11
Example:
$a = strptime('22-09-2008', '%d-%m-%Y');
$timestamp = mktime(0, 0, 0, $a['tm_mon']+1, $a['tm_mday'], $a['tm_year']+1900)
If you want to know for sure whether a date gets parsed into something you expect, you can use DateTime::createFromFormat():
$d = DateTime::createFromFormat('d-m-Y', '22-09-2008');
if ($d === false) {
die("Woah, that date doesn't look right!");
}
echo $d->format('Y-m-d'), PHP_EOL;
// prints 2008-09-22
It's obvious in this case, but e.g. 03-04-2008 could be 3rd of April or 4th of March depending on where you come from :)
<?php echo date('M j Y g:i A', strtotime('2013-11-15 13:01:02')); ?>
http://php.net/manual/en/function.date.php
$time = '22-09-2008';
echo strtotime($time);
function date_to_stamp( $date, $slash_time = true, $timezone = 'Europe/London', $expression = "#^\d{2}([^\d]*)\d{2}([^\d]*)\d{4}$#is" ) {
$return = false;
$_timezone = date_default_timezone_get();
date_default_timezone_set( $timezone );
if( preg_match( $expression, $date, $matches ) )
$return = date( "Y-m-d " . ( $slash_time ? '00:00:00' : "h:i:s" ), strtotime( str_replace( array($matches[1], $matches[2]), '-', $date ) . ' ' . date("h:i:s") ) );
date_default_timezone_set( $_timezone );
return $return;
}
// expression may need changing in relation to timezone
echo date_to_stamp('19/03/1986', false) . '<br />';
echo date_to_stamp('19**03**1986', false) . '<br />';
echo date_to_stamp('19.03.1986') . '<br />';
echo date_to_stamp('19.03.1986', false, 'Asia/Aden') . '<br />';
echo date('Y-m-d h:i:s') . '<br />';
//1986-03-19 02:37:30
//1986-03-19 02:37:30
//1986-03-19 00:00:00
//1986-03-19 05:37:30
//2012-02-12 02:37:30
<?php echo date('U') ?>
If you want, put it in a MySQL input type timestamp. The above works very well (only in PHP 5 or later):
<?php $timestamp_for_mysql = date('c') ?>
Here is how I'd do it:
function dateToTimestamp($date, $format, $timezone='Europe/Belgrade')
{
//returns an array containing day start and day end timestamps
$old_timezone=date_timezone_get();
date_default_timezone_set($timezone);
$date=strptime($date,$format);
$day_start=mktime(0,0,0,++$date['tm_mon'],++$date['tm_mday'],($date['tm_year']+1900));
$day_end=$day_start+(60*60*24);
date_default_timezone_set($old_timezone);
return array('day_start'=>$day_start, 'day_end'=>$day_end);
}
$timestamps=dateToTimestamp('15.02.1991.', '%d.%m.%Y.', 'Europe/London');
$day_start=$timestamps['day_start'];
This way, you let the function know what date format you are using and even specify the timezone.
If you already have the date in that format, you only need to call the "strtotime" function in PHP.
$date = '22-09-2008';
$timestamp = strtotime($date);
echo $timestamp; // 1222041600
Or in a single line:
echo strtotime('22-09-2008');
Short and simple.
For PHP >=5.3, 7 & 8 the this may work-
$date = date_parse_from_format('%Y-%m-%d', "2022-11-15"); //here you can give your desired date in desired format.
//just need to keep in mind that date and format matches.
$timestamp = mktime(0, 0, 0, $date['month'], $date['day'], $date['year'] + 2000); //this will return the timestamp
$finalDate= date('Y-m-d H:i:s', $timestamp); //now you can convert your timestamp to desired dateTime format.
Docs:
date_parse_from_format()
mktime()
date()
Please be careful about time/zone if you set it to save dates in database, as I got an issue when I compared dates from mysql that converted to timestamp using strtotime. you must use exactly same time/zone before converting date to timestamp otherwise, strtotime() will use default server timezone.
Please see this example: https://3v4l.org/BRlmV
function getthistime($type, $modify = null) {
$now = new DateTime(null, new DateTimeZone('Asia/Baghdad'));
if($modify) {
$now->modify($modify);
}
if(!isset($type) || $type == 'datetime') {
return $now->format('Y-m-d H:i:s');
}
if($type == 'time') {
return $now->format('H:i:s');
}
if($type == 'timestamp') {
return $now->getTimestamp();
}
}
function timestampfromdate($date) {
return DateTime::createFromFormat('Y-m-d H:i:s', $date, new DateTimeZone('Asia/Baghdad'))->getTimestamp();
}
echo getthistime('timestamp')."--".
timestampfromdate(getthistime('datetime'))."--".
strtotime(getthistime('datetime'));
//getthistime('timestamp') == timestampfromdate(getthistime('datetime')) (true)
//getthistime('timestamp') == strtotime(getthistime('datetime')) (false)
I have used this format:
$presentDateTime = strtotime(date('Y-m-d H:i:s'));
If you're looking to convert a UTC datetime (2016-02-14T12:24:48.321Z) to timestamp, here's how you'd do it:
function UTCToTimestamp($utc_datetime_str)
{
preg_match_all('/(.+?)T(.+?)\.(.*?)Z/i', $utc_datetime_str, $matches_arr);
$datetime_str = $matches_arr[1][0]." ".$matches_arr[2][0];
return strtotime($datetime_str);
}
$my_utc_datetime_str = '2016-02-14T12:24:48.321Z';
$my_timestamp_str = UTCToTimestamp($my_utc_datetime_str);

PHP date function giving a random number

Hello i'm making a php script to send an email on a client's birthday, basicly i'm looping through every client's birthdates and checking with today's date and if they match, an email is sent. Although the date function is giving a random number instead of today's date, the number is: 1505451600.
Maybe i'm doing something wrong in the code? Does anyone know a way to fix this?
$get_birthday = $DB_con->prepare("SELECT email, dt_nascimento FROM clientes");
if ($get_birthday->execute()) {
while ($array_birthday = $get_birthday->fetch(PDO::FETCH_ASSOC)) {
$birthdate = date('m d', strtotime($array_birthday['dt_nascimento']));
// echo "</br> data:".$array_birthday['dt_nascimento'];
// echo "</br>".$birthdate;
$now = date("m/d");
$now = strtotime($now);
// echo "</br>now: ".$now;
$email = $array_birthday['email'];
if ($now == $birthdate) {
include"PHPMailer/email_birthday.php";
}
}
}
There are 2 changes you need to make for your code to work:
(1) Remove this line:
$now = strtotime($now);
Reason: You don't want a timestamp. You want a formatted date.
(2) Change "m d" on this line:
$birthdate = date('m d', strtotime($array_birthday['dt_nascimento']));
to "m/d" like so:
$birthdate = date('m/d', strtotime($array_birthday['dt_nascimento']));
Reason: you need to format $birthdate and $now the same way to make the comparison work.
I remove the $now conversion to timestamp and change the $birthdate format to the same as $now.
This is the working code :
$get_birthday = $DB_con->prepare("SELECT email, dt_nascimento FROM clientes");
if ($get_birthday->execute()) {
while ($array_birthday = $get_birthday->fetch(PDO::FETCH_ASSOC)) {
$birthdate = date('m d', strtotime($array_birthday['dt_nascimento']));
// echo "</br> data:".$array_birthday['dt_nascimento'];
// echo "</br>".$birthdate;
$now = date("m d");
// echo "</br>now: ".$now;
$email = $array_birthday['email'];
if ($now == $birthdate) {
include"PHPMailer/email_birthday.php";
}
}
}
The reason it gives you a number is how computers measure time is the number of seconds since 1/1/1970 00:00 (UTC (Universal Time)).
1505451600 Is equivalent to: 09/15/2017 # 5:00am (UTC)
this happens because:
date("m/d") returns 9/15 (today month/day)
then strtotime tries to convert this string into unix timestamp, as soon as year is not in string, current year (2017) is assumed
as soon as time part is not there, midnight in your timezone is assumed (5am utc)
this is why final time is 1505451600

check date in php not working with different month

here i am checking the date with current date to previous date it show the proper message when the subtracted date's result is current date .but when the subtracted result is previous date like 02-12-2014 - 4 days it gives 28-11-2014 .and condition of (02-12-2014>=28-11-2014) it gives false.why it cant check the diff of diff month's date. even it true the condition when date like (04-12-2014>=06-12-2014).
<div class="box-content">
<div class="maq_cont">
<marquee direction="up" scrollamount="3" onMouseOut="this.setAttribute('scrollamount',3,0)" onMouseOver="this.setAttribute('scrollamount', 0, 0)" style="height:200px; margin-top:-10px; margin-bottom:-10px;">
<ul class="maq_li">
<?php
echo $work_date = "03-12-2014";
echo "<br>";
echo $day = "3";
echo "<br>";
echo $show_date = date( "d-m-Y", strtotime( "$work_date -$day day" ));
echo "<br>";
echo $cur_date= date( "d-m-Y" );
if ($cur_date >= $show_date) {
echo '<li>done</li>';
} else {
echo '<li>not done</li>';
}
?>
</ul>
</marquee>
</div>
</div>
Try with -
if(strtotime($cur_date)>=strtotime($show_date)){
It is happening because they are strings.
You have to put the year at the beginning of your date string, then month and then the day. The reason is: You aren't comparing dates, you compare string. And they will be compared alphabetically.
e.g. the string date '01.01.2015' is alphabetically smaller than '02.01.2013', but this format ('Ymd') does the trick in this special order: '20150101' is alphabetically and also numerically greater than '20130102'.
// this formatting will work
$show_date = date('Ymd', strtotime("$work_date -$day day"));
$cur_date = date('Ymd');
I would prefer to do this comparison with date and the awesome DateTime object. Do it like this:
if (new DateTime('NOW')
>= DateTime::createFromFormat('d-m-Y', $show_date))
{
echo '<li>done</li>';
} else {
echo '<li>not done</li>';
}
The DateTime::createFromFormat() call returns a DateTime object. The first parameter $format has the same syntax like your format string you are using with date(). The second parameter is the so formatted date string to parse. Read more:
http://php.net/manual/en/datetime.createfromformat.php
After getting this DateTime object you can do some magic like
$date = DateTime::createFromFormat('d-m-Y', $show_date);
$date->modify('+1 days'); // one day later
And to output the date as string use the format()function:
$date->format('Y'); // the year
$date->format('m'); // the month
$date->format('d'); // the day
$date->format('Y-m-d H:i:s'); // e.g. 2014-12-05 23:11:00
$date->format('U'); // as timestamp: 1417817460
// [...]
More Information:
http://php.net/manual/en/datetime.format.php
http://php.net/manual/en/datetime.modify.php
http://php.net/manual/en/function.date.php

Checking a valid date in php not working

I have converted one variable into unix timestamp to checl whether it is valid date or not
.Format is dd/mm/yy . My code is below
<?php
$date1='24/11/2013';
$date2='09/11/2013';
$date3='yuyuy1909090';//CAN BE ANYTHING
if(strtotime($date1)>0){
echo "valid date1";
}
if(strtotime($date2)>0){
echo "valid date2";
}
if(strtotime($date3)>0){
echo "valid date2";
}
?>
but if says only $date2 is valid, i cannot change the format of date because it comes form 3rd party flat file...
What could be the issue?
If you know the valid format, you can use:
$date = DateTime::createFromFormat('d/m/Y', $date1);
if ( $date->getTimestamp() > 0 ) {
echo 'valid date1';
}
Because strtotime thinks 24/11/2013 is in american format, as dates with slashes are interpreted as m/d/y, and there is no 11th of the 24th month, so it fails.
if you did
strtotime('11/24/2013');
instead, it would work.
If you want to keep your date in that format and still use strtotime, you could do
strtotime(str_replace('/', '-', '24/11/2013'));
as dates with hyphens are interpreted as d-m-y format
when date is $date1='yuyuy1909090' then
$date = DateTime::createFromFormat('d/m/Y', $date1);
if ( $date->getTimestamp() > 0 ) {
echo 'valid date1';
}
In such case it will give error , so better to add one line more for regex validation
if(preg_match("/^\d{1,2}\/\d{1,2}\/\d{4}/",$date1){
$date = DateTime::createFromFormat('d/m/Y', $date1);
if ( $date->getTimestamp() > 0 ) {
echo 'valid date1';
}
}

Date is inserting as 0000-00-00 00:00:00 in mysql

My $date output is in the foreach loop
09/25/11, 02/13/11, 09/15/10, 06/11/10, 04/13/10, 04/13/10, 04/13/10,
09/24/09, 02/19/09, 12/21/08
My mysql query(PHP) is as follows
("INSERT INTO table_name(`field1`, `field2`,`date`) VALUES ('".$value1."','".$value2 ."','".$date."')");
Question: In my database all the dates stores as 0000-00-00 00:00:00. But 4th date (06/11/10) is stored as 2006-11-10 00:00:00.
I tried with date('Y-m-d H:i:s', $date); but no help.
Note: My database field is datetime type.
Any idea?
You're on the right track with your date('Y-m-d H:i:s',$date); solution, but the date() function takes a timestamp as its second argument, not a date.
I'm assuming your examples are in American date format, as they look that way. You can do this, and it should get you the values you're looking for:
date('Y-m-d H:i:s', strtotime($date));
The reason it's not working is because it expects the date in the YYYY-MM-DD format, and tries to evaluate your data as that. But you have MM/DD/YY, which confuses it. The 06/11/10 example is the only one that can be interpreted as a valid YYYY-MM-DD date out of your examples, but PHP thinks you mean 06 as the year, 11 as the month, and 10 as the day.
I created my own function for this purpose, may be helpful to you:
function getTimeForMysql($fromDate, $format = "d.m.y", $hms = null){
if (!is_string($fromDate))
return null ;
try {
$DT = DateTime::createFromFormat($format, trim($fromDate)) ;
} catch (Exception $e) { return null ;}
if ($DT instanceof DateTime){
if (is_array($hms) && count($hms)===3)
$DT->setTime($hms[0],$hms[1],$hms[2]) ;
return ($MySqlTime = $DT->format("Y-m-d H:i:s")) ? $MySqlTime : null ;
}
return null ;
}
So in your case, you use format m/d/yy :
$sql_date = getTimeForMysql($date, "m/d/yy") ;
if ($sql_date){
//Ok, proceed your date is correct, string is returned.
}
You don't have the century in your date, try to convert it like this:
<?php
$date = '09/25/11';
$date = DateTime::createFromFormat('m/d/y', $date);
$date = $date->format('Y-m-d');
print $date;
Prints:
2011-09-25
Now you can insert $date into MySQL.

Categories