Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Djangoでタイムゾーンとうまく付き合う
Search
mizzsugar
November 13, 2019
Programming
820
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Djangoでタイムゾーンとうまく付き合う
mizzsugar
November 13, 2019
More Decks by mizzsugar
See All by mizzsugar
自分のPCにPython環境を用意して_VSCodeでStreamlitアプリを動かすまでの8ステップ.pdf
mizzsugar
0
70
Colabのみで初心者向けPythonハンズオン.pdf
mizzsugar
0
60
厳しさとゆるさの間で迷う人に捧げる個人開発記
mizzsugar
0
67
SQLModel入門〜クエリと型〜
mizzsugar
3
1.6k
フルリモート向いてないと思っていた私が、なんだかんだ健やかに 1年半フルリモート出来ている話
mizzsugar
1
160
Djangoでのプロジェクトだって型ヒントを運用出来る!
mizzsugar
4
9.1k
「動くものは作れる」の一歩先へ 〜「自走プログラマー」の紹介〜
mizzsugar
0
650
pytestの第一歩 〜「テスト駆動Python」の紹介〜
mizzsugar
3
480
データ分析ツール開発でpoetryを使う選択肢
mizzsugar
1
1.2k
Other Decks in Programming
See All in Programming
地域 SRE コミュニティ最前線 - ホンマでっかSRE勉強会
tk3fftk
0
240
コーディングルールの鮮度を保ちたい for SRE NEXT 2026 / keep-fresh-go-internal-conventions-sre-next-2026
handlename
0
140
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
320
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
460
Performance Engineering for Everyone
elenatanasoiu
0
270
はてなアカウント基盤 State of the Union
cockscomb
1
1.3k
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
140
20260623_Loop Engineeringで自分の分身の問い合わせBotを作る
ryugen04
0
220
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
2.7k
The Bowling Game- From Imperative to Functional Programming - Part 1
philipschwarz
PRO
0
330
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.5k
Featured
See All Featured
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
200
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Optimising Largest Contentful Paint
csswizardry
37
3.8k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
260
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
210
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
The Spectacular Lies of Maps
axbom
PRO
1
860
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
30 Presentation Tips
portentint
PRO
1
350
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
610
A Tale of Four Properties
chriscoyier
163
24k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Transcript
Djangoでタイムゾーンと うまく付き合う 2019/11/13 Stapy @mizzsugar0425
お前、誰よ • みずきと申します。 • やっていること↓ ◦ 昼:データ分析のデータ基盤のデータマネジメント (GCP: 特にBigQuery) ◦
夜:PythonでWebアプリ開発(Pyramid, PostgreSQL, Nuxt.js, TypeScript) ◦ つい最近まで仕事で Djagoいじってたので趣味で Django触ったりもします ◦ Twitter -> @mizzsugar0425 • コーヒーと自転車が好き • 今週末はDjangogirlsのコーチやります! <- 今日の話のきっかけ
DjangogirlsTutorialの復習をしていたときのこと
しれっと使ってるdjango.utils.timezone.now from django.conf import settings from django.db import models from
django.utils import timezone class Post(models.Model): author = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE) title = models.CharField(max_length=200) text = models.TextField() created_date = models.DateTimeField(default=timezone.now) published_date = models.DateTimeField(blank=True, null=True) def publish(self): self.published_date = timezone.now() self.save() https://tutorial.djangogirls.org/ja/django_models/
なぜPython標準ライブラリの datetime.datetime.now()ではないの?
秘密はここにあった! USE_TZ = True settings.py
USE_TZ=Trueだとタイムゾーンサポートが有効 今19時 だよー 今10時 だよー
タイムゾーンサポートがあるなら settings.pyで TIMEZONE = ‘Asia/Tokyo’と設定している場合・・・ • テンプレート上で日本時間を表示してくれて便利! • settings.pyのTIMEZONEを変更したらその場所の現地時間を表示 •
複数のタイムゾーンを使う場合、どのタイムゾーンの時間を表示するか設定す ればどのタイムゾーンの時間を表示するかそれぞれ振り分けてくれる※ ※公式ドキュメントにタイムゾーンを選択して表示するための実装例があります ↓ https://docs.djangoproject.com/ja/2.2/topics/i18n/timezones/#selecting-the-current-time-zone
内部ではどうなっているの? >>> from django.contrib.auth.models import User >>> from blog.models import
Post >>> >>> author = User.objects.create(username='dummy', email='
[email protected]
') >>> post = Post.objects.create( author=author, title='dummy', text='dummy' ) >>> post.publish() # 日本時間で2019/10/10 19:00:00に実行 >>> post.published_date datetime.datetime(2019, 10, 10, 10, 0, 0, tzinfo=<UTC>) 19時じゃない! UTCって!?
前提知識:nativeとawareという概念 ざっくりPythonでは 日時を扱うdatetimeモジュールのdatetimeオブジェクトを • タイムゾーンなしのdatetimeオブジェクトはnative ex: datetime.datetime(2019, 10, 10, 19,
0, 0) • タイムゾーンありのdatetimeオブジェクトはaware ex: datetime.datetime(2019, 10, 10, 19, 0, 0, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>) と分けている もっと詳しい説明は公式ドキュメントで ↓ https://docs.python.org/ja/3/library/datetime.html#aware-and-naive-objects
UTCとは • 協定世界時(Coordinated Universal Time)のこと • 今の世界で標準時として使っている時間のこと • 日本の場合だと、世界の標準時間より9時間早い https://wa3.i-3-i.info/word11831.html
内部的な話① • テンプレート上やフォームではタイムゾーンが現地のawareなdatetimeオブジェ クト ex:2019年10月10日 19時0分0秒, datetime.datetime(2019, 10, 10, 19,
0, 0, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>) • モデルのインスタンスのpublished_dateアトリビュートを取り出すとタイムゾーン がUTCのawareなdatetimeオブジェクト ex: datetime.datetime(2019, 10, 10, 10, 0, 0, tzinfo=<UTC>) • データベース上ではタイムゾーンなしの時間(値としてはUTCでの時間) ex:2019-10-10 10:00:00 ※PostgreSQLだと2019-10-10 10:00:00+00
内部的な話② • Djangoでは、タイムゾーンサポートを有効にした場合、datetimeオブジェクトは タイムゾーンがsettings.pyのTIME_ZONEで指定した箇所のawereなdatetime オブジェクトとして処理される • 内部的な処理にはタイムゾーンがUTCのawareなdatetimeオブジェクトを使い、 エンドユーザー入出力を行うレイヤー(テンプレートやフォームなど)では現地時 間でやり取りする仕組み •
内部処理にタイムゾーンがUTCのdatetimeオブジェクトを使うと、複数のタイム ゾーンに柔軟かつ安全に変換できるのが良いという思想
1つのタイムゾーンでしか使わなくても • 夏時間 (DST) 変換まわりのバグを防げる • native -> awareに変換した際に意図しない値に変換してしまうバグを防げる •
Djangoがawareなdatetimeオブジェクトを想定している処理でnativeなオブジェ クトを使うことによるバグを防げる • django-admin startprojectコマンドで作られるプロジェクトでタイムゾーンサ ポートありになっていることからもタイムゾーンサポートありの方がいいと主張し ていることがうかがえる
datetime.datetime.now()の話に戻ると・・・ >>> from django.utils import timezone >>> import datetime >>>
>>> from django.utils import timezone >>> >>> # nativeなdatetimeオブジェクト >>> datetime.datetime.now() datetime.datetime(2019, 11, 12, 18, 0, 39, 452139) >>> >>> # タイムゾーンがUTCであるawareなdatetimeオブジェクト >>> timezone.now() datetime.datetime(2019, 11, 12, 9, 0, 46, 708708, tzinfo=<UTC>)
USE_TZ=Trueでnativeなオブジェクトを使うと RuntimeWarning: DateTimeField received a naive datetime * to while
time zone support is active. Djangoから「タイムゾーンサポートが有効な時にnativeなdatetimeオブジェク トを使わないでください」と注意されます。
つまりdatetime.datetime.now()は使わない訳は タイムゾーンサポートが有効な設定をしているから 使っても動きはするけれども native -> awareの変換周りで苦労するやも
まとめ • Pythonのdatetimeオブジェクトにはnativeとawareという概念があり、前者 がタイムゾーンなしで後者がタイムゾーンありの日時(ざっくり) • Djangoではタイムゾーンサポートを有効にした方が安全 • タイムゾーンサポートを有効にした場合、Djangoでは内部的な処理ではタ イムゾーンがUTCの日時を使い、画面やフォームで現地時間に柔軟に変 換できるようにしている
もっと詳しくはブログで! https://mizzsugar.hatenablog.com/entry/2019/11/07/094230 「テンプレートでは日本時間が表示さ れるのがわかった!では APIでは?」 などなど具体的な話も書きました。
ありがとうございました!