/** */ namespace _zeitbild.frontend.helpers { /** */ var _template_cache : Record = {}; /** * @todo caching */ export async function template_coin( name : string, data : Record ) : Promise { let content : string; if (! (name in _template_cache)) { content = ( ( await lib_plankton.file.read( lib_plankton.string.coin( "templates/{{name}}.html.tpl", { "name": name, } ) ) ) .toString() ); _template_cache[name] = content; } else { content = _template_cache[name]; } return Promise.resolve( lib_plankton.string.coin( content, data ) ); } /** * @todo outsource */ export async function promise_row( members : Array< () => Promise > ) : Promise< Array< type_result > > { let results : Array = []; for await (const member of members) { results.push(await member()); } return Promise.resolve>(results); } /** */ export function date_object_get_week_of_year( date : Date ) : int { let date_ : Date = new Date(date.getTime()); date_.setHours(0, 0, 0, 0); // Thursday in current week decides the year. date_.setDate(date_.getDate() + 3 - (date_.getDay() + 6) % 7); // January 4 is always in week 1. let week1 : Date = new Date(date_.getFullYear(), 0, 4); // Adjust to Thursday in week 1 and count number of weeks from date to week1. return ( 1 + Math.round( ( ((date_.getTime() - week1.getTime()) / 86400000) - 3 + (week1.getDay() + 6) % 7 ) / 7 ) ); } /** * @todo unite with type_datetimeobject? */ export type type_datetime = { timezone_shift : int; date : type_date; time : ( null | type_time ); }; /** * @todo timezone_shift */ function datetime_from_date_object( date : Date, options : { timezone_shift ?: int; } = {} ) : type_datetime { options = Object.assign( { "timezone_shift": 0, }, options ); const date_ : Date = lib_plankton.call.convey( date, [ (x : Date) => x.getTime(), (x : int) => (x + (((options.timezone_shift as int) * (60 * 60)) * 1000)), (x : int) => new Date(x), ] ); const iso_string : string = date_.toISOString(); return { "timezone_shift": (options.timezone_shift as int), "date": { "year": parseInt(iso_string.slice(0, 4)), "month": parseInt(iso_string.slice(5, 7)), "day": parseInt(iso_string.slice(8, 10)), }, "time": { "hour": parseInt(iso_string.slice(11, 13)), "minute": parseInt(iso_string.slice(14, 16)), "second": parseInt(iso_string.slice(17, 19)), }, }; } /** * @todo negative shift? */ function datetime_to_date_object( datetime : type_datetime ) : Date { const iso_string : string = lib_plankton.string.coin( "{{year}}-{{month}}-{{day}}T{{hour}}:{{minute}}:{{second}}.000+{{shift}}", { "year": datetime.date.year.toFixed(0).padStart(4, "0"), "month": datetime.date.month.toFixed(0).padStart(2, "0"), "day": datetime.date.day.toFixed(0).padStart(2, "0"), "hour": ((datetime.time !== null) ? datetime.time.hour : 0).toFixed(0).padStart(2, "0"), "minute": ((datetime.time !== null) ? datetime.time.minute : 0).toFixed(0).padStart(2, "0"), "second": ((datetime.time !== null) ? datetime.time.second : 0).toFixed(0).padStart(2, "0"), "shift": (datetime.timezone_shift.toFixed(0).padStart(2, "0") + ":00"), } ); return (new Date(iso_string)); } /** */ export type type_pit = int; /** */ export function pit_to_date_object( pit : type_pit ) : Date { return (new Date(pit * 1000)); } /** */ function pit_from_date_object( date_object : Date ) : type_pit { return Math.round(date_object.getTime() / 1000); } /** */ export function pit_now( ) : type_pit { return pit_from_date_object(new Date(Date.now())); } /** * @todo timezone */ export function pit_to_datetime( pit : type_pit, options : { timezone_shift ?: int } = {} ) : type_datetime { options = Object.assign( { "timezone_shift": 0, }, options ); const date_object : Date = pit_to_date_object(pit); return datetime_from_date_object( date_object, { "timezone_shift": (options.timezone_shift as int), } ); } /** */ export function pit_from_datetime( datetime : type_datetime ) : type_pit { return lib_plankton.call.convey( datetime, [ datetime_to_date_object, pit_from_date_object, ] ); } /** */ export function pit_is_before( pit : type_pit, reference : type_pit ) : boolean { return (pit < reference); } /** */ function pit_is_after( pit : type_pit, reference : type_pit ) : boolean { return (pit > reference); } /** */ export function pit_is_between( pit : type_pit, reference_left : type_pit, reference_right : type_pit ) : boolean { return ( pit_is_after(pit, reference_left) && pit_is_before(pit, reference_right) ); } /** */ function pit_shift_hour( pit : type_pit, increment : int ) : type_pit { return (pit + (60 * 60 * increment)); } /** */ export function pit_shift_day( pit : type_pit, increment : int ) : type_pit { return (pit + (60 * 60 * 24 * increment)); } /** */ export function pit_shift_week( pit : type_pit, increment : int ) : type_pit { return (pit + (60 * 60 * 24 * 7 * increment)); } /** */ function pit_shift_year( pit : type_pit, increment : int ) : type_pit { return (pit + (60 * 60 * 24 * 365 * increment)); } /** */ function pit_trunc_minute( pit : type_pit ) : type_pit { const datetime_input : type_datetime = pit_to_datetime(pit); const datetime_output : type_datetime = { "timezone_shift": 0, "date": { "year": datetime_input.date.year, "month": datetime_input.date.month, "day": datetime_input.date.day, }, "time": { "hour": ( (datetime_input.time === null) ? 0 : datetime_input.time.hour ), "minute": ( (datetime_input.time === null) ? 0 : datetime_input.time.minute ), "second": 0, }, }; return pit_from_datetime(datetime_output); } /** */ function pit_trunc_hour( pit : type_pit ) : type_pit { const datetime_input : type_datetime = pit_to_datetime(pit); const datetime_output : type_datetime = { "timezone_shift": 0, "date": { "year": datetime_input.date.year, "month": datetime_input.date.month, "day": datetime_input.date.day, }, "time": { "hour": ( (datetime_input.time === null) ? 0 : datetime_input.time.hour ), "minute": 0, "second": 0, }, }; return pit_from_datetime(datetime_output); } /** */ function pit_trunc_day( pit : type_pit ) : type_pit { const datetime_input : type_datetime = pit_to_datetime(pit); const datetime_output : type_datetime = { "timezone_shift": 0, "date": { "year": datetime_input.date.year, "month": datetime_input.date.month, "day": datetime_input.date.day, }, "time": { "hour": 0, "minute": 0, "second": 0, }, }; return pit_from_datetime(datetime_output); } /** */ export function pit_trunc_week( pit : type_pit ) : type_pit { const date_object : Date = pit_to_date_object(pit); return lib_plankton.call.convey( date_object.getDay(), [ (x : int) => ((x === 0) ? 7 : x), (x : int) => (x - 1), (x : int) => pit_shift_day(pit, (-x)), pit_trunc_day ] ); } /** */ function pit_trunc_month( pit : type_pit ) : type_pit { const datetime_input : type_datetime = pit_to_datetime(pit); const datetime_output : type_datetime = { "timezone_shift": 0, "date": { "year": datetime_input.date.year, "month": datetime_input.date.month, "day": 1, }, "time": { "hour": 0, "minute": 0, "second": 0, }, }; return pit_from_datetime(datetime_output); } /** */ function pit_trunc_year( pit : type_pit ) : type_pit { const datetime_input : type_datetime = pit_to_datetime(pit); const datetime_output : type_datetime = { "timezone_shift": 0, "date": { "year": datetime_input.date.year, "month": 1, "day": 1, }, "time": { "hour": 0, "minute": 0, "second": 0, }, }; return pit_from_datetime(datetime_output); } /** * @param year year according to specified timezone shift * @param week week according to specified timezone shift * @return the begin of the week (monday, 00:00) */ export function pit_from_year_and_week( year : int, week : int, options : { timezone_shift ?: int; } = {} ) : type_pit { options = Object.assign( { "timezone_shift": 0, }, options ); return lib_plankton.call.convey( { "timezone_shift": (options.timezone_shift as int), "date": { "year": year, "month": 1, "day": 1, }, "time": { "hour": 0, "minute": 0, "second": 0 } }, [ pit_from_datetime, (x : type_pit) => pit_shift_week(x, (week - 1)), pit_trunc_week, ] ); } /** * @todo timezone */ function ical_datetime_to_own_datetime( ical_datetime : lib_plankton.ical.type_datetime ) : type_datetime { return { "timezone_shift": 0, "date": { "year": ical_datetime.date.year, "month": ical_datetime.date.month, "day": ical_datetime.date.day, }, "time": ( (ical_datetime.time === null) ? null : { "hour": ical_datetime.time.hour, "minute": ical_datetime.time.minute, "second": ical_datetime.time.second, } ) }; } /** * @todo timezone */ export function ical_dt_to_own_datetime( ical_dt: lib_plankton.ical.type_dt ) : type_datetime { return { "timezone_shift": 0, "date": ical_dt.value.date, "time": ( (ical_dt.value.time === null) ? null : { "hour": ical_dt.value.time.hour, "minute": ical_dt.value.time.minute, "second": ical_dt.value.time.second, } ) }; } }