user7232034
user7232034

Reputation:

PHP: How to check the season of the year and set a class accordingly

I have a website which uses 4 different background images for the header area which visually corresponds to the season of the ear (summer, autumn etc.) – for the summer timeframe I use one image, for the autumn – another one and so on. The problem is that I have to manually change those images once the season of the year changes.

Maybe someone could show how would it be possible to check the current time / season of the year and then print the corresponding classes to the header element (.summer, .autumn etc.)?

I assume using PHP would be the way.

Upvotes: 6

Views: 9057

Answers (6)

Stephen Ball
Stephen Ball

Reputation: 1

If you are willing to be as 'inaccurate' as grouping three whole months into each season, you could do this (just replacing the season name with the name of the individual image file).

<?php
$SEASONS = [1 => "WINTER", 2 => "WINTER", 3 => "SPRING",  4 => "SPRING",  5 => "SPRING",  6 => "SUMMER", 7 => "SUMMER", 8 => "SUMMER", 9 => "AUTUMN", 10 => "AUTUMN", 11 => "AUTUMN", 12 => "WINTER"];

echo $SEASONS[idate("m")];
?>

Reference:

Upvotes: 0

Itskey
Itskey

Reputation: 11

// Winter (1), Spring (2), Summer (3), Autumn (4)
$season = ceil(date("m", strtotime("+1 months"))/3);

Upvotes: 1

Tobias Boss
Tobias Boss

Reputation: 11

you can get the index of the current season with this 1 line function

season(date('m'));
function season($month)
{
    return ($month + 1) === 13 ? 0 : ceil(($month + 1) / 3) - 1;
}

Upvotes: 0

Shoelaced
Shoelaced

Reputation: 881

I know this question is quite old, but none of the answers on this or any of the other questions that ask this question account for timezones, hemispheres, and different calendars in the same function, and since this came up first when I Googled for this, here's what I ended up writing myself.

If you want to get fancier you could calculate the actual Astronomical dates, geolocate the user, internationalize the season name output, etc., but that's beyond the scope of this question anyway.

function get_season( string $date = '', string $timezone = 'Europe/London', string $hemisphere = 'northern', string $calendar = 'meteorological' ): string {

    // Create the calendars that you want to use for each hemisphere.
    $seasons = array(
        'northern' => array(
            'astronomical'   => array(
                'spring' => '03-20', // mm-dd
                'summer' => '06-21',
                'autumn' => '09-22',
                'winter' => '12-21',
            ),
            'meteorological' => array(
                'spring' => '03-01',
                'summer' => '06-01',
                'autumn' => '09-01',
                'winter' => '12-01',
            ),
        ),
        'southern' => array(
            'astronomical'   => array(
                'spring' => '09-22',
                'summer' => '12-21',
                'autumn' => '03-20',
                'winter' => '06-21',
            ),
            'meteorological' => array(
                'spring' => '09-01',
                'summer' => '12-01',
                'autumn' => '03-01',
                'winter' => '06-01',
            ),
        ),
    );

    // Set $date to today if no date specified.
    if ( empty( $date ) ) {
        $date = new \DateTimeImmutable( 'now', new \DateTimeZone( $timezone ) );
    } else {
        $date = new \DateTimeImmutable( $date, new \DateTimeZone( $timezone ) );
    }

    // Set the relevant defaults.
    $seasons        = $seasons[ strtolower( $hemisphere ) ][ strtolower( $calendar ) ];
    $current_season = array_key_last( $seasons );
    $year           = $date->format( 'Y' );

    // Return the season based on whether its date has passed $date.
    foreach ( $seasons as $season => $start_date ) {

        $start_date = new \DateTimeImmutable( $year . '-' . $start_date, new \DateTimeZone( $timezone ) );

        if ( $date < $start_date ) {
            return $current_season;
        }

        $current_season = $season;
    }

    return $current_season;
}

Usage

// Pass nothing to get current meteorological season in the Northern hemisphere.
echo get_season();

// Pre-PHP 8.0, though I've only tested it on 7.4.
echo get_season( 'December 18', 'Europe/London', 'northern', 'astronomical' );

// After PHP 8.0 you can use named arguments to skip the defaults.
echo get_season( 'December 18', calendar: 'astronomical' );

Outputs

winter // Current season.
autumn
autumn // If PHP 8.0, otherwise error.

I personally like that it lets me add calendars if I discover something unique, like for example, the beginning of Summer is always the first Thursday after April 18th in Iceland.

Upvotes: 1

MjhaL
MjhaL

Reputation: 59

One might consider this necromancy, Yet when I was looking for ready to use method that does this I've got here. Mister Martin answer was good assuming the year will not changes, here is my snippet, might be useful for someone in future:

private function timestampToSeason(\DateTime $dateTime): string{
    $dayOfTheYear = $dateTime->format('z');
    if($dayOfTheYear < 80 || $dayOfTheYear > 356){
        return 'Winter';
    }
    if($dayOfTheYear < 173){
        return 'Spring';
    }
    if($dayOfTheYear < 266){
        return 'Summer';
    }
    return 'Fall';
}

cheers!

Upvotes: 5

mister martin
mister martin

Reputation: 6252

As I stated in the comments, this is an interesting challenge because the dates of seasons are always changing and different depending what part of the world you live in. Your server time and the website visitor's local time are also a factor.

Since you've stated you're just interested in a simple example based on server time and you're not concerned with it being exact, this should get you rolling:

// get today's date
$today = new DateTime();
echo 'Today is: ' . $today->format('m-d-Y') . '<br />';

// get the season dates
$spring = new DateTime('March 20');
$summer = new DateTime('June 20');
$fall = new DateTime('September 22');
$winter = new DateTime('December 21');

switch(true) {
    case $today >= $spring && $today < $summer:
        echo 'It\'s Spring!';
        break;

    case $today >= $summer && $today < $fall:
        echo 'It\'s Summer!';
        break;

    case $today >= $fall && $today < $winter:
        echo 'It\'s Fall!';
        break;

    default:
        echo 'It must be Winter!';
}

This will output:

Today is: 11-30-2016
It's Fall!

Upvotes: 8

Related Questions