Advertisement
Copchase

bd

Nov 30th, 2022 (edited)
1,096
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Reminder: Nightbot cannot work with inline comments, use block comments only */
  2. const birthdayMonth = 12; /* 1 = January. 12 = December, etc... */
  3. const birthdayDay = 3; /* 1 - 28, 30, 31, etc... */
  4. const timeZone = "America/Chicago"; /* IANA Time Zone name */
  5.  
  6. const secondInMs = 1000;
  7. const minuteInMs = 60 * secondInMs;
  8. const hourInMs = 60 * minuteInMs;
  9. const dayInMs = 24 * hourInMs;
  10.  
  11. /**
  12.  * findTimeZoneOffsetMs returns the timezone offset in milliseconds of the specified time zone
  13.  * @param {string} timeZone
  14.  * @returns {number}
  15.  */
  16. function findTimeZoneOffsetMs(timeZone) {
  17.     const offsetFormat = new Intl.DateTimeFormat("en-US", {
  18.         timeZone: timeZone,
  19.         hourCycle: "h23", /* this prevents Intl from presenting 00:00 as 24:00 */
  20.         month: "numeric",
  21.         day: "numeric",
  22.         year: "numeric",
  23.         hour: "numeric",
  24.         minute: "numeric",
  25.         second: "numeric",
  26.     });
  27.  
  28.     const offsetTimeStr = offsetFormat.format(0);
  29.     const extractRegex = /(\d{1,2})\/(\d{1,2})\/(\d{4}), (\d{2}):(\d{2}):(\d{2})/;
  30.     const offsetFrags = offsetTimeStr.match(extractRegex);
  31.  
  32.     /* this is in milliseconds, months are zero indexed */
  33.     return Date.UTC(offsetFrags[3], offsetFrags[1] - 1, offsetFrags[2], offsetFrags[4], offsetFrags[5], offsetFrags[6]);
  34. }
  35.  
  36. /**
  37.  * findNextBirthday finds the next possible birthday date, represented as a Date object
  38.  * @param {number} month
  39.  * @param {number} day
  40.  * @param {number} offset
  41.  * @returns {Date}
  42.  */
  43. function findNextBirthday(month, day, offset) {
  44.     const birthday = new Date();
  45.     birthday.setUTCDate(1);
  46.     birthday.setUTCMonth(month - 1);
  47.     birthday.setUTCDate(day);
  48.     birthday.setUTCHours(0, 0, 0, 0);
  49.  
  50.     const dayAfterBirthday = new Date(birthday);
  51.     dayAfterBirthday.setUTCHours(24);
  52.  
  53.     const now = new Date();
  54.     now.setUTCMilliseconds(now.getUTCMilliseconds() + offset);
  55.  
  56.     if (dayAfterBirthday <= now) {
  57.         /* this birthday is in the past, increment the year */
  58.         birthday.setUTCFullYear(birthday.getUTCFullYear() + 1);
  59.     }
  60.  
  61.     return birthday;
  62. }
  63.  
  64. /**
  65.  * getMsUntilBirthday returns the milliseconds until the birthday begins
  66.  * @param {Date} birthday
  67.  * @param {number} offset
  68.  * @returns {number}
  69.  */
  70. function getMsUntilBirthday(birthday, offset) {
  71.     const now = new Date();
  72.     now.setUTCMilliseconds(now.getUTCMilliseconds() + offset);
  73.     return now.valueOf() - birthday.valueOf();
  74. }
  75.  
  76. /**
  77.  * buildTimeDiff takes a number in milliseconds and converts it into bigger units of time
  78.  * @param {number} diff
  79.  * @returns {Array}
  80.  */
  81. function buildTimeDiff(diff) {
  82.     if (diff === 0) {
  83.         return "Just started FeelsBirthdayMan ";
  84.     }
  85.  
  86.     const isBirthdayToday = diff > 0;
  87.     /* use absolute value here so i can floor divide without worrying about ceilings for negatives */
  88.     let t = Math.abs(diff);
  89.  
  90.     const days = Math.floor(t / dayInMs);
  91.     t = t % dayInMs;
  92.     const hours = Math.floor(t / hourInMs);
  93.     t = t % hourInMs;
  94.     const minutes = Math.floor(t / minuteInMs);
  95.     t = t % minuteInMs;
  96.     const seconds = Math.floor(t / secondInMs);
  97.  
  98.     return [isBirthdayToday, days, hours, minutes, seconds];
  99. }
  100.  
  101. /**
  102.  * formatTimeDiffFrags presents units of time as a string
  103.  * @param {boolean} isBirthdayToday
  104.  * @param {number} days
  105.  * @param {number} hours
  106.  * @param {number} minutes
  107.  * @param {number} seconds
  108.  * @returns {string}
  109.  */
  110. function formatTimeDiffFrags(isBirthdayToday, days, hours, minutes, seconds) {
  111.     if ((days + hours + minutes + seconds) === 0) {
  112.         return "FeelsBirthdayMan";
  113.     }
  114.  
  115.     const strFrags = [];
  116.  
  117.     /* if the birthday is today, then days should be 0 anyway */
  118.     if (days > 0) {
  119.         strFrags.push(`${days} days`)
  120.     }
  121.     if (hours > 0) {
  122.         strFrags.push(`${isBirthdayToday ? 23 - hours : hours} hours`);
  123.     }
  124.     if (minutes > 0) {
  125.         strFrags.push(`${isBirthdayToday ? 59 - minutes : minutes} minutes`);
  126.     }
  127.     if (seconds > 0) {
  128.         strFrags.push(`${isBirthdayToday ? 59 - seconds : seconds} seconds`);
  129.     }
  130.  
  131.     /* add "and" fragment to the final one to be fancy */
  132.     if (strFrags.length > 1) {
  133.         let lastFrag = strFrags.pop();
  134.         lastFrag = `and ${lastFrag}`;
  135.         strFrags.push(lastFrag);
  136.     }
  137.  
  138.     const prefix = isBirthdayToday ? "Ends in " : "Begins in ";
  139.     const middle = strFrags.length > 2 ? strFrags.join(", ") : strFrags.join(" ");
  140.     const suffix = isBirthdayToday ? " FeelsBirthdayMan " : "";
  141.     return `${prefix}${middle}${suffix}`;
  142. }
  143.  
  144. const timeZoneOffsetMs = findTimeZoneOffsetMs(timeZone);
  145. const nextBirthday = findNextBirthday(birthdayMonth, birthdayDay, timeZoneOffsetMs);
  146. const nextMs = getMsUntilBirthday(nextBirthday, timeZoneOffsetMs);
  147. const [isBirthdayToday, days, hours, minutes, seconds] = buildTimeDiff(nextMs);
  148. formatTimeDiffFrags(isBirthdayToday, days, hours, minutes, seconds);
  149.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement