BigDate Formatter -- Update to Date instead of DateTime

Hi,

I want to use the bigDate formatter, but my date field is just date, not dateTime. Any suggestions on how to modify the existing formatter to make this work?

Thanks,
Liz

Hi Liz! You can do this by forking the big date formatter.

  1. Fork static/js/formatters-custom.js
  2. Paste the following in this forked file. This is copied from the static/js/formatters-internal.js file with a few modifications, mostly to accomondate the fact that the standard date field type doesn’t include a specific time.
export function bigDate(profile, keyPath = 'time.start') {
  const dateString = _getProfileFieldAtKeyPath(profile, keyPath);
  if (!dateString) {
    return null;
  }
  const updateDateString = dateString + "T00:00"; //this puts the date field in the right format

  const date = betterTime(updateDateString); //pass this updatedDateString instead of just the dateString
  const locale = _getDocumentLocale();
  const time = date.toLocaleString(locale, {
    hour: 'numeric',
    minute: 'numeric',
    hour12: true,
  });

  return {
    day: date.getDate(),
    month: date.toLocaleString(locale, { month: 'long' }),
    time: time,
  };
}

//adding the following to support the above override of the bigDate formatter
export function _getProfileFieldAtKeyPath(profile, keypath) {
  const paths = keypath.split('.');

  if (!paths.length) {
    console.error('invalid key path', keypath);
    return null;
  }

  return paths.reduce((haystack, needleKey) => {
    if (!haystack) {
      console.log('haystack was null or undefined', haystack, needleKey, idx);
      return null;
    }
    const needle = haystack[needleKey];
    if (!needle) {
      console.log('could not find ' + needleKey, haystack);
      return null;
    }

    return needle;
  }, profile);
}

export function _getDocumentLocale() {
  return document.documentElement.lang.replace('_', '-');
}

export function betterTime(stamp) {
  const offset = new Date(stamp).getTimezoneOffset() / 60;
  const offsetStr = (offset < 0 ? '+0' : '-0') + Math.abs(offset) + ':00';
  return new Date(stamp + offsetStr);
}
  1. Finally, pass this formatter your date field. You can either:
    a. Fork the events-standard card, and in the dataForRender, specify your custom field in the call to the formatter date: Formatter.bigDate(profile, "c_myCustomDateField"), .
    b. Hardcode the field into the formatter we specified above, like so: export function bigDate(profile, keyPath = 'c_myCustomDateField').

If you expect to use this formatter with other date fields, I’d recommend the former. You could also throw a comment in there explaining you made changes to the formatter, in case anyone else maintains this repo down the line. However, ultimately up to you and how you’d like to organize the repo!

Let us know how it goes,
Rose

1 Like

I made an update to this to support dates both with and without times and I thought I’d share:

export function bigDate(profile, keyPath = 'time.start') {
  const dateString = _getProfileFieldAtKeyPath(profile, keyPath);
  if (!dateString) {
    return null;
  }

  let updateDateString;
  if (dateString.includes('T')) {
    updateDateString = dateString;
  } else {
    updateDateString = dateString + "T00:00";
  }

  const date = betterTime(updateDateString); //pass this updatedDateString instead of just the dateString
  const locale = _getDocumentLocale();
  const time = date.toLocaleString(locale, {
    hour: 'numeric',
    minute: 'numeric',
    hour12: true,
  });

  return {
    day: date.getDate(),
    month: date.toLocaleString(locale, { month: 'long' }),
    year: date.getFullYear(),
    time: time
  };
}

//adding the following to support the above override of the bigDate formatter
export function _getProfileFieldAtKeyPath(profile, keypath) {
  const paths = keypath.split('.');

  if (!paths.length) {
    console.error('invalid key path', keypath);
    return null;
  }

  return paths.reduce((haystack, needleKey) => {
    if (!haystack) {
      console.log('haystack was null or undefined', haystack, needleKey, idx);
      return null;
    }
    const needle = haystack[needleKey];
    if (!needle) {
      console.log('could not find ' + needleKey, haystack);
      return null;
    }

    return needle;
  }, profile);
}

export function _getDocumentLocale() {
  return document.documentElement.lang.replace('_', '-');
}

export function betterTime(stamp) {
  const offset = new Date(stamp).getTimezoneOffset() / 60;
  const offsetStr = (offset < 0 ? '+0' : '-0') + Math.abs(offset) + ':00';
  return new Date(stamp + offsetStr);
}

Sorry the posted code snippet was incorrect, instead use

export function betterTime(stamp) {
  const offset = new Date(stamp).getTimezoneOffset() / 60;
  const offsetMinute = new Date(stamp).getTimezoneOffset() % 60;
  let offsetMinuteString = `${Math.abs(offsetMinute)}`;
  if (offsetMinuteString.length === 1) { offsetMinuteString = `0${offsetMinuteString}`};
  const offsetStr = (offset < 0 ? '+0' : '-0') + Math.floor(Math.abs(offset)) + ':' + offsetMinuteString;
  return new Date(stamp + offsetStr);
}
1 Like