Skip to content

Instantly share code, notes, and snippets.

@ExcelRobot
Last active July 2, 2023 16:47
Show Gist options
  • Save ExcelRobot/249f1d057152cf5243af894d2e0965a4 to your computer and use it in GitHub Desktop.
Save ExcelRobot/249f1d057152cf5243af894d2e0965a4 to your computer and use it in GitHub Desktop.
Humanize Seconds LAMBDA Function
/*
These lambdas were inspired by the work of Mike Wolfe's article "Displaying Human
Readable Time Spans" (https://nolongerset.com/displaying-time-spans/). He provided
the logic and I enjoyed the puzzle of converting that logic to dynamic arrays.
Included within:
* HUMANIZESECONDS - Converts seconds to human readable text
* PLURALIZE - Adapts wording based on whether number is singular/plural and
positive/negative.
* CONVERTTOSECONDS - Converts units of years, weeks, days, hours, minutes, and
seconds to total seconds.
*/
/*
Name: Humanize Seconds (HUMANIZESECONDS)
Description: Converts number of seconds to a human readable text broken down by years,
weeks, days, hours, minutes, and seconds.
Dependencies: PLURALIZE, CONVERTTOSECONDS
Author: Excel Robot (@ExcelRobot)
Inspired By: Mike Wolfe (https://nolongerset.com/displaying-time-spans/)
Category: Time
*/
HUMANIZESECONDS = LAMBDA(seconds,LET(
SecondsPerMinute, 60,
SecondsPerHour, SecondsPerMinute*60,
SecondsPerDay, SecondsPerHour*24,
SecondsPerWeek, SecondsPerDay*7,
SecondsPerYear, SecondsPerDay*365,
Years, INT(seconds/SecondsPerYear),
Weeks, LET(x,INT((seconds-Years*SecondsPerYear)/SecondsPerDay),IF(MOD(x,7)=0,x/7,0)),
Days, INT((seconds-Years*SecondsPerYear-Weeks*SecondsPerWeek)/SecondsPerDay),
Hours, INT((seconds-Years*SecondsPerYear-Weeks*SecondsPerWeek-Days*SecondsPerDay)/SecondsPerHour),
Minutes, INT((seconds-Years*SecondsPerYear-Weeks*SecondsPerWeek-Days*SecondsPerDay-Hours*SecondsPerHour)/SecondsPerMinute),
Secs, seconds-Years*SecondsPerYear-Weeks*SecondsPerWeek-Days*SecondsPerDay-Hours*SecondsPerHour-Minutes*SecondsPerMinute,
PluralWording, {"# year[s]";"# week[s]";"# day[s]";"# hour[s]";"# minute[s]";"# second[s]"},
Nums, CHOOSE(SEQUENCE(6),Years,Weeks,Days,Hours,Minutes,Secs),
Pluralized, MID(REDUCE("",SEQUENCE(ROWS(PluralWording)),LAMBDA(tot,x,tot&IF(INDEX(Nums,x,1)=0,"",", "&PLURALIZE(INDEX(PluralWording,x,1),INDEX(Nums,x,1))))),3,999),
Pluralized
));
/*
Name: Pluralize (PLURALIZE)
Description: Combines a number with a wording template string to adapt the wording to
whether the number is singular/plural and positive/negative. Text in brackets [s]
will only be shown if plural, unless a / is included to specify different text for
singular/plural [y/ies]. Text in braces is show based on number being positive/negative
{gain/loss}. If a num_token is not specified, # will be used. If a num_format is not
specified, general formatting will be used.
Author: Excel Robot (@ExcelRobot)
Inspired By: Mike Wolfe (https://nolongerset.com/displaying-time-spans/)
Category: Words
*/
PLURALIZE = LAMBDA(text,num,[num_token],[num_format],LET(
fnGetGroups, LAMBDA(txt,quoted_delimiter,LET(
chars, MID(txt,SEQUENCE(LEN(txt)),1),
seq, SEQUENCE(ROWS(FILTER(chars,chars=LEFT(quoted_delimiter)))),
start, FIND(CHAR(160),SUBSTITUTE(txt,LEFT(quoted_delimiter),CHAR(160),seq)),
chargroup, MID(txt,start,FIND(RIGHT(quoted_delimiter),txt,start)-start+1),
chargroup
)),
BracketGroups, fnGetGroups(text,"[]"),
BraceGroups, fnGetGroups(text, "{}"),
DividingSlash, "/",
IsPlural, ABS(num)<>1,
IsNegative, num<0,
fnGetReplacements, LAMBDA(groups,divider,use_secondary,LET(
finddivider, FIND(divider,groups),
nodivider, IF(use_secondary,MID(groups,2,LEN(groups)-2),""),
withdivider, IF(use_secondary,MID(groups,finddivider+1,LEN(groups)-finddivider-1),MID(groups,2,finddivider-2)),
replacement, IF(ISERROR(finddivider),nodivider,withdivider),
replacement
)),
BracketReplacements, fnGetReplacements(BracketGroups,DividingSlash,IsPlural),
BraceReplacements, fnGetReplacements(BraceGroups,DividingSlash,IsNegative),
ReplaceNumToken, SUBSTITUTE(text,IF(OR(ISOMITTED(num_token),num_token=""),"#",num_token),IF(OR(ISOMITTED(num_format),num_format=""),num,TEXT(num,num_format))),
ReplaceBracketGroups, IFERROR(REDUCE(ReplaceNumToken,SEQUENCE(ROWS(BracketGroups)),LAMBDA(tot,x,SUBSTITUTE(tot,INDEX(BracketGroups,x),INDEX(BracketReplacements,x)))),ReplaceNumToken),
ReplaceBraceGroups, IFERROR(REDUCE(ReplaceBracketGroups,SEQUENCE(ROWS(BraceGroups)),LAMBDA(tot,x,SUBSTITUTE(tot,INDEX(BraceGroups,x),INDEX(BraceReplacements,x)))),ReplaceBracketGroups),
ReplaceBraceGroups
));
/*
Name: Convert To Seconds (CONVERTTOSECONDS)
Description: Converts units of years, weeks, days, hours, minutes, and
seconds to total seconds.
Author: Excel Robot (@ExcelRobot)
Inspired By: Mike Wolfe (https://nolongerset.com/displaying-time-spans/)
Category: Time
*/
CONVERTTOSECONDS = LAMBDA(years,weeks,days,hours,minutes,seconds,LET(
SecondsPerMinute, 60,
SecondsPerHour, SecondsPerMinute*60,
SecondsPerDay, SecondsPerHour*24,
SecondsPerWeek, SecondsPerDay*7,
SecondsPerYear, SecondsPerDay*365,
TotalSeconds, years*SecondsPerYear+weeks*SecondsPerWeek+days*SecondsPerDay+hours*SecondsPerHour+minutes*SecondsPerMinute+seconds,
TotalSeconds
));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment