php, get the the highest-closest time to current from array? [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to get most recent date from an array of dates?
I have a timetable which is an array:
array(
'01.01.2012|11:00',
'01.01.2012|14:30',
'01.01.2012|16:24', // example match
'01.01.2012|17:20',
'01.01.2012|17:43',
'02.01.2012|10:20',
'02.01.2012|12:30',
); // etc.
I want a Cron job that will check current date/time and compare to ones in array. First I check if the date is a match, that's no problem. But then I need to find and display the earliest time from that array which is after the current time. If there's no suitable time within the same date then I display the earliest time from the next date.
For example: lets take the array above and current date/time of 01.01.2012|14:45
The date is a match so we continue
The next time from the array 16:24, but how to find it using PHP? And if the current time is higher than anything for the same date in array, then get the earliest time from next date?
Obviously to get the string with correct date I use "foreach" and "if" and it returns fine. But then how do I go through the times?

Convert to timestamp, sort and iteratively compare with current time.
$ts = array_map(
create_function('$a','return strtotime(str_replace("|", " ", $a));'),
$dates);
$len= count($ts); $now = time();
sort($ts);
for($i=0;$i<$len && (!($now<$ts[$i]));$i++);
echo date("d.m.Y|H:i",$ts[$i]);
Functions of Interest
array_map
create_function
str_replace

If you convert these to UNIX timestamps, you can sort them numerically, loop through and take the first item that is larger than the current timestamp.

You might consider converting those dates to UNIX timestamps:
function getUnixTimestamp($string) {
list($date, $time) = explode('|', $string);
return strtotime("$date $time");
}
Then you could use something like:
$array = array(); // from example
$timestamps = array_map('getUnixTimestamp', $array);
$current = time();
// create an array mapping timestamp to string
$keyedArray = array_combine($timestamps, $array);
// sort by timestamp
ksort($keyedArray);
foreach ($keyedArray as $timestamp => $string) {
if ($timestamp > $current) {
// this is the first timestamp after current time
}
}
You may want to do some extra checking on $timestamp, making sure it's either on the same or next day, but it's easier to work with timestmap comparisons than string matches.

Write a comparison function for the date-time format you have then loop through until you find a date greater or equal to your reference date.
function compareDateTime($dt1, $dt2) {
sscanf($dt1, "%d.%d.%d|%d:%d", $day, $month, $year, $hour, $minute);
$comp1 = $year . $month . $day . $hour . $minute;
sscanf($dt1, "%d.%d.%d|%d:%d", $day, $month, $year, $hour, $minute);
$comp2 = $year . $month . $day . $hour . $minute;
return $comp1 - $comp2;
}
Returns -ve when $dt1 < $dt2 and +ve when $dt1 > $dt2

Related

PHP, Date: A Dot appended to a month short representation

I have
date("M.", $datetime)
I want to get this output:
Jan.
Feb.
Mar.
Apr.
May (no dot necessary)
Jun.
Jul.
…
I dont like the idea of an if-statement to check the length/number of month every time a date is generated.
Is there a approach that is more simple? Like changing the month-name in general? Or hooking into the date function itself to implement an if-statement that runs every time the date function runs.
Thanks
If you don't want the dot to appear after May month, you will need a check of some sort - which normally is an if. You could do something like this, check if the month returned by date() isn't May, and add a dot after if it isn't.
$date = date("M", $datetime);
if (date("M") != "May")
$date .= ".";
Otherwise you'd need to implement a function of your own, but in the end - you will have to end up with this again, there's really no way around it - and this is by far the simplest and cleanest way.
You could wrap this into a function. You can't alter the date() function directly, but you can create one of your own.
function my_date($format, int $timestamp = null) {
if ($timestamp === null)
$timestamp = time();
$date = date($format, $timestamp);
if ($format == "M" && date("M", $timestamp) != "May")
$date .= ".";
return $date;
}
Then use it as
echo my_date("M", $datetime);
This seems to be a bit of a hammer to crack a nut, or to avoid an IF statement in this case, but you can create an array with your month names in it and use that to output different month names if you like
$m_arr = [0,'Jan.','Feb.','Mar.','Apr.','May','Jun.',
'Jul.', 'Aug.', 'Sep.','Oct.','Nov.','Dec.'];
$m = (int)date('n', $datetime);
echo $m_arr[$m];

How to determine if a date is more than three months past current date

I am getting a date back from a mysql query in the format YYYY-MM-DD.
I need to determine if that is more than three months in the past from the current month.
I currently have this code:
$passwordResetDate = $row['passwordReset'];
$today = date('Y-m-d');
$splitCurrentDate = explode('-',$today);
$currentMonth = $splitCurrentDate[1];
$splitResetDate = explode('-', $passwordResetDate);
$resetMonth = $splitResetDate[1];
$diferenceInMonths = $splitCurrentDate[1] - $splitResetDate[1];
if ($diferenceInMonths > 3) {
$log->lwrite('Need to reset password');
}
The problem with this is that, if the current month is in January, for instance, giving a month value of 01, and $resetMonth is November, giving a month value of 11, then $differenceInMonths will be -10, which won't pass the if() statement.
How do I fix this to allow for months in the previous year(s)?
Or is there a better way to do this entire routine?
Use strtotime(), like so:
$today = time(); //todays date
$twoMonthsLater = strtotime("+3 months", $today); //3 months later
Now, you can easily compare them and determine.
I’d use PHP’s built-in DateTime and DateInterval classes for this.
<?php
// create a DateTime representation of your start date
// where $date is date in database
$resetDate = new DateTime($date);
// create a DateIntveral representation of 3 months
$passwordExpiry = new DateInterval('3M');
// add DateInterval to DateTime
$resetDate->add($passwordExpiry);
// compare $resetDate to today’s date
$difference = $resetDate->diff(new DateTime());
if ($difference->m > 3) {
// date is more than three months apart
}
I would do the date comparison in your SQL expression.
Otherwise, PHP has a host of functions that allow easy manipulation of date strings:
PHP: Date/Time Functions - Manual

PHP - checking if two dates match but ignoring the year

I have an array which will output a date. This date is outputted in the mm/dd/yyyy format. I have no control over how this outputted so I cant change this.
Array
(
[date] => 04/06/1989
)
I want to use php to check if this date matches the current date (today), but ignoring the year. So in the above example I just want to check if today is the 6th April. I am just struggling to find anything which documents how to ignore the years.
if( substr( $date, 0, 5 ) == date( 'm/d' ) ) { ...
Works only if it's certain that the month and date are both two characters long.
Came in a little late, but here’s one that doesn’t care what format the other date is in (e.g. “Sep 26, 1989”). It could come in handy should the format change.
if (date('m/d') === date('m/d', strtotime($date))) {
echo 'same as today';
} else {
echo 'not same as today';
}
this will retrieve the date in the same format:
$today = date('m/d');
Use this:
$my_date = YOUR_ARRAY[date];
$my_date_string = explode('/', $my_date);
$curr_date = date('m,d,o');
$curr_date_string = explode(',', $date);
if (($my_date_string[0] == $curr_date_string[0]) && ($my_date_string[1] == $curr_date_string[1]))
{
DO IT
}
This way, you convert the dates into strings (day, month, year) which are saved in an array. Then you can easily compare the first two elements of each array which contains the day and month.
You can use for compare duple conversion if you have a date.
$currentDate = strtotime(date('m/d',time())); --> returns current date without care for year.
//$someDateTime - variable pointing to some date some years ago, like birthday.
$someDateTimeUNIX = strtotime($someDateTime) --> converts to unix time format.
now we convert this timeunix to a date with only showing the day and month:
$dateConversionWithoutYear = date('m/d',$someDateTimeUNIX );
$dateWithoutRegardForYear = strtotime($dateConversionWithoutYear); -->voila!, we can now compare with current year values.
for example: $dateWithoutRegardForYear == $currentDate , direct comparison
You can convert the other date into its timestamp equivalent, and then use date() formatting to compare. Might be a better way to do this, but this will work as long as the original date is formatted sanely.
$today = date('m/Y', time());
$other_date = date('m/Y', strtotime('04/06/1989'));
if($today == $other_date) {
//date matched
}
hi you can just compare the dates like this
if(date('m/d',strtotime($array['date']])) == date('m/d',strtotime(date('Y-m-d H:i:s',time()))) )

How to convert date into same format?

I want to get the $registratiedag and count a couple of days extra, but I always get stuck on the fact that it needs to be a UNIX timestamp? I did some google-ing, but I really don't get it.
I hope someone can help me figure this out. This is what I got so far.
$registratiedag = $oUser['UserRegisterDate'];
$today = strtotime('$registratiedag + 6 days');
echo $today;
echo $registratiedag;
echo date('Y-m-d', $today);
There's obviously something wrong with the strtotime('$registratiedag + 6 days'); part, because I always get 1970-01-01
You probably want this:
// Store as a timestamp
$registratiedag = strtotime($oUser['UserRegisterDate']);
$new_date = strtotime('+6 days', $registratiedag);
// You'll need to format for printing $new_date
echo date('Y-m-d', $new_date);
// I think you want to compare $new_date against
// today's date. I'd recommend a string comparison here,
// As time() includes the time as well
// time() is implied as the second argument to date,
// But we'll put it anyways just to be clearer
if( date('Y-m-d', $new_date) == date('Y-m-d', time()) ) {
// The dates are equal, do something here
}
else if($new_date < time()) {
// if the new date is earlier than today
}
// etc.
First it converts $registratiedag to a timestamp, then it adds 6 days
EDIT: You probably should change $today to something less misleading like $modified_date or something
try:
$today = strtorime($registratiedag);
$today += 86400 * 6; // seconds in 1 day * 6 days
at least one of your problems is that PHP does not expand variables in single quotes.
$today = strtotime("$registratiedag + 6 days");
//use double quotes and not single quotes when embedding a php variable in a string
If you want to include the value of variable $registratiedag right into the text passed as parameter of strtotime, you have to enclose that parameter with ", not with '.

PHP shortcut to find smallest number / date

I have a situation whereby a series of 15 dates have been created, currently in UNIX timestamps.
Another variable <?php $dateidate = date(strtotime('+20 days')); ?>
The objective is to find the smallest of the 15 other dates that is greater > than $dateidate and display in the format of 'd-m-Y'
Once we've done that is there a way to get the second smallest of the 15 other dates that is greater > than $dateidate and display in the format of 'd-m-Y'.
So, you have 15 dates which are UNIX timestamps. Useful.
Ok, here's what you can do to do it easily:
$datearray = array(timestamp1,timestamp2,etc.) // an array of timestamps
$dateidate = time() + 1728000; //current time + 20 days worth of seconds (20 * 24 * 60 * 60)
foreach($datearray as $key => $date)
{
if($date < $dateidate)
{
unset $datearray[$key]; //Remove timestamp from original array if less than $dateidate
}
}
$earliestdate = min($datearray);
//min returns the least of the values in the array, opposite of max, which you could use to find the latest date in the array
$date = date('d-m-Y',$earliestdate);
strtotime generates a timestamp.
instead of this:
<?php $dateidate = date(strtotime('+20 days')); ?>
do this:
<?php $dateidate = strtotime('+20 days'); ?>
Put all timestamps into an array with special keys so you can distinguish which one is your pivot.
Sort that array and do what you need to do with the sorted array.
This solution filters the $dates array which stores the timestamps using an anonymous function, so in the $shorterOnes array you will have all the timestamps that are bigger than $dateidate.
Then the array is sorted, the first one will be smallest and so on.
$dateidate=strtotime('+20 days');
$dates=array(/*timestamps*/);
$shorterOnes=array_filter($dates, function ($v) use ($dateidate) {
return $v>$dateidate;
});
sort($shorterOnes);
echo date('d-m-Y', $shorterOnes[0]);
echo date('d-m-Y', $shorterOnes[1]);
Anonymous functions only work from PHP 5.3. Lower than that, you need to use create_function().

Categories