---
slug: "時間分岐のテンプレートタグifbeforeifafterifafterbefore"
title: "時間分岐のテンプレートタグ ifbefore ifafter ifafterbefore"
description: "# -*- coding: utf-8 -*-"
url: "https://www.ytyng.com/blog/時間分岐のテンプレートタグifbeforeifafterifafterbefore"
publish_date: "2011-09-10T11:20:24Z"
created: "2011-09-10T11:20:24Z"
updated: "2026-02-26T21:50:03.570Z"
categories: ["Django"]
keywords: ""
featured_image_url: "https://media.ytyng.com/resize/20230812/f8603f3114b44ceda29ba7a939211f05.png.webp?width=768"
has_video: false
has_music: false
video_urls: []
music_urls: []
lang: "ja"
---

# 時間分岐のテンプレートタグ ifbefore ifafter ifafterbefore

<pre><cord># -*- coding: utf-8 -*-
"""
時間を判定して表示分岐させるテンプレートタグ
例:
{% ifbefore '2011-12-24 20:00:00' %}
    ここは 2011-12-24 20:00:00 未満に表示される
{% else %}
    ここは 2011-12-24 20:00:00 以後に表示される
{% endifbefore %}

引数は、datetimeの他、
'%Y-%m-%d %H:%M:%S', '%Y-%m-%d', '%H:%M:%S' 形式の日付文字列が使える
"""

import datetime

from django import template
from django.template import Node, NodeList, resolve_variable

register = template.Library()

class IfAfterBeforeNode(Node):
    child_nodelists = ('nodelist_true', 'nodelist_false')
    datestr_format_list = ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d', '%H:%M:%S')

    def __init__(self, var_after, var_before, nodelist_true, nodelist_false=None):
        self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
        self.var_after = var_after
        self.var_before = var_before
        self.now = datetime.datetime.now()

    def strptime(self, date_string):
        """
        日付文字列をパースしてdatetimeにする。
        パースできなければNone
        """
        date_string = date_string.strip("""'" """)
        for datestr_format in self.datestr_format_list:
            try:
                return datetime.datetime.strptime(date_string, datestr_format)
            except ValueError:
                pass
        return None

    def __repr__(self):
        return "&lt;IfBeforeAfter node&gt;"

    def __iter__(self):
        for node in self.nodelist_true:
            yield node
        for node in self.nodelist_false:
            yield node

    def arg_to_dt_or_none(self, arg, context):
        """
        引数を datetime もしくは none として取得
        self.var_after, self.var_before に使う
        """
        if not arg:
            return None
        try:
            # 引数がdatetimeの場合があるので
            dt = resolve_variable(arg, context)
        except template.VariableDoesNotExist:
            dt  = None
        if dt is None or not isinstance(dt,  datetime.datetime):
            dt = self.strptime(arg)
        return dt

    def render(self, context):

        dt_after  = self.arg_to_dt_or_none(self.var_after,  context)
        dt_before = self.arg_to_dt_or_none(self.var_before, context)

        if dt_after and dt_before:
            if dt_after &lt;= self.now &lt; dt_before:
                return self.nodelist_true.render(context)
            else:
                return self.nodelist_false.render(context)
        elif dt_after:
            if dt_after &lt;= self.now:
                return self.nodelist_true.render(context)
            else:
                return self.nodelist_false.render(context)
        elif dt_before:
            if self.now &lt; dt_before:
                return self.nodelist_true.render(context)
            else:
                return self.nodelist_false.render(context)
        else:
            return u'Parse Error. No after, before'

@register.tag
def ifbefore(parser, token):
    """
    現在日時が"YYYY-MM-DD HH:MM:SS" より前(未満)であればレンダリング
    """
    _tagname, var_before = token.split_contents()
    nodelist_true = parser.parse(('else', 'endifbefore'))
    token = parser.next_token()
    if token.contents == 'else':
        nodelist_false = parser.parse(('endifbefore',))
        parser.delete_first_token()
    else:
        nodelist_false = NodeList()
    return IfAfterBeforeNode(None, var_before, nodelist_true, nodelist_false)

@register.tag
def ifafter(parser, token):
    """
    現在日時が"YYYY-MM-DD HH:MM:SS" より後(以上)であればレンダリング
    """
    _tagname, var_after = token.split_contents()
    nodelist_true = parser.parse(('else', 'endifafter'))
    token = parser.next_token()
    if token.contents == 'else':
        nodelist_false = parser.parse(('endifafter',))
        parser.delete_first_token()
    else:
        nodelist_false = NodeList()
    return IfAfterBeforeNode(var_after, None, nodelist_true, nodelist_false)

@register.tag
def ifafterbefore(parser, token):
    """
    2つの引数をとり、現在時刻がその以上未満であればレンダリング
    """
    _tagname, var_after, var_before = token.split_contents()

    nodelist_true = parser.parse(('else', 'endifafterbefore'))
    token = parser.next_token()
    if token.contents == 'else':
        nodelist_false = parser.parse(('endifafterbefore',))
        parser.delete_first_token()
    else:
        nodelist_false = NodeList()
    return IfAfterBeforeNode(var_after, var_before, nodelist_true, nodelist_false)</cord></pre>
