一、概述
在帆软开发过程中,经常会遇到需要格式化处理日期或传参的需求或场景,本文总结了帆软提供的时间与日期处理函数的一些实用技巧。
二、技术调研
2.1 帆软官方文档
日期和时间函数概述:官方文档链接
2.2 常用的日期与时间函数【含辅助函数】
TODAY():获取当前日期。示例:如果系统日期是2005年9月10日则TODAY()等于2005-09-10。
DATEDELTA(date,deltadays):返回一个日期date后deltadays的日期。deltaDays可以为正值,负值,零。
示例:
DATEDELTA("2008-08-08",-10)等于2008-07-29。
DATEDELTA("2008-08-08",10)等于2008-08-18。
DATEINMONTH(date,number):函数返回在某一个月当中第几天的日期。
示例:
DATEINMONTH("2008-08-08",20)等于2008-08-20。
DATEINMONTH("2008-08-08",-1)等于2008-08-31。
DATEINWEEK(date,number):函数返回在某一个星期当中第几天的日期。
示例:
dateInWeek("2008-08-28",2)等于2008-08-26。
dateInWeek("2008-08-28",-1)等于2008-08-31。如果最后一个参数为-1,返回该日期所在星期的最后一天。
ENDOFMONTH(date,number)返回指定日期所在月份之前或之后月份的最后一天的日期值
date:指定日期,可缺省;缺省时默认为本月;
number:指定月份前/后月份的数量,整数,可缺省;缺省或者为0时,默认为date参数当月;正整数时,为date之后的月份,负整数时为date之前的月份;
备注:
不支持第一个参数缺省时第二个参数不缺省
示例:
ENDOFMONTH("2021-12-22")等于2021-12-31
ENDOFMONTH("2021-12-22",12)等于2022-12-31
ENDOFMONTH("2021-12-22",-12)等于2020-12-31
ENDOFMONTH("2021-12-22",36)等于2024-12-31
MONTH:(serial_number)返回日期中的月。月是介于1和12之间的一个数。
Serial_number:含有所求的月的日期.
备注:
FineReport将日期保存为系列数,一个系列数代表一个与之匹配的日期,以方便用户对日期进行数值式计算。
在1900年日期系统中,FineReport电子表格将1900年1月1日保存为系列数2,将1900年1月2日保存为系列数3,将1900年1月3日保存为系列数4……依此类推。如在1900年日期系统,1998年1月1日存为系列数35796。
示例:
MONTH("2000/1/1")等于1。
MONTH("2006/05/05")等于5。
MONTH("1997/04/20")等于4。
MONTH("2000-1-1","yyyy-MM-dd")等于1。
MONTH("2006-05-05","yyyy-MM-dd")等于5。
MONTH("1997-04-20","yyyy-MM-dd")等于4。
MONTH(35796)等于1。
MONTHDELTA(date,delta):返回指定日期date后delta个月的日期。
示例:
MONTHDELTA("2008-08-08",4)等于2008-12-08。
YEARDELTA(date,delta):返回指定日期后delta年的日期。
示例:YEARDELTA("2008-10-10",10)等于2018-10-10。
LEFT(text,num_chars):根据指定的字符数返回文本串中的第一个或前几个字符。
Text:包含需要选取字符的文本串或单元格引用。
Num_chars:指定返回的字符串长度。
备注:
Num_chars的值必须等于或大于0。如果num_chars大于整个文本的长度,LEFT函数将返回所有的文本。如果省略num_chars,则默认值为1。
示例:
LEFT("Fine software",8)等于“Fine sof”。
LEFT("Finesoftware")等于“F”。
如果单元格A3中含有“China”,则LEFT(A3,2)等于“Ch”。
STARTWITH(str1,str2):判断字符串str1是否以str2开始。
备注:
str1和str2都是大小写敏感的。
示例:
STARTWITH("FineReport","Fine")等于true。
STARTWITH("FineReport","Report")等于false。
STARTWITH("FineReport","fine")等于false。
SPLIT(String1,String2):返回由String2分割String1组成的字符串数组。
String1:以双引号表示的字符串。
String2:以双引号表示的分隔符。例如逗号","
示例:
SPLIT("hello,world,yes",",")=["hello","world","yes"]。
SPLIT("this is very good"," ") = ["this","is","very","good"]。
备注:
如果只有一个参数,则返回一个错误。如果有多个参数,则只有前两个起作用。
三、解决方案
3.1 常见的日期格式
注:将【-】替换成【/】等分隔符,公式使用方式基本相同,本文统一以【-】作列举。
YYYY-MM-DD:2024-11-25
YYYY-MM:2024-11
MM-DD:11-25
【MM-DD至MM-DD】:11-25至11-30
TT时:11时
TT:mm -> TT:mm:8:00 - 10:00
当日某时、当天两小时、当日、昨日、本周、上周、过去7天、周度、本月、上月、月度
3.2 常见的下钻动态传参格式化
注1:参数$$$动态改变,数据通常来自于图表组件的坐标轴。
注2:
本文中业务约定日期格式如下:
日: MM-DD
周: MM-DD至MM-DD
月: YYYY-MM
**将$$$分解为stime与etime并向下钻页面传递参数,日期格式化函数总结如下:**
1.时/当天两小时/当日
stime/etime: today()
2.日度 [MM-DD]->[YYYY-MM-DD]
stime/etime: left(today(),5)+$$$
3.昨日
stime/etime: DATEDELTA((left(today(),5)+$$$),-1)
4.过去7天 [考虑跨年] [含当日]
stime: DATEDELTA((left(today(),5)+$$$),-6)
etime: today()
5.本周/周度/上周 [参数形式为:MM-DD至MM-DD] [区间跨度为一周7天] [考虑跨年]
stime:
1.基于$$$拼接
if((STARTWITH($$$,"12") && MONTH(today()) = 1),(year(today())-1)+'-'+left($$$,5),left(today(),5)+left($$$,5))
2.基于etime做减法
DATEDELTA(left(today(),5)+right($$$,5),-6)
etime: left(today(),5)+right($$$,5)
6.月度 [参数形式为:YYYY-MM]
stime: $$$+'-01'
etime: ENDOFMONTH($$$+'-01')
补充:从当日判断的常见日期范围
1. 当日: today()
2. 昨日: DATEDELTA(today(),-1)
3. 过去7天: DATEDELTA(today(),-6)
4. 本周:
[周一] DATEINWEEK(today(),1)
[周日] DATEINWEEK(today(),-1)
5. 上周:
[周一] DATEINWEEK(DATEDELTA(today(),-6),1)
[周日] DATEINWEEK(DATEDELTA(today(),-6),-1)
6.本月
[月初] DATEINMONTH(today(),1)
[月末] DATEINMONTH(today(),-1)
7.上月
[月初] MONTHDELTA(DATEINMONTH(today(),1),-1)
[月末] MONTHDELTA(DATEINMONTH(today(),-1),-1)
3.3 页面日期参数传递方式与交互逻辑
// 使用JS传参【日度:MM-DD、周度:MM-DD至MM-DD、月度:YYYY-MM】
// 可能的入参:日度[08-01]/周度[08-01至08-08]/月度[2024-08]
var flag = 0 // 判定标签
if(date.length<6) {
flag = 1 // 日度
} else if (date.length<10) {
flag = 3 // 月度
} else {
flag = 2 // 周度
}
// 获取当前时间
var nowISO = new Date().toISOString()
// 获取当前年份
var currentYear = nowISO.split('-')[0]
// 获取当前月份
var currentMonth = nowISO.split('-')[1]
switch (flag) {
case 1:
// 日度处理方式
if (currentMonth < date.split('-')[0] && date.split('-')[0] == 12) {
// 跨年判断
currentYear = currentYear - 1
}
var value = currentYear + '-' + date
var startDate = value
var endDate = value
break;
case 2:
// 周度处理方式
var dates = date.split('至')
// 跨年处理
if ((dates[0].split('-')[0] > dates[1].split('-')[0]) && dates[0].split('-')[0] == 12) {
var startDate = (currentYear - 1) + '-' + dates[0]
var endDate = currentYear + '-' + dates[1]
} else {
var startDate = currentYear + '-' + dates[0]
var endDate = currentYear + '-' + dates[1]
}
break;
case 3:
// 月度处理方式
const big = ['01','03','05','07','08','10','12']
// const small = [4,6,9,11]
var year = date.split('-')[0]
if ((year % 4 == 0 && year % 100 != 0) || year % 400 ==0) {
var FebDays = '29'
} else {
var FebDays = '28'
}
var month = date.split('-')[1]
if (month == 2) { // 2月
var startDate = date + '-' + '01'
var endDate = date + '-' + FebDays
} else if (big.includes(month)) { // 大月
var startDate = date + '-' + '01'
var endDate = date + '-' + '31'
} else { // 小月
var startDate = date + '-' + '01'
var endDate = date + '-' + '30'
}
break;
}
注:使用公式传参,参考上文公式,根据需求使用。
四、总结
本文总结了帆软提供的时间与日期处理函数的一些实用技巧,总结了一些页面参数传递方式与交互逻辑以供开发人员参考。