strtotime function for hours more than 24 - php

Hello I am trying to compare a time during with Hours:Minutes:Seconds format using strtotime function but there is a probleme if Hours is more than 24
PHP Code:
$time_duration_1 = '102:44:18';
$time_duration_2 = '87:42:19';
if(strtotime($time_duration_1) > strtotime($time_duration_2))
{
return true;
}else{
return false;
}
Is there any handy function for that kind of situation? or shall I do the checking manually hard coded?
Thanks in advance

Make a function to calculate your hours, minutes and seconds:
function formatHours($time){
$date = explode(':', $time);
return ($date[0]*60*60)+($date[1]*60)+$date[2];
}
if(formatHours($time_duration_1) > formatHours($time_duration_2)){
// ......

The way I'd solve that would be with mktime:
function getTimeFromString($time){
$time = explode(':', $time);
return mktime($time[0], $time[1], $time[2]);
}
if(getTimeFromString($time_duration_1) > getTimeFromString($time_duration_2)){

Related

True only on Weekdays and at a specific time

I am using PHP 7.4.1 and Laravel Framework 6.20.12 with the carbon library.
I want to return true only once from Monday to Friday if a date crosses the $sendPost variable. My cron-job runs every 5 Minutes.
I tried:
<?php
require 'vendor/autoload.php';
use Carbon\Carbon;
function checkMsgFired() {
$now = Carbon::now();
// $now = Carbon::createFromFormat('d/m/Y H:i:s', "19/1/2021 14:43:00");
$lastSendPost = Carbon::createFromFormat('d/m/Y H:i:s', "18/1/2021 14:43:00"); // the posting has already happended today
$post = array();
$post['Frequency'] = "MoToFr"; // send only from monday to friday at a specific date once
$post['sendPost'] = Carbon::createFromFormat('H:i:s', "14:40:00"); // when the post should be send
if($post['Frequency'] === "MoToFr") {
// if it is a WEEKDAY
if($now->dayOfWeek !== Carbon::SATURDAY or $now->dayOfWeek !== Carbon::SUNDAY) {
// $lastPosting didn't happen today
if(!$lastSendPost->isToday() && $now->gt($post['sendPost'])){
return true;
}
else{
return false;
}
} else {
return false;
}
}
}
var_dump(checkMsgFired());
However, the posting time does not seem to work. How can I check that the event has already fired once at the exact time?
Furthermore, is there an easier version to code this?
I appreciate your replies!
Something like possibly? This’ll give you true when the time is between 14:40 and 14:45, so long as your cron job runs every 5 minutes it should be mostly correct.
<?php
require 'vendor/autoload.php';
use Carbon\Carbon;
function checkMsgFired() {
$now = Carbon::now();
$frequency = "MoToFr";
$sendPost = Carbon::createFromFormat('H:i:s', "14:40:00");
if ($frequency === "MoToFr") {
if ($now->isWeekday()) {
return $now->between($sendPost, $sendPost->addMinutes(5));
}
}
return false;
}
var_dump(checkMsgFired());

Function to check user birth date is 18 years or upper not always work correctly

I am beginner webdeveloper.
I use in my project Laravel 5.8.
I have this this code:
if ($this->calcutateAge($request->input('date')) < 18) {
return Redirect::back()->withErrors(['You are a minor. Registration is allowed for adult users']);
}
function calcutateAge($dob)
{
$dob = date("Y-m-d", strtotime($dob));
$dobObject = new DateTime($dob);
$nowObject = new DateTime();
$diff = $dobObject->diff($nowObject);
return $diff->y;
}
It's work fine. But I have problem with date ex 2045-12-12.
This function is not working. With year: 2015-12-12 - it's okey.
How can I repair it?
I suggest you should use Carbon.
use Carbon\Carbon;
function calcutateAge($dob){
return \Carbon::parse($dob)->age;
}
I would write your function to return true or false depending on if the user is 18 or not.
function is_18($dob)
{
$dobObject = new DateTime(date("Y-m-d", strtotime($dob)));
$nowObject = new DateTime();
return $dobObject < $nowObject ? ($dobObject->diff($nowObject)->y > 18) : false;
}
Then your IF block is simplified to this:
if (!$this->is_18($request->input('date')) {
return Redirect::back()->withErrors(['You are a minor. Registration is allowed for adult users']);
}
I would find out when a person born 18 years ago was born, then compare to that:
function isAdult($dob) {
$adult = new DateTime('18 years ago'); // 'date' => '2002-09-01 12:05:52.000000'
$dob = date("Y-m-d", strtotime($dob));
$dobObject = new DateTime($dob);
return $adult >= $dobObject; // 2002-09-01 is after the passed date of birth
}
you can add 18 year and compare the date like this:
$dobObject = new DateTime($dob.' +18 years');
$nowObject = new DateTime();
if ($dobObject > $nowObject)
print 'great you are granted'
else
print 'sorry you are minor'
If you run var_dump($diff); you will see:
["invert"]=> int(1)
Which means is a negative difference.
So, you can do return $diff->invert? -$diff->y : $diff->y;
Of course this is a solution based on your code. You can always check if the date is someday into the future, and return false or throw some exception in this case.

how to format hours in php?

I made this function and it works:
$myHour = "09:09";
$myHour = time_format($myHour);
function time_format($h){
$initial_string = $h;
$new = substr($h,1,strlen($h));
$h = substr($h,0,-4);
if ($h == "0"){
return $new;
}else{
return $initial_string;
}
}
This function verify it the string looks like: "01:02" and get rid of the first "0", so it will become "1:02" else if it looks like "13:13" it will return "13:13".
My question is how to improve my function? or if there exists other better method ? thx
use ltrim to just simply remove the leading 0 if there is one. I assume there is a reason you cant just change the date format which generates the string ?
function time_format($h){
return ltrim($h, "0");
}
But changing the date format is the best option
this will be your shortened function, still readable
function time_format($h){
if (substr($h, 0, 1) == "0"){
return substr($h, 1);
}else{
return $h;
}
}
this would be even shorter
function time_format($h){
return substr($h, 0, 1) == "0" ? substr($h, 1) : $h;
}
this one is even without the if operators
to read more about it, here is a link.
<?php
$date = new DateTime('2000-01-01');
echo $date->format('Y-m-d H:i:s');
?>
Please have a detailed look here:
http://www.php.net/manual/en/datetime.format.php
You can get a DateTime object by UnixTimestamp (if needed) with this way
$dtStr = date("c", $timeStamp);
$date = new DateTime($dtStr);
Source: Creating DateTime from timestamp in PHP < 5.3
use PHP date function
try to google first..

Verify valid date using PHP's DateTime class

Below is how I previously verified dates. I also had my own functions to convert date formats, however, now am using PHP's DateTime class so no longer need them. How should I best verify a valid date using DataTime? Please also let me know whether you think I should be using DataTime in the first place. Thanks
PS. I am using Object oriented style, and not Procedural style.
static public function verifyDate($date)
{
//Given m/d/Y and returns date if valid, else NULL.
$d=explode('/',$date);
return ((isset($d[0])&&isset($d[1])&&isset($d[2]))?(checkdate($d[0],$d[1],$d[2])?$date:NULL):NULL);
}
You can try this one:
static public function verifyDate($date)
{
return (DateTime::createFromFormat('m/d/Y', $date) !== false);
}
This outputs true/false. You could return DateTime object directly:
static public function verifyDate($date)
{
return DateTime::createFromFormat('m/d/Y', $date);
}
Then you get back a DateTime object or false on failure.
UPDATE:
Thanks to Elvis Ciotti who showed that createFromFormat accepts invalid dates like 45/45/2014.
More information on that: https://stackoverflow.com/a/10120725/1948627
I've extended the method with a strict check option:
static public function verifyDate($date, $strict = true)
{
$dateTime = DateTime::createFromFormat('m/d/Y', $date);
if ($strict) {
$errors = DateTime::getLastErrors();
if (!empty($errors['warning_count'])) {
return false;
}
}
return $dateTime !== false;
}
With DateTime you can make the shortest date&time validator for all formats.
function validateDate($date, $format = 'Y-m-d H:i:s')
{
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) == $date;
}
var_dump(validateDate('2012-02-28 12:12:12')); # true
var_dump(validateDate('2012-02-30 12:12:12')); # false
function was copied from this answer or php.net
You could check this resource: http://php.net/manual/en/datetime.getlasterrors.php
The PHP codes states:
try {
$date = new DateTime('asdfasdf');
} catch (Exception $e) {
print_r(DateTime::getLastErrors());
// or
echo $e->getMessage();
}
Try this:
function is_valid_date($date,$format='dmY')
{
$f = DateTime::createFromFormat($format, $date);
$valid = DateTime::getLastErrors();
return ($valid['warning_count']==0 and $valid['error_count']==0);
}
$date[] = '20/11/2569';
$date[] = 'lksdjflskdj';
$date[] = '11/21/1973 10:20:30';
$date[] = '21/11/1973 10:20:30';
$date[] = " ' or uid like '%admin%";
foreach($date as $dt)echo date('Y-m-d H:i:s', strtotime($dt))."\n";
Output
1970-01-01 05:30:00
1970-01-01 05:30:00
1970-01-01 05:30:00
1973-11-21 10:20:30
1970-01-01 05:30:00
1970-01-01 05:30:00
I needed to allow user input in (n) different, known, formats...including microtime. Here is an example with 3.
function validateDate($date)
{
$formats = ['Y-m-d','Y-m-d H:i:s','Y-m-d H:i:s.u'];
foreach($formats as $format) {
$d = DateTime::createFromFormat($format, $date);
if ($d && $d->format($format) == $date) return true;
}
return false;
}
With the following an empty string like '' or 0 or '0000-00-00 00:00:00' is false
$valid = strtotime($date) > 0;
For me, the combination of date_parse and checkdate works best and it is almost one-liner:
$date="2024-02-29";
$dp=date_parse("$date");
if (sprintf("%04d-%02d-%02d",$dp['year'], $dp['month'], $dp['day'])===$date && checkdate($dp['month'], $dp['day'], $dp['year'])) {
// format is OK and date is valid
}

English to Time

Does anyone know of a good class / library to convert English representations of time into timestamps?
The goal is to convert natural language phrases such as "ten years from now" and "three weeks" and "in 10 minutes" and working out a best match unix timestamp for them.
I have hacked up some pretty poor and untested code to get going on it, but I am sure there are great parsers out there for calendars and such.
private function timeparse($timestring)
{
$candidate = #strtotime($timestring);
if ($candidate > time()) return $candidate; // Let php have a bash at it
//$thisyear = date("Y");
if (strpos($timestring, "min") !== false) // Context is minutes
{
$nummins = preg_replace("/\D/", "", $timestring);
$candidate = #strtotime("now +$nummins minutes");
return $candidate;
}
if (strpos($timestring, "hou") !== false) // Context is hours
{
$numhours = preg_replace("/\D/", "", $timestring);
$candidate = #strtotime("now +$numhours hours");
return $candidate;
}
if (strpos($timestring, "day") !== false) // Context is days
{
$numdays = preg_replace("/\D/", "", $timestring);
$candidate = #strtotime("now +$numdays days");
return $candidate;
}
if (strpos($timestring, "year") !== false) // Context is years (2 years)
{
$numyears = preg_replace("/\D/", "", $timestring);
$candidate = #strtotime("now +$numyears years");
return $candidate;
}
if (strlen($timestring) < 5) // 10th || 2nd (or probably a number)
{
$day = preg_replace("/\D/", "", $timestring);
if ($day > 0)
{
$month = date("m");
$year = date("y");
return strtotime("$month/$day/$year");
}
else
{
return false;
}
}
return false; // No can do.
}
Use the DateTime class.
e.g.:
$string='four days ago';
$d=date_create($string);
$d->getTimestamp();
ETA:
which you could extend:
class myDateTime extends DateTime {
static $defined_expressions=array(...);
function __construct($expression=NULL) {
if ($exp=$this->translate($expression)) {
parent::__construct($exp);
}
}
function translate($exp) {
//check to see if strtotime errors or not
//if it errors, check if $exp matches a pattern in self::$defined_expressions
return $exp, modified $exp or false
}
}
Sometime ago I had come across http://www.timeapi.org which converts natural language queries into time. It is an API though.
The ruby source code is on github. If need be, I guess you could try to port it to PHP.
Just got a notification from PHPClasses, with one of the runner-ups of the monthly innovation award: Text to Timestamp
You could try that...
Cocoa's and GNUStep's NSDateFormatter are able to handle such time representations. The GNUStep version is open-source.

Categories