前言
因为工作涉及一些国际化的业务,所以写代码时常常涉及一些时区转换。汇总了常用的代码,整理到一篇文章里。
代码
核心处理逻辑是:
- 用get_city_id_to_timezone_dict函数读取每个城市的时区;
- 不同时区的城市之间的时间转换,就通过计算这两个城市的时间差去推算即可。
def get_city_id_to_timezone_dict(date):
timezone = spark.sql("""
select distinct
city_id,
utc_offset_current
from
***
where
concat_ws('-',year,month,day) = '{}'""".format(date))
@udf(returnType=StringType())
def get_utc_timezone(x):
return 'UTC-0'+str(int(abs(int(x)/60)))+':00'
timezone = timezone.withColumn('utc_timezone', get_utc_timezone(F.col('utc_offset_current')))
timezone = timezone.dropna().toPandas()
cityid_timezone_dict = {}
for i in range(timezone.shape[0]):
key = timezone.iloc[i]['city_id']
val = timezone.iloc[i]['utc_timezone']
cityid_timezone_dict[key] = val
# cityid_timezone_dict是一个类似于{city_id: 'UTC-04:00'}的字典
return cityid_timezone_dict
# 北京时间转当地时间
# @udf(returnType=StringType())
def beijing2local(x, city_id, fmt="%Y-%m-%d %H"):
UTC_LC = cityid_timezone_dict[str(city_id)]
tz_LC = int(UTC_LC.split('UTC')[1].split(':')[0])
utc_diff = 8 - tz_LC
t = datetime.datetime.strptime(x, fmt)
lc = t - datetime.timedelta(hours = utc_diff)
ret = lc.strftime(fmt)
return ret
@udf(returnType=StringType())
def BJ2local(x, city_id, fmt="%Y-%m-%d %H:%M:%S"):
UTC_LC = cityid_timezone_dict[str(city_id)]
tz_LC = int(UTC_LC.split('UTC')[1].split(':')[0])
utc_diff = 8 - tz_LC
t = datetime.datetime.strptime(x, fmt)
lc = t - datetime.timedelta(hours = utc_diff)
ret = lc.strftime(fmt)
return ret
# 当地日期转北京时间
def local2beijing(from_dt, to_dt, city_id, fmt="%Y-%m-%d"):
UTC_LC = cityid_timezone_dict[str(city_id)]
tz_LC = int(UTC_LC.split('UTC')[1].split(':')[0])
utc_diff = 8 - tz_LC
from_bj = datetime.datetime.strptime(from_dt, fmt) + datetime.timedelta(hours = utc_diff)
from_bj = from_bj.strftime("%Y-%m-%d %H")
to_bj = datetime.datetime.strptime(to_dt, fmt) + datetime.timedelta(days = 1, hours = utc_diff-1)
to_bj = to_bj.strftime("%Y-%m-%d %H")
return from_bj, to_bj