WRY

Where Are You?
You are on the brave land,
To experience, to remember...

0%

Timezone Interval Calculate

Problem Description

Given a time T_utc represented in UTC and the time zone TZ in which it actually resides, calculate the start and end times of the week and month in which it falls.

Solve

  1. Convert T_utc to the corresponding local time in the time zone TZ.
  2. Determine the start and end times of the month/week based on the local time.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import pytz
import calendar
from datetime import datetime, timedelta


class IntervalCalc:

@staticmethod
def calc_start_of_month(t_utc: datetime, tz: str) -> datetime:
t_local = t_utc.astimezone(pytz.timezone(tz))
return t_local.replace(day=1, hour=0, minute=0, second=0, microsecond=0)

@staticmethod
def calc_end_of_month(t_utc: datetime, tz: str) -> datetime:
t_local = t_utc.astimezone(pytz.timezone(tz))
_, days_in_month = calendar.monthrange(t_local.year, t_local.month)
return t_local.replace(day=days_in_month, hour=23, minute=59, second=59, microsecond=999999)

@staticmethod
def calc_start_of_week(t_utc: datetime, tz: str):
t_local = t_utc.astimezone(pytz.timezone(tz))
# weekday(): Monday: 0, Sunday is 6.
delta = (t_local.weekday() + 1) % 7
start_of_week = t_local - timedelta(days=delta)
return start_of_week.replace(hour=0, minute=0, second=0, microsecond=0)

@staticmethod
def calc_end_of_week(t_utc: datetime, tz: str):
return (IntervalCalc.calc_start_of_week(t_utc, tz) + timedelta(days=6)).replace(hour=23, minute=59, second=59, microsecond=999999)

@staticmethod
def calc_start_of_day(t_utc: datetime, tz: str):
t_local = t_utc.astimezone(pytz.timezone(tz))
return t_local.replace(hour=0, minute=0, second=0, microsecond=0)

@staticmethod
def calc_end_of_day(t_utc: datetime, tz: str):
t_local = t_utc.astimezone(pytz.timezone(tz))
return t_local.replace(hour=23, minute=59, second=59, microsecond=999999)

if __name__ == "__main__":
dt = datetime(2023, 4, 30, 23, 1, tzinfo=pytz.UTC)
print(f"dt: {dt}")
print(f"calc_start_of_month: {IntervalCalc.calc_start_of_month(dt, 'Asia/Shanghai')}")
print(f"calc_end_of_month: {IntervalCalc.calc_end_of_month(dt, 'Asia/Shanghai')}")
print(f"calc_start_of_week: {IntervalCalc.calc_start_of_week(dt, 'Asia/Shanghai')}")
print(f"calc_end_of_week: {IntervalCalc.calc_end_of_week(dt, 'Asia/Shanghai')}")
print(f"calc_start_of_day: {IntervalCalc.calc_start_of_day(dt, 'Asia/Shanghai')}")
print(f"calc_end_of_day: {IntervalCalc.calc_end_of_day(dt, 'Asia/Shanghai')}")

1
2
3
4
5
6
7
dt: 2023-04-30 23:01:00+00:00
calc_start_of_month: 2023-05-01 00:00:00+08:00
calc_end_of_month: 2023-05-31 23:59:59.999999+08:00
calc_start_of_week: 2023-04-30 00:00:00+08:00
calc_end_of_week: 2023-05-06 23:59:59.999999+08:00
calc_start_of_day: 2023-05-01 00:00:00+08:00
calc_end_of_day: 2023-05-01 23:59:59.999999+08:00