Python

参考文献

  1. https://docs.python.org/ja/3/library/datetime.html
    • #strftime-strptime-behavior に strptime() の書式コードがある。
  2. https://docs.python.org/ja/3.8/library/stdtypes.html#typeiter

フィボナッチ数列を返すイテレータオブジェクト

イテレータオブジェクトの構成プロトコルは、イテレータオブジェクト自体を返す
__iter__()
と次のアイテムを返す
__next__()
とのことなので[2]、これらのメソッドを実装する。以下のイテレータオブジェクトは100に達するまでフィボナッチ数列を出力する。
class Fibonacci:
    def __iter__(self):
        print('===== __iter__() was just called. =====')
        self.a = 0
        self.b = 0
        return self
    def __next__(self):
        if self.b >= 100:
            raise StopIteration()
        if self.b == 0:
            c = 1
        elif self.a == 0:
            c = 1
        else:
            c = self.a + self.b
        self.a = self.b
        self.b = c
        return c

fi = Fibonacci()
for x in fi:
    print(x)
for x in fi:  # 2回目も可能.
    print(x)
===== __iter__() was just called. =====
1
1
2
3
5
8
13
21
34
55
89
144
===== __iter__() was just called. =====
1
1
2
3
5
8
13
21
34
55
89
144
いくつに達したら終わるかを毎回変更することもできる。
import random

class Fibonacci:
    def __iter__(self):
        print('===== __iter__() was just called. =====')
        self.a = 0
        self.b = 0
        self.threshold = random.choices([5, 10, 20, 30])[0]
        return self
    def __next__(self):
        if self.b >= self.threshold:
            raise StopIteration()
        if self.b == 0:
            c = 1
        elif self.a == 0:
            c = 1
        else:
            c = self.a + self.b
        self.a = self.b
        self.b = c
        return c

文字列を datetime 型に変換しユニックス秒に変換する

datetime.datetime.strptime() で datetime 型にできる。timestamp() メソッドでユニックス秒にできる。タイムゾーン情報をパースしないと datetime 型は自分のタイムゾーンについて無知になる。その場合でも timestamp() メソッドではシステムのタイムゾーンが適用される。タイムゾーン情報をパースさせれば datetime 型は自分のタイムゾーンを認識する。日本時間の1時より協定世界時の1時の方が未来である。
import datetime

s = '2022-03-13 01:23:45'
dt = datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S')  # naive
ts = dt.timestamp()  # ここでローカル時刻として UNIX 秒化される
print(dt, dt.tzinfo)
print(ts)
print(datetime.datetime.fromtimestamp(ts))

s = '2022-03-13 01:23:45+09:00'
dt = datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S%z')  # aware
ts = dt.timestamp()
print(dt, dt.tzinfo, dt.tzinfo.utcoffset(dt))
print(ts)
print(datetime.datetime.fromtimestamp(ts))

s = '2022-03-13 01:23:45+00:00'
dt = datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S%z')  # aware
ts = dt.timestamp()
print(dt, dt.tzinfo, dt.tzinfo.utcoffset(dt))
print(ts)
print(datetime.datetime.fromtimestamp(ts))
2022-03-13 01:23:45 None
1647102225.0
2022-03-13 01:23:45

2022-03-13 01:23:45+09:00 UTC+09:00 9:00:00
1647102225.0
2022-03-13 01:23:45

2022-03-13 01:23:45+00:00 UTC 0:00:00
1647134625.0
2022-03-13 10:23:45
上のコードに示しているように datetime.datetime.fromtimestamp() でユニックス秒から datetime 型を復元できるが、このとき明示的にタイムゾーンを指定しないと datetime 型は自分のタイムゾーンについて無知になる。
ts = 1647102225.0

dt = datetime.datetime.fromtimestamp(ts)
print(dt, dt.tzinfo)

dt = datetime.datetime.fromtimestamp(ts, datetime.timezone(datetime.timedelta(hours=9)))
print(dt, dt.tzinfo)

dt = datetime.datetime.fromtimestamp(ts, datetime.timezone(datetime.timedelta(hours=0)))
print(dt, dt.tzinfo)
2022-03-13 01:23:45 None

2022-03-13 01:23:45+09:00 UTC+09:00

2022-03-12 16:23:45+00:00 UTC