Upcoming Dates

So, I am creating an array of different dates. Birthdays, anniversaries and holidays. I would like to order an array by which the next one happens, essentially sort from October to September (carryover to next year)

so if my array

$a = ([0]=>"1980-04-14", [1]=>"2007-06-08", 
  [2]=>"2008-12-25", [3]=>"1978-11-03")

I would like to sort it so that it is

$a = ([0]=>"1978-11-03", [1]=>"2008-12-25", 
  [2]=>"1980-04-14", [3]=>"2007-06-08")

because the November "event" is what happens next (October will be on it).

I am trying to use where is my cmp function

function cmp($a, $b)
{
  $a_tmp = split("-", $a);
  $b_tmp = split("-", $b);
  return strcmp($a_tmp[1], $b_tmp[1]);
} 

I am not sure how to change this to get the desired effect.

+3
source share
6 answers
function relative_year_day($date) {
    $value = date('z', strtotime($date)) - date('z');

    if ($value < 0)
        $value += 365;

    return $value;
}

function cmp($a, $b)
{
    $aValue = relative_year_day($a);
    $bValue = relative_year_day($b);

    if ($aValue == $bValue)
        return 0;

    return ($aValue < $bValue) ? -1 : 1;
}

$a = array("1980-04-14", "2007-06-08",
    "2008-12-25", "1978-11-03");

usort($a, "cmp");
+3
source

, , , , ( ). , , . .

:

PHP, , Perl.

#!/bin/perl -w

# Sort sequence of dates by next occurrence of anniversary.
# Today "birthdays" count as low (will appear first in sequence)

use strict;

my $refdate = "2008-10-05";

my @list = (
    "1980-04-14", "2007-06-08",
    "2008-12-25", "1978-11-03",
    "2008-10-04", "2008-10-05",
    "2008-10-06", "2008-02-29"
);

sub date_on_or_after
{
    my($actdate, $refdate) = @_;
    my($answer) = $actdate;
    if ($actdate lt $refdate)   # String compare OK with ISO8601 format
    {
        my($act_yy, $act_mm, $act_dd) = split /-/, $actdate;
        my($ref_yy, $ref_mm, $ref_dd) = split /-/, $refdate;
        $ref_yy++ if ($act_mm < $ref_mm || ($act_mm == $ref_mm && $act_dd < $ref_dd));
        $answer = "$ref_yy-$act_mm-$act_dd";
    }
    return $answer;
}

sub anniversary_compare
{
    my $r1 = date_on_or_after($a, $refdate);
    my $r2 = date_on_or_after($b, $refdate);
    return $r1 cmp $r2;
}

my @result = sort anniversary_compare @list;

print "Before:\n";
print "* $_\n" foreach (@list);
print "Reference date: $refdate\n";
print "After:\n";
print "* $_\n" foreach (@result);

, - , date_on_or_after() , . Perl - $a $b .

script :

Before:
* 1980-04-14
* 2007-06-08
* 2008-12-25
* 1978-11-03
* 2008-10-04
* 2008-10-05
* 2008-10-06
* 2008-02-29
Reference date: 2008-10-05
After:
* 2008-10-05
* 2008-10-06
* 1978-11-03
* 2008-12-25
* 2008-02-29
* 1980-04-14
* 2007-06-08
* 2008-10-04

, , 29 , "" . , "" 2009-02-29, . 2000-200-28 2008-02-29 ( 2000-02-28).

+1

12 , . .

function cmp($a, $b)
{
$a_tmp = explode("-", $a["date"]);
$b_tmp = explode("-", $b["date"]);
if ($a_tmp[1] < date("m"))
{
  $a_tmp[1] += 12;
}
if ($b_tmp[1] < date("m"))
{
  $b_tmp[1] += 12;
}
return strcmp($a_tmp[1] . $a_tmp[2], $b_tmp[1] . $b_tmp[2]);
} 
0

strtotime(), , , ( ). , , , ,

.

for ($i=0; $i<count($a); $i++){
  if ($currentTimestamp > $a[$i]){
    unset($a[$i]);
  }
}
0

. , .

$a = array_combine(array_map('strtotime', $a), $a);
ksort($a);

, .

function dateCmp($date1, $date2) {
  return (strtotime($date1) > strtotime($date2))?1:-1;
}

usort($a, 'dateCmp');

, , uasort .

uasort($a, 'dateCmp');

, .

0

, 1970 (ints):

$date1 = split("-", $a);
$date2 = split("-", $b);
$seconds1 = mktime(0,0,0,$date1[1],$date1[2],$date1[0]);
$seconds2 = mktime(0,0,0,$date2[1],$date2[2],$date2[0]);
// eliminate years
$seconds1 %= 31536000;
$seconds2 %= 31536000;
return $seconds1 - $seconds2;

PHP, , .

: , . , , , .

-1

Source: https://habr.com/ru/post/1697871/


All Articles