/* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is comprised of the ADF directory The Initial Developer of the Original Code is PaperThin, Inc. Copyright (c) 2009-2025. All Rights Reserved. By downloading, modifying, distributing, using and/or accessing any files in this directory, you agree to the terms and conditions of the applicable end user license agreement. */ /* *************************************************************** Author: PaperThin, Inc. Name: date_2_0.cfc Summary: Date Utils functions for the ADF Library Version: 2.0 History: 2015-08-31 - GAC - Created 2016-09-29 - GAC - Added functions to calculated the first and last days of the quarter 2020-12-16 - GAC - Added the countDown and countDownText functions */ component displayname="date_2_0" extends="date_1_2" hint="Date Utils functions for the ADF Library" { property name="version" value="2_0_2"; property name="type" value="singleton"; property name="wikiTitle" value="Date_2_0"; /* Author: PaperThin, Inc. Name: $firstDayOfQuarter Summary: Returns date for first day of the quarter for the provided month/year Returns: Date Arguments: Numeric - inMonth Numeric - inYear History: 2016-09-29 - GAC - Created 2017-01-27 - GAC - Updated inYear parameter issue */ public date function firstDayOfQuarter(required numeric inMonth, required numeric inYear) { var dateObj = createDate(arguments.inYear, arguments.inMonth, 1); return DateAdd("q", Quarter(dateObj)-1, '01-01-' & year(dateObj)); } /* Author: PaperThin, Inc. Name: $firstDayOfQuarterByDate Summary: Returns date for first day of the quarter from the provided date Returns: Date Arguments: Date - inDate History: 2016-09-29 - GAC - Created */ public date function firstDayOfQuarterByDate(date inDate='#Now()#') { return firstDayOfQuarter(inMonth=Month(arguments.inDate),inYear=Year(arguments.inDate)); } /* Author: PaperThin, Inc. Name: $lastDayOfQuarter Summary: Returns date for last day of the quarter for the provided month/year Returns: Date Arguments: Numeric - inMonth Numeric - inYear History: 2016-09-29 - GAC - Created */ public date function lastDayOfQuarter(required numeric inMonth, required numeric inYear) { var qtrStartDate = firstDayOfQuarter(inMonth=arguments.inMonth,inYear=arguments.inYear); return DateAdd("d",-1,DateAdd("m",3,qtrStartDate)); } /* Author: PaperThin, Inc. Name: $lastDayOfQuarterByDate Summary: Returns date for last day of the quarter from the provided date Returns: Date Arguments: Date - inDate History: 2016-09-29 - GAC - Created */ public date function lastDayOfQuarterByDate(date inDate='#Now()#') { return lastDayOfQuarter(inMonth=Month(arguments.inDate),inYear=Year(arguments.inDate)); } /* Author: PaperThin, Inc. Name: $epochTimeToLocalDate Summary: Returns datetime for provided Epoch Time (number of seconds since Jan 01 1970) Returns: Date Arguments: epoch - date in seconds History: 2016-09-29 - GAC - Created */ public date function EpochTimeToLocalDate(epoch) { return DateAdd("s",arguments.epoch,DateConvert("utc2Local", "January 1 1970 00:00")); } /* countDown(dateTime) * Counts down to a date. * * @param dateTime Date to count down to. (Required) * @return Returns a structure. * @author Nathan Dintenfass (nathan@changemedia.com) * @version 1, October 11, 2002 2020/12/16 - Added Updated to break into 2 functions Updated this function to only return the data structure */ public struct function countDown(required date dateTime) { var retData = {}; var dateToUse = parseDateTime(arguments.dateTime); //grab now(), so we don't have to do it over and over var rightNow = now(); //a string used to return var returnString = ""; //var to hold the sum to determine if it has passed var sum = ""; //a var to tack on the beginning and end of string return var prefix = ""; var suffix = ""; //get the absolute difference in years, months, days, hours, minutes and seconds retData.years = dateDiff("yyyy",rightNow,dateToUse); retData.months = dateDiff("m",rightNow,dateToUse); retData.days = dateDiff("d",rightNow,dateToUse); retData.hours = dateDiff("h",rightNow,dateToUse); retData.minutes = dateDiff("n",rightNow,dateToUse); retData.seconds = dateDiff("s",rightNow,dateToUse) - (60*retData.minutes); //now go back through them in reverse order and delete off the appropriate units retData.minutes = retData.minutes - (60*retData.hours); retData.hours = retData.hours - (24*retData.days); retData.days = retData.days - dateDiff("d",dateAdd("m",-1*retData.months,dateToUse),dateToUse); retData.months = retData.months - (12*retData.years); return retData; } /* countDownText(dateTime,showTime) * Counts down to a date/time. * * @param dateTime Date to count down to. (Required) * @param showTime Display Hours,Minutes,Seconds after the Years,Months,Days * @return Returns a string * @author Nathan Dintenfass (nathan@changemedia.com) * @version 1, October 11, 2002 2020/12/16 - Added Updated to break into 2 functions Updated date string formatting */ public string function countDownText(required date dateTime, boolean showTime=true) { //a struct to hold the data for the countdown var countdownData = countDown(dateTime=arguments.dateTime); //a string used to return var returnString = ""; //var to hold the sum to determine if it has passed var sum = ""; //a var to tack on the beginning and end of string return var prefix = ""; var suffix = ""; //first, gather the sum, to know if it's future or past sum = countDownData.years + countdownData.months + countdownData.days + countdownData.hours + countdownData.minutes + countdownData.seconds; //if the sum is 0, it's right now! if( NOT sum ) return "Right Now!"; //if the sum is negative, it's in the past, so multiply -1 for display purposes if( sum LT 0 ) { countdownData.seconds = countdownData.seconds * -1; countdownData.minutes = countdownData.minutes * -1; countdownData.hours = countdownData.hours * -1; countdownData.days = countdownData.days * -1; countdownData.months = countdownData.months * -1; countdownData.years = countdownData.years * -1; //prefix = "passed "; suffix = " ago"; } //add the prefix returnString = returnString & prefix; // build the return string if( countDownData.years GT 0 ) { returnString = returnString & countdownData.years; if ( countDownData.years EQ 1 ) returnString = returnString & " year"; else returnString = returnString & " years"; } if( countdownData.months GTE 0 ) { if( LEN(TRIM(returnString)) ) returnString = returnString & ", "; returnString = returnString & countdownData.months; if ( countDownData.months EQ 1 ) returnString = returnString & " month"; else returnString = returnString & " months"; } if( countdownData.days GTE 0 ) { if( LEN(TRIM(returnString)) ) returnString = returnString & ", "; returnString = returnString & countdownData.days; if ( countDownData.days EQ 1 ) returnString = returnString & " day"; else returnString = returnString & " days"; } if( countdownData.hours GTE 0 AND arguments.showTime ) { if( LEN(TRIM(returnString)) ) returnString = returnString & ", "; returnString = returnString & countdownData.hours; if ( countDownData.hours EQ 1 ) returnString = returnString & " hour"; else returnString = returnString & " hours"; } if( countdownData.minutes GTE 0 AND arguments.showTime ) { if( LEN(TRIM(returnString)) ) returnString = returnString & ", "; returnString = returnString & countdownData.minutes; if ( countDownData.minutes EQ 1 ) returnString = returnString & " minute"; else returnString = returnString & " minutes"; } if( countdownData.seconds GTE 0 AND arguments.showTime ) { if( LEN(TRIM(returnString)) ) returnString = returnString & ", "; returnString = returnString & countdownData.seconds; if ( countDownData.seconds EQ 1 ) returnString = returnString & " second"; else returnString = returnString & " seconds"; } //add the suffix returnString = returnString & suffix; //return the string return returnString; } /* calcExecutionTime(startMS,endMS,mask); mask - string Use dd for days, hh for hours, mm for minutes, ss for seconds, lll for milliseconds padded with leading zeros Use d for days, h for hours, m for minutes, s for seconds, l for milliseconds Omit a mask unit to not display it and add its value to the next smallest unit. */ public string function calcExecutionTime(required numeric startMS, required numeric endMS, string mask='dd:hh:mm:ss.lll') { var retStr = '00:00:00:00.000'; var execMS = VAL(arguments.endMS-arguments.startMS); // var execMS = ( startTS GT endTS ) ? (startTS - endTS) : (endTS - startTS); var timeData = createTimeStruct(timespan=execMS); var maskStr = arguments.mask; var v = 0; var uList = 'd:24,h:60,m:60,s:60,l:1000'; var mList = 'dd,hh,mm,ss,lll'; //var mList = 'dd,d,hh,h,mm,m,ss,s,lll,ll,l'; var uListRnds = ListLen(uList)-1; for ( var r=1; r <= uListRnds; r++) { var unitGrp = ListGetAt(uList,r,','); var nextPos = r+1; var nextGrp = ListGetAt(uList,nextPos,','); var unit = ListFirst(unitGrp,':'); var multi = ListLast(unitGrp,':'); var next = ListFirst(nextGrp,':'); if ( FindNoCase(unit,maskStr) EQ 0 AND timeData[unit] GT 0 ) { if ( next EQ 'l' ) next = 'ms'; var combVal = timeData[unit] * VAL(multi); timeData[next] = timeData[next] + combVal; } } if ( NOT StructIsEmpty(timeData) ) { for ( var i=1; i <= ListLen(mList,','); i++) { var mItem = ListGetAt(mList,i,','); var key = LEFT(mItem,1); if ( key EQ 'l' ) key = 'ms'; if ( FindNoCase(mItem,maskStr) ) { if ( LEN(mItem) > 1 ) // AND key NEQ "d" { if ( key EQ 'ms' ) v = NumberFormat(timeData[key],'000'); else v = NumberFormat(timeData[key],'00'); } else v = NumberFormat(timeData[key],'0'); maskStr = replace(maskStr, mItem, v, "ONE"); } } retStr = maskStr; } return retStr; } /* public string function calcExecutionTime(required numeric startMS, required numeric endMS) { var retStr = '00:00:00:00.000'; var execMS = VAL(arguments.endMS-arguments.startMS); var timeData = createTimeStruct(timespan=execMS); if ( NOT StructIsEmpty(timeData) ) { // Break days back into Hours if ( timeData.d GT 0 ) { var dayHours = timeData.d * 24; timeData.h = timeData.h + dayHours; } retStr = NumberFormat(timeData.h,'00');; retStr = retStr & ":" & NumberFormat(timeData.m,'00'); retStr = retStr & ":" & NumberFormat(timeData.s,'00'); retStr = retStr & "." & NumberFormat(timeData.ms,'000'); } return retStr; }*/ /* calcExecutionTimeFromDates(startDT,endDT); mask - string Use dd for days, hh for hours, mm for minutes, ss for seconds, lll for milliseconds padded with leading zeros Use d for days, h for hours, m for minutes, s for seconds, l for milliseconds Omit a mask unit to not display it and add its value to the next smallest unit. */ public string function calcExecutionTimeFromDates(required date startDT, required date endDT, string mask='dd:hh:mm:ss.lll') { var retStr = '00:00:00:00.000'; var sDateTime = ParseDateTime(arguments.startDT); var eDateTime = ParseDateTime(arguments.endDT); var startTS = sDateTime.getTime(); var endTS = eDateTime.getTime(); var execMS = ( startDT GT endDT ) ? (startTS - endTS) : (endTS - startTS); var timeData = createTimeStruct(timespan=execMS); var maskStr = arguments.mask; var v = 0; var uList = 'd:24,h:60,m:60,s:60,l:1000'; var mList = 'dd,hh,mm,ss,lll'; //var mList = 'dd,d,hh,h,mm,m,ss,s,lll,ll,l'; var uListRnds = ListLen(uList)-1; for ( var r=1; r <= uListRnds; r++) { var unitGrp = ListGetAt(uList,r,','); var nextPos = r+1; var nextGrp = ListGetAt(uList,nextPos,','); var unit = ListFirst(unitGrp,':'); var multi = ListLast(unitGrp,':'); var next = ListFirst(nextGrp,':'); if ( FindNoCase(unit,maskStr) EQ 0 AND timeData[unit] GT 0 ) { if ( next EQ 'l' ) next = 'ms'; var combVal = timeData[unit] * VAL(multi); timeData[next] = timeData[next] + combVal; } } if ( NOT StructIsEmpty(timeData) ) { for ( var i=1; i <= ListLen(mList,','); i++) { var mItem = ListGetAt(mList,i,','); var key = LEFT(mItem,1); if ( key EQ 'l' ) key = 'ms'; if ( FindNoCase(mItem,maskStr) ) { if ( LEN(mItem) > 1 ) // AND key NEQ "d" { if ( key EQ 'ms' ) v = NumberFormat(timeData[key],'000'); else v = NumberFormat(timeData[key],'00'); } else v = NumberFormat(timeData[key],'0'); maskStr = replace(maskStr, mItem, v, "ONE"); } } retStr = maskStr; } return retStr; } /* public string function calcExecutionTimeFromDates(required date startDT, required date endDT) { var retStr = '00:00:00:00.000'; var startDT = ParseDateTime(arguments.startDT); var endDT = ParseDateTime(arguments.endDT); var startTS = startDT.getTime(); var endTS = endDT.getTime(); var execMS = ( startDT GT endDT ) ? (startTS - endTS) : (endTS - startTS); var timeData = createTimeStruct(timespan=execMS); if ( NOT StructIsEmpty(timeData) ) { // Break days back into Hours if ( timeData.d GT 0 ) { var dayHours = timeData.d * 24; timeData.h = timeData.h + dayHours; } retStr = NumberFormat(timeData.h,'00');; retStr = retStr & ":" & NumberFormat(timeData.m,'00'); retStr = retStr & ":" & NumberFormat(timeData.s,'00'); retStr = retStr & "." & NumberFormat(timeData.ms,'000'); } return retStr; }*/ /* createTimeStruct(timespan,mask) https://cflib.org/udf/CreateTimeStruct * Converts a given number of days, hours, minutes, OR seconds to a struct of days, hours, minutes, AND seconds. * * @param timespan The timespan to convert. * @param mask The the base time unit to use for the provided timespan value. * @return Returns a structure. * @author Dave Pomerance (dpomerance@mos.org) * @version 1, January 7, 2002 2023/01/19 - Added Updated to add milliseconds */ public struct function createTimeStruct(required numeric timespan,string mask="ms") { var retStruct = {}; // if timespan isn't an integer, convert mask towards s until timespan is an integer or mask is ms while ( INT(arguments.timespan) neq arguments.timespan AND arguments.mask neq "ms" ) { if (arguments.mask eq "d") { arguments.timespan = arguments.timespan * 24; arguments.mask = "h"; } else if (arguments.mask eq "h") { arguments.timespan = arguments.timespan * 60; arguments.mask = "m"; } else if (arguments.mask eq "m") { arguments.timespan = arguments.timespan * 60; arguments.mask = "s"; } else if (arguments.mask eq "s") { arguments.timespan = arguments.timespan * 60; arguments.mask = "ms"; } } // only 5 allowed values for mask - if not one of those, return blank struct if ( ListFind("d,h,m,s,ms", arguments.mask) ) { // compute seconds if (arguments.mask eq "ms") { retStruct.ms = (arguments.timespan mod 1000) + (arguments.timespan - Int(arguments.timespan)); arguments.timespan = int(arguments.timespan/1000); arguments.mask = "s"; } else retStruct.ms = 0; if (arguments.mask eq "s") { retStruct.s = (arguments.timespan mod 60) + (arguments.timespan - Int(arguments.timespan)); arguments.timespan = int(arguments.timespan/60); arguments.mask = "m"; } else retStruct.s = 0; // compute minutes if (mask eq "m") { retStruct.m = arguments.timespan mod 60; arguments.timespan = int(arguments.timespan/60); arguments.mask = "h"; } else retStruct.m = 0; // compute hours, days if (mask eq "h") { retStruct.h = arguments.timespan mod 24; retStruct.d = int(arguments.timespan/24); } else { retStruct.h = 0; retStruct.d = arguments.timespan; } } return retStruct; } }