Django datetimeが日本時間にならないときの対処法

プログラミング

先日Djangoにて、データベースに登録されてる日時は日本時間だが、表示時間は標準時間になってしまうという問題が発生したため、対処法を記載します。

問題

簡単なDjangoのコードとともに原因を説明します。
以下のようなDjangoのコードがあります。

from django.db import models
from django.utils import timezone

class Name(models.Model):
        date = models.DateTimeField(default=timezone.now)
        name = models.CharField(max_length=20)

        def __str__(self):
            return self.name
from django.shortcuts import render
from django.views import View

from .models import Name

class IndexView(View):
    def get(self, request):

        content = Name.objects.all()

        params = {
            'content': content,
        }

        return render(request, 'example_app/index.html', params)
{% block main %}

  <table>
    <tr>
      <th>日付</th>
      <th>名前</th>
    </tr>
    {% for item in content %}
    <tr>
      <td>{{ item.date }}</td>
      <td>{{ item.name }}</td>
    </tr>
    {% endfor %}

{% endblock %}

これをブラウザ上で表示すると以下のようになります。

この時の日付は日本時間です。

しかし、この日付を文字列にして、リストにする必要がありありました。
その時、リストに追加された時間は標準時間(UTC)に変換されてしまいます。

from django.shortcuts import render
from django.views import View

from .models import Name

class IndexView(View):
    def get(self, request):

        content = Name.objects.all()

        date = []
        name = []

        for i in content:
            datetime = i.date.strftime(('%y/%m/%d %H:%M'))
            date.append(datetime)
            name.append(i.name)

        params = {
            'content': content,
            'date': date,
            'name': name,
        }

        return render(request, 'example_app/index.html', params)

原因

現時点でわかりません。

もしわかる人がいたら教えていただきたいです。

対処方法

標準時間と日本時間は9時間の時差があります。

よって、9時間加えてあげると、リストの形でも日本時間になります。

時間の加算や減算は、Pythonの標準ライブラリであるtimedeltaを使用します。
timedeltaはdattetimeモジュールに含まれています。

以下のようにviews.pyを書き換えました。

from django.shortcuts import render
from django.views import View
from datetime import timedelta #追加

from .models import Name

class IndexView(View):
    def get(self, request):

        content = Name.objects.all()

        date = []
        name = []

        for i in content:
            datetime = i.date + timedelta(hours=9) #修正
            datetime = datetime.strftime(('%y/%m/%d %H:%M')) #修正
            date.append(datetime)
            name.append(i.name)

        params = {
            'content': content,
            'date': date,
            'name': name,
        }

        return render(request, 'example_app/index.html', params)

これでクエリーセットで渡した日時とリストで渡した日時の表示が同じになりました。

もし3日加算したい場合は、hoursをdaysに変更したりして、timedeltaを上手に活用してください。

コメント

タイトルとURLをコピーしました