Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Djangoでタイムゾーンとうまく付き合う
Search
mizzsugar
November 13, 2019
Programming
840
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
140
Colabのみで初心者向けPythonハンズオン.pdf
mizzsugar
0
100
厳しさとゆるさの間で迷う人に捧げる個人開発記
mizzsugar
0
78
SQLModel入門〜クエリと型〜
mizzsugar
3
1.7k
フルリモート向いてないと思っていた私が、なんだかんだ健やかに 1年半フルリモート出来ている話
mizzsugar
1
170
Djangoでのプロジェクトだって型ヒントを運用出来る!
mizzsugar
4
9.2k
「動くものは作れる」の一歩先へ 〜「自走プログラマー」の紹介〜
mizzsugar
0
670
pytestの第一歩 〜「テスト駆動Python」の紹介〜
mizzsugar
3
500
データ分析ツール開発でpoetryを使う選択肢
mizzsugar
1
1.2k
Other Decks in Programming
See All in Programming
Distance field of Julia set
kinakomoti321
0
150
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
3
1.4k
AI駆動開発4年目の現在地(『あなたはFDEになるべきか?』イベント資料)
kumaiu
0
130
LLM 101
dalinaum
0
470
Seven New Principles of Software Engineering
yegor256
0
440
[DroidKnights 2026] Workflow AX: From Auto-Documented Policies to E2E Testing
raeminkang
0
520
TS 7.0 で baseUrl が使えなくなった今、パスエイリアスをどうするか
bicstone
2
500
AI-Powered Domain-Driven Design
ziobrando
0
390
Web3Dライブラリを作ってVue Custom Rendererの仕組みを理解しよう / lets learn vue custom renderer by making 3d library
drumath2237
1
120
JIS keyboard support in Omarchy
lef237
0
180
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
230
Goコンパイラを作ってGoをもっと理解する / Build a Go compiler to better understand Go
ikura_hamu
0
120
Featured
See All Featured
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
121
120k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
580
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
560
Believing is Seeing
oripsolob
1
270
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.6k
Ruling the World: When Life Gets Gamed
codingconduct
0
430
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
43k
Fantastic passwords and where to find them - at NoRuKo
philnash
53
4k
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では?」 などなど具体的な話も書きました。
ありがとうございました!