pyudf 计算自然周和当周周一

3 篇文章 1 订阅
1 篇文章 0 订阅

目标

业务统计需要按照自然周看数据,所以把每天计算都归到自然周。
展示的时候用自然周的周一来代替自然周展示。
odps 没有计算自然周的函数,所以用 Python 做了一个 udf 来实现。
一年的第一天是周一,那么这一年的自然周就是以01开始,否则是以00,
这个在计算对应的周一时会产生问题,针对跨年周做了兼容处理。
似乎 MySQL 在计算自然周的时候也有类似问题,这里没有细查。

代码

from odps.udf import annotate
import datetime

@annotate("string->string")
class get_year_week(object):
    def evaluate(self, arg):
        try :
            ds_date = datetime.datetime.strptime(arg, '%Y%m%d')
            yw = '{}'.format(ds_date.strftime("%Y%W"))
            if yw[-2:] == '00':
                ds_date = ds_date + datetime.timedelta(days=1 - ds_date.isoweekday())
            yw = '{}'.format(ds_date.strftime("%Y%W"))
            return yw
        except:
            return None


@annotate("string->string")
class get_year_week_day(object):
    def evaluate(self, yearsweek):
        iosweekday=1
        try :
            year = yearsweek[:4]
            # if 0101 is monday, the yearweek will begin on 01,need mines 1
            if datetime.datetime.strptime(year, '%Y').isoweekday() == 1:
                week_num = int(yearsweek[-2:]) - 1
            else:
                week_num = int(yearsweek[-2:])
            monday_of_the_week = datetime.datetime.strptime(year, '%Y') + datetime.timedelta(days=7 * week_num)
            # 
            if monday_of_the_week.isoweekday() != iosweekday:
                monday_of_the_week = monday_of_the_week + datetime.timedelta(days=iosweekday - monday_of_the_week.isoweekday())
            return monday_of_the_week.strftime('%Y%m%d')
        except:
            return None

效果

select date1,yearweek(date1),yearweekday(yearweek(date1)) monday
from date_list;
date1_c1monday
2018022120180820180219
2018123120185320181231
2019010120185320181231
2019010620185320181231
2019010720190120190107
2019010820190120190107
2019123120195220191230
2020010120195220191230
2020123120205220201228
2021010120205220201228
2021123120215220211227
2022010120215220211227
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值