网站首页 / 育儿 / 正文

C语言日历代码(日历代码实现)

时间:2022-04-13 22:05:07 浏览:7628次 作者:用户投稿 【我要投诉/侵权/举报 删除信息】

多条告白如次剧本只需引入一次

前天咱们经过一段代码展现了怎样经过Python的Pandas包天生一个日历表,即使诸位感爱好不妨参考:经过Pandas天生日历表;

不得不说在 DB Engine(https://db-engines.com/en/ranking)排行榜中,PostgreSQL迩来几年从来都很宁静,而且在各个云平台中都有特殊老练的PaaS产物供各个企业运用,那么咱们即日的目的即是演练一下怎样经过#postgresql#来天生一致的日历表。

正文运用的PostgreSQL本子为14.1,Windows Server 2016情况下运转。

DB Engine Ranking

少许要害的功效

GENERATE_SERIES

在实行处置计划之前,咱们先领会PostgreSQL的一个因变量:“GENERATE_SERIES”,经过字面道理该当能大概猜出来,这个因变量不妨天生一个序列的数据,直白讲即是天生单列的一个数据表。

咱们先经过psql吩咐获得对于此因变量的刻画,如次图所示:

GENERATE_SERIES Description in psql

此因变量重要有几个特性:

不妨归来整型(bigint,int),浮点典型(numeric)序列;不妨归来带时区的功夫戳典型(timestamp)序列;不妨归来不带时区的功夫戳典型(timestamp)序列;大略举个例子:

1.1 归来整型序列

当指定开始,尽头参数SELECT GENERATE_SERIES(1, 10);截止如次所示:

归来整型序列

当指定开始,尽头,步长参数步长不妨领会为腾跃值,从1发端,即使步长为2,那么下一个数字该当是1 + 2 = 3,以该类推;

SELECT GENERATE_SERIES(1, 10, 2);归来整型序列,指定步长

1.2 归来浮点典型序列

此功效一致于归来整型序列,各别点是传入的不妨是带少量位的浮点典型数据,如次图所示:

SELECT GENERATE_SERIES(1.1, 10.9, 0.5);归来浮点典型序列,指定步长

1.3 归来功夫戳(timestamp)序列

此功效不妨经过指定开始,尽头和步长征三号个参数,归来一段功夫戳的序列数据,如次图所示:

SELECT GENERATE_SERIES('2022-01-01'::TIMESTAMP, '2022-01-31'::TIMESTAMP, '1 DAY') AS datum;归来功夫戳序列

须要提防的是:

必需同声指定三个参数,开始,尽头,步长;开始和尽头参数,必需是功夫戳典型(timestamp),即使传入的是日子典型,须要表露变换;步长不妨是钟点,秒钟,秒,天,礼拜,年等;日子典型数据操纵

咱们须要记取这一个操纵:日子 + 平头 = 日子,如底下例子所示:

date + integer → dateAdd a number of days to a datedate '2022-01-09' + 5 → 2022-01-14Case 1: 当月计划

Case 2: 跨月计划

底下咱们贯串GENERATE_SERIES 因变量实行怎样获得一个日子典型的序列;

开始:2022-01-01, 尽头:2022-01-31;这两个功夫点中央间隙了30天,经过代码实行如次:

SELECT '2022-01-01'::DATE + s.a AS datumFROM GENERATE_SERIES(0, 30) AS s(a);截止如次图所示:

经过GENERATE_SERIES因变量归来日子典型序列

这种计划的上风是:

归来日子典型序列,原因变量仅扶助传时髦间戳典型数据;不须要按日子功夫的Interval指定功夫间隙,将功夫间隙默许为1天。自设置因变量

经过上头的熟习,咱们仍旧不妨经过传入发端日子和间隙天数获得咱们想要的截止。然而即使交易上常常变幻发端日子和功夫间隙,咱们还须要连接的重写SQL语句。为了制止从新改写SQL语句,咱们将设置一个因变量“get_calendar”,并将“发端日子”(start_dt)和“功夫间隙”(days)做为参数字传送入,进而使咱们的截止和语句越发精巧。

代码如次所示:

CREATE OR REPLACE FUNCTION public.get_calendar(start_dt date,days integer) RETURNS TABLE(datum date) LANGUAGE 'sql'AS $BODY$SELECT start_dt + s.a AS datumFROM GENERATE_SERIES(0, days) AS s(a)GROUP BY s.aORDER BY 1;$BODY$;大略尝试一下,仍旧将‘2022-01-01’动作发端日子,功夫间隙树立为30天:

SELECT * FROM get_calendar('2022-01-01', 30);自设置因变量让代码越发精巧

完备代码实行

最后,咱们将经过PostgreSQL的洪量日子和字符串变换因变量,扩充咱们的自设置因变量“get_calendar”,获得一个完备的日历表,简直代码如次所示。

/* Author: Derek ZhuDate: 2022-01-08Purpose: Calendar table practice in PostgreSQL 14.1Description: Start date: 2022-01-01 Set days length in 2nd argument of 'Genarate_series' function */-- FUNCTION: public.get_calendar(date, integer)-- DROP FUNCTION IF EXISTS public.get_calendar(date, integer);CREATE OR REPLACE FUNCTION public.get_calendar(start_dt date,days integer) RETURNS TABLE(datum date, year numeric, month numeric, day_of_month numeric, week_of_year numeric, iso_day_of_week numeric, year_calendar_week text, day_of_year numeric, quarter_of_year numeric, quartal text, year_quartal text, day_name text, month_name text, year_month text, year_half integer, leap_year boolean, weekend text, cw_start date, cw_end date, month_start date, month_end date) LANGUAGE 'sql' COST 100 VOLATILE PARALLEL UNSAFE ROWS 1000AS $BODY$SELECT datum, EXTRACT(YEAR FROM datum) AS "year", EXTRACT(MONTH FROM datum) AS "month", EXTRACT(DAY FROM datum) AS day_of_month, EXTRACT(WEEK FROM datum) AS week_of_year, -- ISO 8601 day of the week numbering, The day of the week as Monday (1) to Sunday (7) EXTRACT(ISODOW FROM datum) AS iso_day_of_week, -- Standard Gregorian day of the week numbering, The day of the week as Sunday (0) to Saturday (6) -- EXTRACT(DOW FROM datum) AS day_of_week, -- ISO calendar year and week TO_CHAR(datum, 'iyyy/IW') AS year_calendar_week, EXTRACT(DOY FROM datum) AS day_of_year, EXTRACT(QUARTER FROM datum) AS quarter_of_year, 'Q' || TO_CHAR(datum, 'Q') AS quartal, TO_CHAR(datum, 'yyyy/"Q"Q') AS year_quartal, TO_CHAR(datum, 'TMDay') AS day_name, TO_CHAR(datum, 'TMMonth') AS month_name, TO_CHAR(datum, 'yyyy/mm') AS year_month, -- Half year CASE WHEN EXTRACT(MONTH FROM datum) < 7 THEN 1 ELSE 2 END AS year_half, -- Leap year CASE WHEN EXTRACT(YEAR FROM datum) % 4 = 0 THEN TRUE ELSE FALSE END AS leap_year, -- Weekend CASE WHEN EXTRACT(ISODOW FROM datum) in (6, 7) THEN 'Weekend' ELSE 'Weekday' END AS weekend, -- ISO start and end of the week of this date datum + (1 - EXTRACT(ISODOW FROM datum))::integer AS cw_start, datum + (7 - EXTRACT(ISODOW FROM datum))::integer AS cw_end, -- Start and end of the month of this date datum + (1 - EXTRACT(DAY FROM datum))::integer AS month_start, ((datum + (1 - EXTRACT(DAY FROM datum))::integer + '1 month'::interval)::date - '1 day'::interval)::DATE AS month_endFROM (SELECT start_dt + s.a AS datumFROM GENERATE_SERIES(0, days) AS s(a)GROUP BY s.a) AS calendarORDER BY 1;$BODY$;ALTER FUNCTION public.get_calendar(date, integer) OWNER TO postgres;获得2022年终年日历,如次所示:

SELECT * FROM get_calendar('2022-01-01', 364);2022 Calendar Table

经过文本编纂器查看截止,如次所示:

Calendar data in csv

经过Excel查看截止,如次所示:

Calendar data in excel

至此,咱们仍旧实行了一切功效;

归纳

经过PostgreSQL天生日历表重要有底下几个提防点:

ISO8601规范中,一个礼拜的天数为:Monday (1) ~ Sunday (7);领会并精巧运用GENERATE_SERIES因变量天生日子序列;养成模块化思想风气,将通用的数据操纵笼统为因变量或本领,不妨扩充运用范畴;与前天经过Python Pandas的案例一律,咱们最后也将处置计划?

版权声明:
本文内容由互联网用户自发贡献,该文观点仅代表作者本人,因此内容不代表本站观点、本站不对文章中的任何观点负责,内容版权归原作者所有、内容只用于提供信息阅读,无任何商业用途。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站(文章、内容、图片、音频、视频)有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至353049283@qq.com举报,一经查实,本站将立刻删除、维护您的正当权益。