Custom Post Type date archive links in WordPress

Custom Post Type date archive links are not supported out-of-box within WordPress (as of 3.6 beta). Nor are CPT date archives, but that’s another post (coming soon). The built-in date archive link functions (get_year_link, get_month_link, get_day_link) only work for Post archives.

Here is a function that will create your date archive links for you. I had a fallback of giving you get_post_type_archive{}, but took it out. If there is ever the case of not having the year, you should just use get_post_type_archive{} directly.

This function also automatically handles any rewrites you have for custom post types. I often use prefixes at work as best practice, and nobody wants eh-events in their URL string!

Let me know if you find a more efficient way of doing this. I’d love to direct to your source, or at least update mine! :)

The Function

 * This allows us to generate any archive link - plain, yearly, monthly, daily
 * @param string $post_type
 * @param int $year
 * @param int $month (optional)
 * @param int $day (optional)
 * @return string
function EH_get_post_type_date_link( $post_type, $year, $month = 0, $day = 0 ) {
    global $wp_rewrite;
    $post_type_obj = get_post_type_object( $post_type );
    $post_type_slug = $post_type_obj->rewrite['slug'] ? $post_type_obj->rewrite['slug'] : $post_type_obj->name;
    if( $day ) { // day archive link
        // set to today's values if not provided
        if ( !$year )
            $year = gmdate('Y', current_time('timestamp'));
        if ( !$month )
            $month = gmdate('m', current_time('timestamp'));
        $link = $wp_rewrite->get_day_permastruct();
    } else if ( $month ) { // month archive link
        if ( !$year )
            $year = gmdate('Y', current_time('timestamp'));
        $link = $wp_rewrite->get_month_permastruct();
    } else { // year archive link
        $link = $wp_rewrite->get_year_permastruct();
    if ( !empty($link) ) {
        $link = str_replace('%year%', $year, $link);
        $link = str_replace('%monthnum%', zeroise(intval($month), 2), $link );
        $link = str_replace('%day%', zeroise(intval($day), 2), $link );
        return home_url( "$post_type_slug$link" );
    return home_url( "$post_type_slug" );