Time difference not working when year changes - php

I have a script that was working, well is working but not properly. The function is suppose to work out the time difference between two dates/times.
The First date is the Current Date and Time (Date + Hr:Min) and the second date is chosen by a user.
The purpose is to show error when the current date/time is within 24 hours from the user chosen date. i.e. if today is 23/20/2012 16:00 and the user chooses 24/10/2012 15:00 (this mean its within 24 hours) but if user chooses 26/10/2012 19:00 then its passed 24 hours.
Now this works fine but when the date changes its year (when user selected any date after 31st Dec 2012.. it assumes its still within 24 hours.. and im quite baffled how this happens.. can anyone shed some light what I've done wrong?
$dt = $_GET['dt']; $tm = $_GET['tm'];
// Current Date an time (Hrs & Mins)
$date1 = date("Y-m-d H:i");
// Chosen Date/Time
$date2 = date("Y-m-d", strtotime( "$dt" ) );
$diff = strtotime($date2." $tm") + - strtotime($date1);
if($diff/3600 < 24)
echo "0";
else
echo "1";
The following is the corresponding Ajax that makes th call
function getAjaxTime()
{
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
alert ("Your browser does not support AJAX!");
return;
}
dt = document.frm.arrival_date.value;
tm = document.frm.arrival_hour.value +':'+document.frm.arrival_min.value;
xmlHttp.open("GET","<?php echo $base_dir;?>/admin/get/timediff.php?dt="+encodeURI(dt)+"&tm="+encodeURI(tm),false);
xmlHttp.send(null);
return xmlHttp.responseText;
}

I would try something like this:
function isDateWithin24Hours($targetDate, $currentDate = 'now') {
$targetDate = new DateTime($targetDate);
$currentDate = new DateTime($currentDate);
$interval = $targetDate->diff($currentDate);
//%a = total number of days
if ($interval->format('%a') > 1) {
return (int) false;
}
return (int) true;
}
echo isDateWithin24Hours('2012-10-24 19:00:00');
echo isDateWithin24Hours('2012-10-24 19:00:00', '2012-10-23 18:00:00');

According to the php manual - http://us3.php.net/manual/en/datetime.formats.date.php - your date is not a valid format:
24/10/2013 // with / as deliminators
These would be valid
24-10-2013 // with - as deliminators
10/24/2013 // with / as deliminators and as m/d/Y
Update-
Also, the following format is invalid in strtotime & date-
Thursday, 10 May, 2012 00:30
But this would be valid -
Thursday, May 10, 2012 00:30
Update #2
In fact once your $_GET['dt'] is in a valid php format, you could simplify your code to-
$dt = $_GET['dt']; $tm = $_GET['tm'];
// Current Date an time (Hrs & Mins)
$date1 = date("Y-m-d H:i");
$diff = strtotime($dt." ".$tm) + - strtotime($date1);
if($diff/3600 < 24)
echo "0";
else
echo "1";

Related

Efficiently check if exactly 2 days passed from given datetime in my case

I have following code that add 2 days to a given date.
$myDate = 2018-07-28 11:00:00; // the date is picked from db
$penaltyDays = 2;
$date1 = new DateTime($myDate);
$date1->add(new DateInterval("P{$penaltyDays}D")); // add N days
$now = new DateTime();
$interval = $date1->diff($now); // get difference
$days = $interval->d; // difference in days
I want value of $days must be 0 after passing exactly 48 hours. If 3 days are passed the value of $days should be -1.
I will also appreciate if someone tell me efficient/proper way to get the result.
To make an efficient code according to your specification then I would rather use strtotime than DateTime.
This code checks if the current time is larger than the database time + two (or three) days in seconds.
$myDate = "2018-07-28 11:00:00";
$unix = strtotime($myDate);
if(time() > ($unix + 86400*3)){
$days = -1;
}else if(time() > ($unix + 86400*2)){
$days = 0;
}else{
$days = "something else";
}
Echo $days;
https://3v4l.org/d6Q15

PHP - How to check if current day/time is between two weekdays including time (from - to)

