I have a custom post type that I’d like to group in years (in an accordion display) by using the ACF date field. I use the following date format in my ACF and WP settings d/m/Y.
Somehow some posts don’t end up in the correct year but in 1970. How to make sure the date formatting is working as expected?
<?php
// Retrieve the list of posts from your CPT 'accreditations' with ACF fields 'description' and 'date'
$posts = get_posts(array(
'post_type' => 'accreditaties',
'posts_per_page' => -1,
)); ?>
<?php
// Sort the posts by the 'date' field in descending order
usort($posts, function($a, $b) {
$dateA = get_field('acc_aanvangsdatum', $a->ID);
$dateB = get_field('acc_aanvangsdatum', $b->ID);
return strtotime($dateB) - strtotime($dateA);
});
// Create an associative array to group posts by year
$groupedPosts = array();
// Iterate through the sorted list of posts and assign each post to the corresponding year
foreach ($posts as $post) {
$date = get_field('acc_aanvangsdatum', $post->ID);
$year = date('Y', strtotime($date));
if (!isset($groupedPosts[$year])) {
$groupedPosts[$year] = array();
}
$groupedPosts[$year][] = $post;
}
// Iterate through the grouped posts and generate the HTML markup for each year's section
foreach ($groupedPosts as $year => $posts) {
echo '<button class="accordion"><h4>' . $year . '</h4></button>';
echo '<div class="panel accreditaties">';
?>
<div class="grid-container">
<div class="grid-item" id="grid-item-title"><p>Aanvangsdatum</p></div>
<div class="grid-item" id="grid-item-title"><p>Titel</p></div>
<div class="grid-item" id="grid-item-title"><p>Status</p></div>
<div class="grid-item" id="grid-item-title"><p align="right">Uren</p></div>
<?php
// Sort the posts within each year section by date in descending order
usort($posts, function($a, $b) {
$dateA = DateTime::createFromFormat('d/m/Y', get_field('acc_aanvangsdatum', $a->ID));
$dateB = DateTime::createFromFormat('d/m/Y', get_field('acc_aanvangsdatum', $b->ID));
return $dateB <=> $dateA;
});
foreach ($posts as $post) {
$title = get_the_title($post->ID);
$acc_aanvangsdatum = get_field('acc_aanvangsdatum', $post->ID);
$acc_status = get_field('acc_status', $post->ID);
$acc_uren = get_field('acc_uren', $post->ID);
$acc_beschrijving = get_field('acc_beschrijving', $post->ID);
?>
<div class="grid-item"><p><?php echo $acc_aanvangsdatum ?></p></div>
<div class="grid-item"><p><a href="<?php echo get_permalink($post->ID); ?>"><?php echo $title ?></a></p></div>
<div class="grid-items-status-uren">
<div class="grid-item status"><p><?php echo $acc_status ?></p></div>
<div class="grid-item uren"><p align="right"><?php echo $acc_uren ?></p></div>
</div>
<?php
}
echo '</div>'; // Move the closing </grid-containe> tag here
echo '</div>';
}
?><br>
<script>
var years = document.getElementsByClassName("year");
var i;
for (i = 0; i < years.length; i++) {
years[i].addEventListener("click", function() {
var posts = this.nextElementSibling;
if (posts.style.display === "block") {
posts.style.display = "none";
} else {
posts.style.display = "block";
}
});
}
</script>
usort($posts, function($a, $b) {
$dateA = get_field('acc_aanvangsdatum', $a->ID);
$dateB = get_field('acc_aanvangsdatum', $b->ID);
return strtotime($dateB) - strtotime($dateA);
});
“d/m/Y” is not an valid date format for strtotime()
https://www.php.net/manual/en/datetime.formats.php
strtotime() should be interpreting “d/m/Y” as “m/d/Y” so the return should still be within the “Year”, so I’m not sure why it would be an issue, but it’s the only thing that I can see to cause it.
Thank you very much @hube2. I was able to solve it by getting rid of strtotime() all together.. For reference here my code:
<?php
// Retrieve the list of posts from your CPT 'accreditations' with ACF fields 'description' and 'date'
$posts = get_posts(array(
'post_type' => 'accreditaties',
'posts_per_page' => -1,
));
// Create an associative array to group posts by year
$groupedPosts = array();
// Iterate through the list of posts and assign each post to the corresponding year
foreach ($posts as $post) {
$date = get_field('acc_aanvangsdatum', $post->ID);
$parsedDate = DateTime::createFromFormat('d/m/Y', $date);
$year = $parsedDate->format('Y');
if (!isset($groupedPosts[$year])) {
$groupedPosts[$year] = array();
}
$groupedPosts[$year][] = $post;
}
// Sort the grouped posts by year in descending order
krsort($groupedPosts);
// Iterate through the grouped posts and generate the HTML markup for each year's section
foreach ($groupedPosts as $year => $posts) {
echo '<button class="accordion"><h4>' . $year . '</h4></button>';
echo '<div class="panel accreditaties">';
?>
<div class="grid-container">
<div class="grid-item" id="grid-item-title"><p>Aanvangsdatum</p></div>
<div class="grid-item" id="grid-item-title"><p>Titel</p></div>
<div class="grid-item" id="grid-item-title"><p>Status</p></div>
<div class="grid-item" id="grid-item-title"><p align="right">Uren</p></div>
<?php
// Sort the posts within each year section by date in descending order
usort($posts, function($a, $b) {
$dateA = DateTime::createFromFormat('d/m/Y', get_field('acc_aanvangsdatum', $a->ID));
$dateB = DateTime::createFromFormat('d/m/Y', get_field('acc_aanvangsdatum', $b->ID));
return $dateB <=> $dateA;
});
foreach ($posts as $post) {
$title = get_the_title($post->ID);
$acc_aanvangsdatum = get_field('acc_aanvangsdatum', $post->ID);
$acc_status = get_field('acc_status', $post->ID);
$acc_uren = get_field('acc_uren', $post->ID);
$acc_beschrijving = get_field('acc_beschrijving', $post->ID);
?>
<div class="grid-item"><p><?php echo $acc_aanvangsdatum ?></p></div>
<div class="grid-item"><p><a href="<?php echo get_permalink($post->ID); ?>"><?php echo $title ?></a></p></div>
<div class="grid-item status"><p><?php echo $acc_status ?></p></div>
<div class="grid-item uren"><p align="right"><?php echo $acc_uren ?></p></div>
<?php
}
echo '</div>'; // Close the grid-container
echo '</div>'; // Close the panel for the current year
}
?>
<script>
var years = document.getElementsByClassName("year");
var i;
for (i = 0; i < years.length; i++) {
years[i].addEventListener("click", function() {
var posts = this.nextElementSibling;
if (posts.style.display === "block") {
posts.style.display = "none";
} else {
posts.style.display = "block";
}
});
}
</script>
<style>
.grid-container {
display: grid;
grid-template-columns: 17% auto 16% 5%;
grid-column-gap: 0.5em;
}
.grid-item {
border: 0px solid black;
padding: 0em;
}
.grid-items-status-uren {
display: contents;
}
</style>
I think I know what could be causing the original issue now
I said
should be interpreting “d/m/Y” as “m/d/Y”
So if you had a day like 30/01/2023 (30 Jan 2023) then strtotime() tries to use “30” as the month it is returning false (error) and that was likely the source of not sorting them correctly. Any date with a day > the number of days in what it is using for month would return an error.
You must be logged in to reply to this topic.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.