It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I need to compare a date to today. Basically I put in 2/17/13 and it will output "yesterday". I've tried echo date('l jS F', strtotime('2/15/13')); but it will only display that date not compare it to today.
From http://www.highlystructured.com/comparing_dates_php.html
$exp_date = "2006-01-16";
$todays_date = date("Y-m-d");
$today = strtotime($todays_date);
$expiration_date = strtotime($exp_date);
if ($expiration_date > $today) {
$valid = "yes";
} else {
$valid = "no";
}
Here's an example, to get you started:
$when = '2/17/13';
$now = new DateTime();
// I append $now's time to $then, to make sure we compare
// the two dates using the same time of the day
// if you want to compare to $then at 00:00:00, leave it out
$then = new DateTime( $when . ' ' . $now->format( 'H:i:s' ) );
$diff = $now->diff( $then );
switch( $diff->days )
{
case 0:
echo 'today';
break;
case 1:
echo $diff->invert ? 'yesterday' : 'tomorrow';
break;
default:
echo $diff->invert ? $diff->days . ' days ago' : $diff->days . ' days from now';
break;
}
Drupal ships with a very nice format_interval($interval, $granularity = 2, $langcode = NULL) function.
<?php
function format_interval($interval, $granularity = 2, $langcode = NULL) {
$units = array(
'1 year|#count years' => 31536000,
'1 month|#count months' => 2592000,
'1 week|#count weeks' => 604800,
'1 day|#count days' => 86400,
'1 hour|#count hours' => 3600,
'1 min|#count min' => 60,
'1 sec|#count sec' => 1,
);
$output = '';
foreach ($units as $key => $value) {
$key = explode('|', $key);
if ($interval >= $value) {
$output .= ($output ? ' ' : '') . format_plural(floor($interval / $value), $key[0], $key[1], array(), array('langcode' => $langcode));
$interval %= $value;
$granularity--;
}
if ($granularity == 0) {
break;
}
}
return $output ? $output : t('0 sec', array(), array('langcode' => $langcode));
}
?>
You don't need to be running Drupal to use it. Just include the above function somewhere. However, the above function also calls format_plural() - which calls t() (both custom Drupal functions), so you'll need to modify the above function or include all of them.
Your use case:
<?php
$today = date();
$compare = strtotime('2/15/13');
$interval = ($today - $compare);
print format_interval($interval, 1);
// Outputs '1 day'
?>
function checkDate($todaysDate,$expirationDate){
$today = strtotime($todays_date);
$expiration_date = strtotime($exp_date);
if ($expiration_date > $today) {
$valid = "yes";
} else {
$valid = "no";
}
return $valid
}
$expirationDate = "2006-01-16";
$todaysDate = date("Y-m-d");
$valid=checkDate($todaysDate,$expirationDate)
Do it in a function then you can use it with any combination of dates. You can then expand upon the function with some conditionals to figure out if its "yesterday".
function relativeTime($time) {
$d[0] = array(1,"second");
$d[1] = array(60,"minute");
$d[2] = array(3600,"hour");
$d[3] = array(86400,"day");
$d[4] = array(604800,"week");
$d[5] = array(2592000,"month");
$d[6] = array(31104000,"year");
$w = array();
$return = "";
$now = time();
$diff = ($now-$time);
$secondsLeft = $diff;
for($i=6;$i>-1;$i--)
{
$w[$i] = intval($secondsLeft/$d[$i][0]);
$secondsLeft -= ($w[$i]*$d[$i][0]);
if($w[$i]!=0)
{
$return.= abs($w[$i]) . " " . $d[$i][1] . (($w[$i]>1)?'s':'') ." ";
}
}
$return .= ($diff>0)?"ago":"left";
return $return;
}
Related
I have a php script here to create login at our datacenter for myself, but this script is doing the login for next week if i run it after 12:00 on monday, and a lot of times I'm not there the whole week, so I want to improve this script by asking for user input and pass the dates that I will be there so the script only picks up on those dates. I know i have to do this with stdin and I do have a part that works, but i have no idea on how to integrate this into the current script and how to make sure i can give multiple dates
My stdin part that does ask my for a date, but no idea on how to combine it:
<?php
function promptDateFromUser(string $prompt, string $dateFormat): DateTimeInterface
{
echo "{$prompt} [$dateFormat]: ";
$stdin = fopen('php://stdin', 'r');
$line = trim(fgets(STDIN));
fclose($stdin);
$dateTime = DateTimeImmutable::createFromFormat('Y-m-d', $line);
if (! $dateTime instanceof DateTimeInterface) {
throw new UnexpectedValueException('Invalid datetime format');
}
}
$dateTime = promptDateFromUser("Please insert date:", 'Y-m-d');
?>
My login script as of now:
<?php
require 'shared.php';
restore_exception_handler();
restore_error_handler();
$md = new RevisionModificationData;
$md->comment = 'Set by the dcgaccess script';
$date = new DateTime();
$hour = (int)$date->format('H');
$dow = (int)$date->format('w');
if (($dow === 1 && $hour > 12) || ($dow > 1 && $dow < 6)) {
$add = 'P' . (8 - $dow) . 'D';
$date->add(new DateInterval($add));
}
if (($dow === 1 && $hour <= 12) || $dow === 0 || $dow === 6) {
if ($dow === 6) {
$date->add(new DateInterval('P2D'));
} elseif ($dow === 0 ) {
$date->add(new DateInterval('P1D'));
}
}
$tomorrow = $date->format('Y-m-d');
$duration = 720;
$customerId = 30;
$purpose = 'DCG visit';
$phoneNumber = '';
$name = 'SOME NAME, REMOVED FOR PUBLICATION';
$colo = Colo::getByName($name);
Ensure::notNull($colo, "Colo for RackSpace is null when it should not be!");
$spaces = $colo->getRackSpaces();
foreach ($spaces as $space) {
$rackSpace = $space;
}
Ensure::notNull($rackSpace, "RackSpace is null when it should not be!");
if ($colo->getCustomerId() != $customerId) {
throw new UserException(ErrorCodes::PERMISSION_DENIED);
}
for ($x = 0; $x < 5; $x++) {
$start = $tomorrow." 8:00:00";
$end = Util::stringToMysqlDateTime($start . ' + ' . $duration . ' minutes');
$shouldSms = strlen((string)$phoneNumber) > 0;
$req = BioAccessRequest::create($rackSpace, $purpose, $start, $end, $shouldSms, $md);
$users = BioAccessUser::getAll();
foreach ($users as $user) {
if ($user->name === 'USER NAME') {
$req->addBioAccessUser($user, $md);
}
}
$req->request();
echo "Access requested for: ", $tomorrow, PHP_EOL;
$date->add(new DateInterval('P1D'));
$tomorrow = $date->format('Y-m-d');
}
?>
I'm a big php noob, so some explanation is greatly appreciated!
after some help from a friend, i managed to solve this:
#!/usr/bin/env php
<?php
include('shared.php');
restore_exception_handler();
restore_error_handler();
// Constants
$timeout = 45;
$md = new \RevisionModificationData;
$md->comment = 'Set by the dcgaccess script';
$duration = "720";
$customerId = "30";
$purpose = "DCG visit";
$phoneNumber = "";
$name="SOME NAME, REMOVED FOR PUBLICATION";
// Functions
function requestInput($msg) {
global $timeout;
echo "$msg\n\nThe timeout for this selection is $timeout seconds.\n\n> ";
$fd = fopen('php://stdin', 'r');
$read = array($fd);
$write = $except = array(); // we don't care about this
if(stream_select($read, $write, $except, $timeout)) {
$choice = trim(fgets($fd));
}
echo "\nYou typed: $choice\n\n";
return $choice;
}
// Start of program
$date = new DateTime();
$weekchoice = (int)requestInput("Which week would you like to request access for?\n1) Current week\n2) Next week\n3) Specific week number");
if ($weekchoice == 3) {
$weeknumber = (int)requestInput("Please enter a numeric week number");
} else {
$weeknumber = (int)$date->format("W");
if ($weekchoice == 2) {
$weeknumber += 1;
}
}
// We override $date with the start of the chosen week
$date->setISODate($date->format("Y"), $weeknumber);
echo "Thanks, you chose week $weeknumber which starts with " . $date->format("l d F, Y") . " \n\n";
$dayschoice = requestInput("Please enter the days you want access, as a space separated list:\n1) Monday\n2) Tuesday\n3) Wednesday\n4) Thursday\n5) Friday\n\nExample: 1 3 5");
$daylist = explode(' ', $dayschoice);
$processedDays = [];
foreach ($daylist as $eachday) {
$iday = (int)$eachday;
if ($iday == 0 || $iday % 7 == 0) { // No Sundays, also (int)"" -> 0, which is terrible
continue;
}
$add_days = $iday - 1; // Sums 0 if Monday, 1 if Tuesday and so on...
$newdate = new DateTime($date->format("Y-m-d"));
$newdate->modify("+$add_days days");
$processedDays[] = $newdate;
$formatted = $newdate->format("l d F Y");
echo "Processing day $iday, which is $formatted\n";
}
$hour = $date->format('H');
$tomorrow = $date->format('Y-m-d');
$confirm = requestInput("\nRequest access for these days? Yes/No");
if ($confirm != "Yes") {
echo 'Good bye!';
exit(0);
}
foreach ($processedDays as $reqDay) {
echo "Submitting " . $reqDay->format("l d F Y") . "\n";
$colo = Colo::getByName($name);
Ensure::notNull($colo, "Colo for RackSpace is null when it should not be!");
$spaces = $colo->getRackSpaces();
foreach ($spaces as $space) {
$rackSpace = $space;
}
Ensure::notNull($rackSpace, "RackSpace is null when it should not be!");
if ($colo->getCustomerId() != $customerId) {
throw new UserException(ErrorCodes::PERMISSION_DENIED);
}
}
foreach ($processedDays as $reqDay) {
$start = $reqDay->format('Y-m-d')." 8:00:00";
$end = Util::stringToMysqlDateTime($start . ' + ' . $duration . ' minutes');
$shouldSms = strlen((string)$phoneNumber) > 0;
$req = BioAccessRequest::create($rackSpace, $purpose, $start, $end, $shouldSms, $md);
$users = BioAccessUser::getAll();
foreach ($users as $user) {
if ($user->name === 'USER NAME') {
$req->addBioAccessUser($user, $md);
}
}
$req->request();
echo "Access requested: ", $reqDay->format('l d F Y'), PHP_EOL;
$tomorrow = $date->format('Y-m-d');
}
?>
I have 2 string like this "2018/04/10-14:54:55" and "2018/04/10-14:56:10".
How can I calculate different between them? I've used strtotime to change the string to date but it gives the wrong value.
Please help me with this.
Thank you
<?php
$time1 = '2018/04/10-14:54:55';
$time2 = '2018/04/10-14:56:10';
$format = 'Y/m/d-H:i:s';
$t1 = DateTime::createFromFormat($format, $time1);
$t2 = DateTime::createFromFormat($format, $time2);
echo "time1" . $t1->format('Y-m-d H:i:s') . "<br/>";
echo "time2" . $t2->format('Y-m-d H:i:s') . "<br/>";
$difference = $t1->diff($t2);
echo $difference->format('%s%a secs');
You can use specific format to create a datetime ojbect, after that you can use diff function to get the difference.
Please try this code.
function time_difference($time_1, $time_2, $limit = null)
{
$val_1 = new DateTime($time_1);
$val_2 = new DateTime($time_2);
$interval = $val_1->diff($val_2);
$output = array(
"year" => $interval->y,
"month" => $interval->m,
"day" => $interval->d,
"hour" => $interval->h,
"minute" => $interval->i,
"second" => $interval->s
);
$return = "";
foreach ($output AS $key => $value) {
if ($value == 1)
$return .= $value . " " . $key . " ";
elseif ($value >= 1)
$return .= $value . " " . $key . "s ";
if ($key == $limit)
return trim($return);
}
return trim($return);
}
$time1 = '2018/04/10 14:54:55';
$time2 = '2018/04/10 14:56:10';
$resp = time_difference ($time1, $time2);
echo $resp;
output:
1 minute 15 seconds
This is an example, I have explained the details in the code itself:
<?php
date_default_timezone_set("Asia/Tehran"); //Set your timezone to avoid warnings in PHP error_log
// Use '/' for American date format and use '-' for Europian date format
// Use 'T' instead of '-'
$time_1 = strtotime( str_replace('-', 'T', "2018/04/10-14:54:55") ); //Replace '-' to 'T' to get "2018/04/10T14:54:55"
$time_2 = strtotime( str_replace('-', 'T', "2018/04/10-14:56:10") ); //Replace '-' to 'T' to get "2018/04/10T14:56:10"
$diff = $time_2 - $time_1;
echo $diff; // in seconds
?>
I hope it helps.
Lets assume I have the following:
$times = array();
for($month = $current_month; $month <= $end_month; $month++) {
$first_minute = mktime(0, 0, 0, $month, 1);
$last_minute = mktime(23, 59, 0, $month, date('t', $first_minute));
$times[$month] = array($first_minute, $last_minute);
}
I now need to loop through all the $months but I am not sure how I can achieve this.
I have tried foreach() but that requires I enter a value for $month. We are assuming the value is not clear.
Do you mean you need to loop through $times?
A simple foreach will do...
foreach ($times as $month => $mins) {
// $month = the month
// $mins[0] = first minute
// $mins[1] = last minute
}
Can try using foreach() like this
foreach($times as $month=>$val){
echo 'Month: ' . $month . ' ';
echo 'First Minute: ' . $val[0] . ' ';
echo 'last Minute: ' . $val[1];
echo '<br />';
}
Perhaps you should use Datetime instead?
$end_month = 12;
$times = [];
$oneMonth = new DateInterval('P1M');
$dt = new Datetime('midnight first day of'); // 2014-12-01T00:00:00+00:00
while($dt->format('m') <= $end_month) {
$firstSecond = $dt->getTimestamp();
$dt->add($oneMonth); // 2015-01-01T00:00:00+00:00
$lastSecond = $dt->getTimestamp() -1;
$times[$dt->format('m')] = [$firstSecond, $lastSecond];
}
foreach ($times as $month => $seconds) {
// ...
}
But you could only work with Datetime object:
while($dt->format('m') <= $end_month) {
$times[] = clone $dt;
$dt->add($oneMonth);
}
foreach ($times as $month) {
echo $month->format('m'), // 12
$month->getTimestamp();
}
I have 2 date ranges
[contract_start_date] => 2011-10-20 [contract_end_date] => 2011-10-29
and I want to verify if the dates below are in range of the date range above
2011-05-05 and 2011-10-10
the dates given must not in any way exceed the range of the contract
Is there a function for this in PHP ?
See:: http://php.net/manual/en/datetime.diff.php
$datetime1 = new DateTime('2011-10-20');
$datetime2 = new DateTime('2011-10-29');
//PHP 5.3.0
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');
//PHP 5.2.2
var_dump($datetime1 < $datetime2);
$datetime3 = new DateTime('2011-05-05');
$datetime4 = new DateTime('2011-10-10');
if ($datetime3 > $datetime1 && $datetime2 > $datetime1 && $datetime3 < $datetime2 && $datetime2 < $datetime2) {
//valid range
}//end if
$start = strtorime($contract_start_date);
$end = strtotime($contract_end_date);
$required_start = strtotime("2011-05-05");
$required_end = strtotime("2011-10-10");
if ($end > $required_end or $end < $required_start)
{
//out of range
}
if ($start < $required_start or $start > $required_end)
{
//out of range
}
This should give you exactly what you're looking for:
define(CONTRACT_START, "2011-10-20");
define(CONTRACT_END, "2011-10-29");
function checkDateRange($dateArray)
{
foreach($dateArray as $dateStr)
{
$curDate = strtotime($dateStr);
if($curDate < strtotime(CONTRACT_START) || $curDate > strtotime(CONTRACT_END))
{
return false;
}
}
return true;
}
$dates = array( 0 => "2011-10-02", 1 => "2011-10-25");
if(checkDateRange($dates))
{
echo "Dates are within range";
}
else
{
echo "Dates are NOT within range";
}
Find below code to get date difference in days, month and year:
<?php
function datediff($date1,$date2,$format='d'){
$difference = abs(strtotime($date2) - strtotime($date1));
switch (strtolower($format)){
case 'd':
$days = round((($difference/60)/60)/24,0);
break;
case 'm':
$days = round(((($difference/60)/60)/24)/30,0);
break;
case 'y':
$days = round(((($difference/60)/60)/24)/365,0);
break;
}
return $days;
}
//Example
echo datediff('2011-06-1','2010-8-30','D') . ' Days<br />';
echo datediff('2011-06-1','2010-8-30','m') . ' Months<br />';
echo datediff('2011-06-1','2010-8-30','y') . ' Years<br />';
?>
If I have two dates - $end_date and $start_date, how can I express the difference between the two in a format such as "2 Years : 4 Months : 2 Days"?
I know that I can get the difference between the two dates like so:
$dif=strtotime($end_date)-strtotime($today);
But how can I convert that result into the human-readable format, like that shown above?
This is how you can format a timestamp:
echo date('d-m-Y', strtotime($end_date)) // for DD-MM-YYYY format
Are you looking to calculate the difference between 2 dates, in number days?
EDIT: code to find the difference between dates in "XXyear YYmonth ZZday". The code assumes that start and end dates are in YYYY-MM-DD format. If that's not the case for you, please either change them to YYYY-MM-DD format, OR change the arguments to mktime() accordingly.
$endDate = '2011-03-01';
$startDate = '2011-02-02';
$daysPerYear = 365;
$daysPerMonth = 30.4;
$diffDay = $diffMonth = $diffYear = 0;
$endDateTs = mktime(0, 0, 0, substr($endDate, 5, 2), substr($endDate, 8, 2), substr($endDate, 0, 4));
$startDateTs = mktime(0, 0, 0, substr($startDate, 5, 2), substr($startDate, 8, 2), substr($startDate, 0, 4));
$diffDay = ($endDateTs - $startDateTs) / 60 / 60/ 24; // difference between 2 dates in number of days
$diffYear = floor($diffDay / $daysPerYear); // difference in years
$diffDay = $diffDay % $daysPerYear; // balance days
$diffMonth = floor($diffDay / $daysPerMonth); // difference in months
$diffDay = ceil($diffDay % $daysPerMonth); // balance days
echo ($diffYear ? $diffYear . 'year ' : '') . ($diffMonth ? $diffMonth . 'month ' : '') . ($diffDay ? $diffDay . 'day' : '');
Note: I haven't tested the code for all possible date combinations, including leap year etc. Please feel free to tweak as needed.
Hope this helps.
If a coarse difference is enough ("2 years ago"), then you might want to try the Date_HumanDiff PEAR package.
The clean, DRY, professional, modern way to do this is to create two datetime objects and call diff(). The generated diff object will automatically populate year, month, day values for you.
Then you only need to iterate through a lookup array containing your desired units and implode any non-zero results into the plain English output string.
Code (Demo)
$startDate = '2001-04-20';
$endDate = '2015-11-29';
$diff = (new DateTime($startDate))->diff(new DateTime($endDate));
$lookup = [
'y' => 'Year',
'm' => 'Month',
'd' => 'Day',
];
$elements = [];
foreach ($lookup as $property => $word) {
if ($diff->$property) {
$elements[] = "{$diff->$property} $word" . ($diff->$property !== 1 ? 's' : '');
}
}
echo implode(' : ', $elements);
// 14 Years : 7 Months : 9 Days
function is_leap_year($year)
{
if($year % 4 == 0)
{
if($year % 100 == 0)
{
if($year % 400 == 0)
{
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
else
{
return false;
}
}
function calculate_date($now, $end){
$years = date('Y', strtotime($end)) - date('Y', strtotime($now)) ;
if($years < 0)
{
return "Error: year";
}
$mounths = date('m', strtotime($end)) - date('m', strtotime($now)) ;
if($mounths < 0)
{
if($years < 1)
{
return "Error: mounth and year";
}
else
{
$years --;
$mounths += 12;
}
}
$days = date('d', strtotime($end)) - date('d', strtotime($now)) ;
if($days < 0){
if($mounths < 1)
{
if($years < 1)
{
return "Error: day, mounth and year";
}
else
{
$years --;
$mounths += 12;
}
}
else
{
$mounths --;
switch (date('m', strtotime($now)))
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
$days +=31;
break;
case 4:
case 6:
case 9:
case 11:
$days +=30;
break;
case 2:
if(is_leap_year(date('Y', strtotime($now))))
{
$days += 29;
break;
}
else
{
$days += 28;
break;
}
}
}
}
return $years . " Years : " . $mounths . " Months : " . $days . " Days Remaining.";
}
$end_date = new DateTime('2011-08-05');
$end_date = $end_date->format('d-m-Y');
$today = date('d-m-Y');
$remaining = calculate_date($today, $end_date);
echo $remaining;
And if you want to format end_date you can use:
date('d-m-Y', strtotime($end_date))
And after that you can calculate remaining time with calculate_date .