I need to check if current date and time is between two weekdays which include time (from and to). There can be multiple records in the db and week days are stored via PHP date('N') where 1 (for Monday) through 7 (for Sunday) as well as hour - minute is stored via time.
For instance, a stored rule can be the following:
week_day_from : 5 (Friday)
week_hour_from : 16:00:00
week_day_to : 7 (Sunday)
week_hour_to : 18:00:00
or even
week_day_from : 7 (Sunday)
week_hour_from : 10:00:00
week_day_to : 2 (Tuesday)
week_hour_to : 12:00:00
How can I determine if current day/time applies in one of the rules? The main idea is to hide some results if one of the rule applies (i.e. do not show this meal after friday 16:00 and before Sunday 18:00)
thank you in advance
The function getdate will give you more exact information. The function getDate() will return an array containing information about the weekday and time. By having the interval,you can determine if applies.
found something....
had to create pseudo dates in order to use strtotime and compare with current date time. Pseudo dates are created via conditions as shown below which are commented to describe my logic.
I would much better prefer a MySQL query based solution rather than fetching all rules and compare but I can not find a way. I would be gratefull if you check my code and tell me what you think. Flaw may be possible...
$daynow = date("N"); //$daynow = 7;
$datetimenow = date("d-m-Y G:i:s");
if($row['week_day_from'] > $row['week_day_to'])
{// case from saturday(6) to thursday(4)
if($daynow == 7)
{
$check_from = date("d-m-Y", strtotime("Sunday + ".$row['week_day_from']." Days - 1 week"));
$check_to = date("d-m-Y", strtotime("Sunday + ".$row['week_day_to']." Days"));
}
else
{
$check_from = date("d-m-Y", strtotime("Sunday + ".$row['week_day_from']." Days - 2 week"));
$check_to = date("d-m-Y", strtotime("Sunday + ".$row['week_day_to']." Days - 1 week"));
}
}
else
{// case from thursday(4) to saturday(6)
if($daynow == 7)
{
$check_from = date("d-m-Y", strtotime("Sunday + ".$row['week_day_from']." Days"));
$check_to = date("d-m-Y", strtotime("Sunday + ".$row['week_day_to']." Days"));
}
else
{
$check_from = date("d-m-Y", strtotime("Sunday + ".$row['week_day_from']." Days - 1 week"));
$check_to = date("d-m-Y", strtotime("Sunday + ".$row['week_day_to']." Days - 1 week"));
}
}
if
(
strtotime($datetimenow) >= strtotime($check_from." ".$row['week_hour_from'])
AND
strtotime($datetimenow) <= strtotime($check_to." ".$row['week_hour_to'])
)
{
//RULE APPLIES
}

Need a equivalent solution for vbscript command cdbl(now) with php

With vbscript i can retrieve a double value from the current date/time with the command cdbl(now).
Now = '09.05.2015 21:44:10'
cdbl(Now) = 42133,9056712963
I'm looking for a equivalent solution with php that will give me back a double value from the current date/time.
cdbl return datetime in microsoft format. before comma date - number of days since 1 January 1900. After comma time - 24 hours is 1. So if you use dates within Unix epoch (code may be not effective,i wanted make it more understandable)
function cdbl($str) {
$datetime0 = new DateTime('1970-01-01');
$datetime = new DateTime($str);
// 25560 - days from 1 Jan 1900 to 1 Jan 1970
$cdbl = $datetime->diff($datetime0)->days + 25569;
// Remove time from string - it is the sane as 00:00
$str0 = preg_replace('/((T|\s+).+)$/','', $str);
// The number of seconds since the day start
$time = strtotime($str) - strtotime($str0);
// The number of seconds wittin a day
$timefullday = strtotime("$str0 + 1 day") - strtotime($str0);
$cdbl += $time / $timefullday;
return $cdbl;
}
echo cdbl('09.05.2015 21:44:10');
result:
42133.905671296
As you can see, there is a problem of rounding. If print result of the calculation time before summing, the answer will be the same as yours. I've never done calculating tasks, so I can not tell you what to do with it. The only suggestion is convert to a string :)
Well, if you choose to work outside of Unix dates you should write some code
The following function returns the current Unix timestamp as a double value:
function cdblnow(){
// time in seconds since 1 Jan 1970 (GMT)
$timeunix = time();
// add the timezone offset
$TimeZone = "Asia/Bangkok";
$dateTimeZone = new DateTimeZone($TimeZone);
$dateTime = new DateTime("now", $dateTimeZone);
$timeOffset = $dateTimeZone->getOffset($dateTime);
$timeunix = $timeunix + $timeOffset;
// determines the days between 1 Jan 1970 and today
$days = intval($timeunix / 86400);
// second count from today
$secondsremains = $timeunix % 86400;
// 25569 days difference between microsoft and unix time stamp start
$now_date = $days + 25569;
// 0.0000115741 represents one second at the cdbl-function from microsoft
$now_time = $secondsremains * 0.0000115741;
return $now_date + $now_time;}
This function returns the unix time stamp from a double:
function GetUnixTimeFromCdblNow($cdbl){
$days = intval($cdbl);
$seconds = round($cdbl - $days,9);
$timeunix = (($days -25569) * 86400);
$timeunix = $timeunix + intval($seconds / 0.0000115740);
return $timeunix;}

Why does date gives me a wrong date?

