GP
do $$
declare
--指定日期
p_date date := to_date('20221028','yyyymmdd');
--指定日期所在月的天数
days int := cast(to_char(to_date(to_char(p_date + interval '1 month','yyyymm')||'01','yyyymmdd') - 1,'dd') as int);
--指定月1号星期几
p_week int := cast(extract (dow from to_date(to_char(p_date,'yyyymm')||'01','yyyymmdd')) as int);
--指定年月
p_year_month varchar(10) := to_char(p_date,'yyyy-mm');
--指定日期
p_day varchar(2) := to_char(p_date,'dd');
sun int := case when p_week <> 0 then null else 1 end; --星期日
mon int := case when p_week <> 1 then sun + 1 else 1 end; --星期一
tue int := case when p_week <> 2 then mon + 1 else 1 end; --星期二
wed int := case when p_week <> 3 then tue + 1 else 1 end; --星期三
thu int := case when p_week <> 4 then wed + 1 else 1 end; --星期四
fri int := case when p_week <> 5 then thu + 1 else 1 end; --星期五
sat int := case when p_week <> 6 then fri + 1 else 1 end; --星期六
sun_v varchar(2); --星期日
mon_v varchar(2); --星期一
tue_v varchar(2); --星期二
wed_v varchar(2); --星期三
thu_v varchar(2); --星期四
fri_v varchar(2); --星期五
sat_v varchar(2); --星期六
begin
--输出月份
raise notice '%:',p_year_month;
--输出头部星期
raise notice '日 一 二 三 四 五 六';
--循环输出
while (sun < days or mon < days or tue < days or wed < days or thu < days or fri < days or sat < days)
loop
sun_v := coalesce (cast(sun as varchar(2)),'');
mon_v := coalesce (cast(mon as varchar(2)),'');
tue_v := coalesce (cast(tue as varchar(2)),'');
wed_v := coalesce (cast(wed as varchar(2)),'');
thu_v := coalesce (cast(thu as varchar(2)),'');
fri_v := coalesce (cast(fri as varchar(2)),'');
sat_v := coalesce (cast(sat as varchar(2)),'');
--初始化第一排
raise notice '% % % % % % %',sun_v||decode(sun_v,p_day,'*',''),mon_v||decode(mon_v,p_day,'*',''),tue_v||decode(tue_v,p_day,'*',''),wed_v||decode(wed_v,p_day,'*',''),thu_v||decode(thu_v,p_day,'*',''),fri_v||decode(fri_v,p_day,'*',''),sat_v||decode(sat_v,p_day,'*','');
sun := case when sat + 1 <= days then sat + 1 end;
mon := case when sun + 1 <= days then sun + 1 end;
tue := case when mon + 1 <= days then mon + 1 end;
wed := case when tue + 1 <= days then tue + 1 end;
thu := case when wed + 1 <= days then wed + 1 end;
fri := case when thu + 1 <= days then thu + 1 end;
sat := case when fri + 1 <= days then fri + 1 end;
end loop;
end$$;
Oracle
DECLARE
--指定日期
p_date DATE;
--指定日期所在月的天数
days INTEGER;
--指定月1号星期几
p_week INTEGER;
--指定年月
p_year_month varchar2(7);
--指定日期
p_day VARCHAR2(2);
sun INTEGER; --星期日
mon INTEGER; --星期一
tue INTEGER; --星期二
wed INTEGER; --星期三
thu INTEGER; --星期四
fri INTEGER; --星期五
sat INTEGER; --星期六
BEGIN
--指定日期
p_date := to_date('20221028','yyyymmdd');
--指定日期所在月的天数
days := to_number(to_char(to_date(to_char(add_months(p_date,1),'yyyymm') || '01','yyyymmdd') - 1,'dd'));
--指定月1号星期几
p_week := CASE to_char(to_date(to_char(p_date,'yyyymm')||'01','yyyymmdd'),'dy') WHEN 'sun' THEN '0' WHEN 'mon' THEN '1' WHEN 'tue' THEN '2' WHEN 'wed' THEN '3' WHEN 'thu' THEN '4' WHEN 'fri' THEN '5' WHEN 'sat' THEN '6' END;
--指定年月
p_year_month := to_char(p_date,'yyyy-mm');
--指定日期
p_day := to_char(p_date,'dd');
sun := CASE WHEN p_week <> 0 THEN NULL ELSE 1 END; --星期日
mon := CASE WHEN p_week <> 1 THEN sun + 1 ELSE 1 END; --星期一
tue := CASE WHEN p_week <> 2 THEN mon + 1 ELSE 1 END; --星期二
wed := CASE WHEN p_week <> 3 THEN tue + 1 ELSE 1 END; --星期三
thu := CASE WHEN p_week <> 4 THEN wed + 1 ELSE 1 END; --星期四
fri := CASE WHEN p_week <> 5 THEN thu + 1 ELSE 1 END; --星期五
sat := CASE WHEN p_week <> 6 THEN fri + 1 ELSE 1 END; --星期六
--输出月份
dbms_output.put_line(p_year_month||':');
--输出头部星期
dbms_output.put_line('日'||chr(9)||'一'||chr(9)||'二'||chr(9)||'三'||chr(9)||'四'||chr(9)||'五'||chr(9)||'六');
--循环输出
WHILE (sun < days OR mon < days OR tue < days OR wed < days OR thu < days OR fri < days OR sat < days)
LOOP
--初始化第一排
dbms_output.put_line(sun||CASE sun WHEN p_day THEN '*' END||chr(9)||mon||CASE mon WHEN p_day THEN '*' END||chr(9)||tue||CASE tue WHEN p_day THEN '*' END||chr(9)||wed||CASE wed WHEN p_day THEN '*' END||chr(9)||thu||CASE thu WHEN p_day THEN '*' END||chr(9)||fri||CASE fri WHEN p_day THEN '*' END||chr(9)||sat||CASE sat WHEN p_day THEN '*' END);
sun := CASE WHEN sat + 1 <= days THEN sat + 1 END;
mon := CASE WHEN sun + 1 <= days THEN sun + 1 END;
tue := CASE WHEN mon + 1 <= days THEN mon + 1 END;
wed := CASE WHEN tue + 1 <= days THEN tue + 1 END;
thu := CASE WHEN wed + 1 <= days THEN wed + 1 END;
fri := CASE WHEN thu + 1 <= days THEN thu + 1 END;
sat := CASE WHEN fri + 1 <= days THEN fri + 1 END;
END LOOP;
END;
注意:在dbeaver中,声明段中出现 end; 会出现错误,在plsql中正常。
Java
package com.yuzhenc;
import java.sql.Date;
import java.util.Calendar;
/**
* @author: yuzhenc
* @date: 2022-01-08 16:17:59
* @desc: com.yuzhenc
* @version: 1.0
*/
public class PrintDate {
public static void main(String[] args) {
//给定date字符串
String strDate = "2022-10-28";
//实例化一个Date
Date date = Date.valueOf(strDate);
//Date转为Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
//月份
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1; //从0开始,所以+1
System.out.println(year + "-" + month + ":");
//星期提示
System.out.println("日\t一\t二\t三\t四\t五\t六\t");
//获取本月的最大天数
int maxDay = cal.getActualMaximum(Calendar.DATE);
//获取当前日期中的日
int nowday = cal.get(Calendar.DATE);
//将日期调为本月1号
cal.set(Calendar.DATE,1);
//获取1号是本周的第几天
int num = cal.get(Calendar.DAY_OF_WEEK);
//计数器
int count = 0;
//输出空格
for (int i = 1; i < num; i++) {
System.out.print("\t");
}
count = count + num;
//从1号到maxDay号进行遍历
for (int i = 1; i <= maxDay; i++) {
if (i == nowday) {
System.out.print(i+"*"+"\t");
} else {
System.out.print(i+"\t");
}
if (count%7 == 0) {
System.out.println();
}
count ++;
}
}
}