I want to calculate a date based on a timestamp and some other informations.
My function looks like:
function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
$days = 0;
$extraDays = 0;
$endOfCurrentMonth = 0;
$tsDay = 86400;
if($endOfMonth){
$endOfCurrentMonth = date("t", $timestamp) - date("d",$timestamp);
//rest of days in current month. In this sample 16 days
}
for($i=0;$i<$extraMonth;$i++){
$x = $i + 1;
$date = new DateTime(date("Y-m-d", $timestamp)); //create dateobject to add a month
$date->modify("+{$x} month"); // add the month (next month)
$extraDays += date("t", strtotime($date->format("Y-m-d")));
// get the days of the selected month and add them to count
// in this case its 31 + 30 + 31 = 92
}
$days = $endOfCurrentMonth + $extraDays;
// count everything together 16 + 92 = 108 days
return date("d.m.y", $timestamp + ($tsDay*$days));
//returning date with 108 days added.
}
As a sample I call the function like:
// the timestamp is 2015-07-15
echo getLastDeliveryDate(1436911200, true, 3);
// should return 2015-10-31
But this return 2015-10-30 and I don't know why. But 108 Days shold be 2015-10-31. Whats going wrong here ?
If I call
echo getLastDeliveryDate(1436911200, true, 2);
Its correct and gives me 2015-09-30
Actually I allways want the last day of the month.
EDIT:
Wired, if I test this here: IDEONE everything works fine. Im my Project it doesn't :(
You need to create the datetime object before the loop:
$date = new DateTime(date("Y-m-d", $timestamp)); //create dateobject to add month
// simpler alternative: $date = new DateTime("#$timestamp");
for($i=0;$i<$extraMonth;$i++){
$date->modify("+1 month"); // add the month (next month)
// $extraDays += date("t", strtotime($date->format("Y-m-d")));
// you can reduce this line to:
$extraDays += $date->format("t");
}
// Result: 15-10-31
otherwise there is always 31 added because you use the day of the timestamp + 1 month.
Note:
You can reduce the whole function to this:
function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
$date = new DateTime("#$timestamp");
$date->modify("+$extraMonth month");
if ($endOfMonth)
$date->modify("last day of this month");
return $date->format("d.m.y");
}
The problem is the daylight savings time. You loose one hour on the 25th of october 2015. Since your timestamp is exactly 0:00:00 you lose one hour resulting in "30.10.2015 23:00:00" what should actually be 0:00:00
function getLastDeliveryDate($timestamp,$endOfMonth=true,$extraMonth=0){
$days = 0;
$extraDays = 0;
$endOfCurrentMonth = 0;
$tag = 86400;
if(date( 'H',$timestamp)==0){$timestamp+=3601;}
if($endOfMonth){
$endOfCurrentMonth = date("t", $timestamp) - date("d",$timestamp);
}
$date = new DateTime(date("Y-m-d", $timestamp));
for($i=0;$i<$extraMonth;$i++){
$date->modify("+1 month");
$extraDays += $date->format("t");
}
$days = $endOfCurrentMonth + $extraDays;
return date("d.m.y", $timestamp + ($tag*$days));
}
echo getLastDeliveryDate(1436911200, true, 3);
This code has a dirty fix for this problem by adding one hour and one second if your datetime is fixed to 0:00:00. When you don't care about the hours themselves, then this solution will fix your problem and is viable in any case. If you care about the hours, you have to check whether you are in daylight savings time or not and act acordingly.

Automatically calculate expiry date php

In a site I am creating, I want to store member data and in that data I have a start/join date which is easy to get, but I want to automatically calculate the expiry date which I'm having problems with..
Basically all new members will expire on the last day of February each year, so if I join on say 1st Feb 2013 my expiry will be on 28/02/2014, if I join on 1/03/13 or 20/12/13 my expiry will still be on 28/02/2014. ((I don't mind too much about the 1 day that appears on leap years))
Does anyone know how I can work this out - I know it's probably something obvious but I just cant seem to grasp it! :/
(I'll be doing this in php)
Many thanks in advance,
Chris
Assuming that you have (or can get) their registration date in a Unix timestamp format, you could do the following:
function calculateExpiry($reg_date)
{
$next_year = strtotime('+1 year', $reg_date);
$feb_days = ((($next_year % 4) == 0) && ((($next_year % 100) != 0) || (($next_year % 400) == 0))) ? 29 : 28;
return strtotime($feb_days.' February '.$next_year);
}
This will always return the last day of February for the following year in a Unix timestamp, so you can format it how you like. I think this logic is suitable, see the following use cases:
Register: 01/01/2013, Returns: 28/02/2014
Register: 09/10/2013, Returns: 28/02/2014
Register: 31/12/2013, Returns: 28/02/2014
Register: 01/01/2014, Returns: 28/02/2015
This should do the trick too :).
function calculate_expiry( $rawDate ) {
// Convert data into usable timestamp
$signupDate = strtotime( $signupDate );
$cutoffYear = date('Y', $signupDate) + 1;
// Set the expiry to be the last day of Feb (the first day of March -1)
$expiryDate = new DateTime();
$expiryDate->setTimestamp( mktime( 0, 0, 0, 3, 1, $cutoffYear ) );
$expiryDate->sub( new DateInterval('P1D') );
}
Well, we will get the current signup date by doing...
$signup_date = date("m-d-Y"); // or time()
And then offset it by another year
$expire_date = date("m-d-Y", strtotime("+1 year"))

Categories