How to add date/time for yesterday/tomorrow in insert text action?

I"m trying to create keyboard sequences to replicate typing commands in my note-taking app (Obsidian) so I can type /template for example and have it replaced by custom markdown text.

In the markdown text, I'm using three dates- yesterday, today and tomorrow. I see that there's an option to have a custom formatted date for today using (BTT)@dateformat:REPLACE_THIS_WITH_CUSTOM_FORMAT(BTT) I was wondering if it's possible here to somehow do a +1 and -1 to get the other two dates.

1 Like

Replying because I also want to solve this exact use case!

You can use the the predefined action "Transform & Replace Selection With Java Script", then enter something like this (there doesn't need to be any selection for this action to work):

Yesterday:

async (clipboardContentString) => { 
  var yesterday = new Date(new Date().setDate(new Date().getDate()-1));
  return yesterday.toLocaleDateString('en-GB');
}

Tomorrow:

async (clipboardContentString) => { 
  var yesterday = new Date(new Date().setDate(new Date().getDate()+1));
  return yesterday.toLocaleDateString('en-GB');
}

1 Like

Thanks Andreas, really helpful!

Because the toLocaleDateString method converts back to UTC (and also because I wanted some additional info in the string) I ended up creating an (admittedly dirty) way of getting the result I was after.

This case is to create a string for tomorrow's date in YYYYMMDD ddd DD format:

async (clipboardContentString) => {
  var tomorrow = new Date(new Date().setDate(new Date().getDate()+1));
  var dateString;
  var weekday = new Array(7);

  weekday[0] = "Sun";
  weekday[1] = "Mon";
  weekday[2] = "Tue";
  weekday[3] = "Wed";
  weekday[4] = "Thu";
  weekday[5] = "Fri";
  weekday[6] = "Sat";

  dateString = tomorrow.getFullYear() + ('0' + (tomorrow.getMonth()+1)).slice(-2) + ('0' + tomorrow.getDate()).slice(-2) + ' ' + weekday[tomorrow.getDay()] + ' ' + ('0' + tomorrow.getDate()).slice(-2);

return dateString;
}
1 Like

Thanks, that works with a caveat. What is the difference between Transform & Replace Selection with javascript and Run Real Javascript?

I've two actions in my trigger now- the first one is Transform & Replace Selection with javascript to generate the dates and it works fine on its own. The second one is a regular Paste Text which pastes the rest of the template which is static text. However, when I execute the trigger in my markdown file, the dates always paste at the end regardless of the order I set in the actions. Can I do something to fix that?

Thanks for sharing this. I modified it to suit my use too!

As I'm exploring the JS transformer more, it seems more interesting now. I notice that in the Paste Text action, there's an option to use an existing transformer before pasting. If I were to say create a JS transformer that looks for a placeholder like in the text and replaces it with the appropriate date, then can I just use the one Paste Text action? That should in theory solve my issue of the order being messed up and the transformer will be available to be used for more templates later on. Am I understanding how this works correctly?

Yes, but that's a bit clunky right now.

Could you try to add a very small delay between your actions?

I did. The order still remains reversed. Even if I add a delay of 2 seconds, it waits 2 second before pasting anything but the dates always come up after the text.

The order in the trigger is:

  1. transformer (dates)
  2. delay
  3. paste text (static text)

I'll look into that tomorrow. Probably some threading issue :slight_smile:

No worries. I can wait. As a workaround, I can put all the template text in the transformer function only. The only issue is that those text boxes mess up the quotes whenever I modify something near them. I tried turning off "Smart Quotes" but that doesn't persist in those boxes. Anyway, thanks for the prompt reply.

That's weird, the smart quotes option should apply to all text areas on macOS :-/

I have it on globally since I need it in most apps. In certain apps though, I can right click on the text area and disable it from there which overrides for that app. Only in BTT, it fails to retain the setting for some reason.

I'll try another way to force this behavior off - I think it's a weird macOS bug caused by the (admittedly non-standard) way of using these text areas :slight_smile:

1 Like

This works for me using "Transform & Replace Selection With Javascript" - no need to have anything selected.

async (clipboardContentString) => {

const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

let tomorrow = new Date(new Date().setDate(new Date().getDate()+1));

return (tomorrow.getFullYear() +"-"+ ('0' + (tomorrow.getMonth()+1)).slice(-2) +"-"+ ('0' + tomorrow.getDate()).slice(-2) +" "+ days[tomorrow.getDay()])
}

If today's date is "2023-04-21 Friday" then it returns "2023-04-22 Saturday"

2 Likes

Just in case if someone wants to format it in the below way:

Friday, 07/Jun/24 11:48:22 AM

Then for yesterday:

async (clipboardContentString) => {
  var yesterday = new Date(new Date().setDate(new Date().getDate() - 1));

  // Helper function to get AM/PM in uppercase
  function getAmPm(hours) {
    return hours < 12 ? 'AM' : 'PM';
  }

  // Date options
  var dateOptions = {
    weekday: 'long',
    day: '2-digit',
    month: 'short',
    year: '2-digit',
  };

  // Time options
  var timeOptions = {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false, // 24-hour format
  };

  // Format date and time separately
  let formattedDate = yesterday.toLocaleDateString('en-GB', dateOptions);
  let formattedTime = yesterday.toLocaleTimeString('en-GB', timeOptions);

  // Add slashes to the date (e.g., 13/Oct/24)
  formattedDate = formattedDate.replace(/ /g, '/'); // Replace spaces with slashes

  // Get the hour and determine AM or PM
  let hours = yesterday.getHours();
  let amPm = getAmPm(hours);

  // Combine everything with comma and space
  return `${formattedDate}, ${formattedTime} ${amPm}`;
};

And for tomorrow:

async (clipboardContentString) => {
  var tomorrow = new Date(new Date().setDate(new Date().getDate() + 1));

  // Helper function to get AM/PM in uppercase
  function getAmPm(hours) {
    return hours < 12 ? 'AM' : 'PM';
  }

  // Date options
  var dateOptions = {
    weekday: 'long',
    day: '2-digit',
    month: 'short',
    year: '2-digit',
  };

  // Time options
  var timeOptions = {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false, // 24-hour format
  };

  // Format date and time separately
  let formattedDate = tomorrow.toLocaleDateString('en-GB', dateOptions);
  let formattedTime = tomorrow.toLocaleTimeString('en-GB', timeOptions);

  // Add slashes to the date (e.g., 13/Oct/24)
  formattedDate = formattedDate.replace(/ /g, '/'); // Replace spaces with slashes

  // Get the hour and determine AM or PM
  let hours = tomorrow.getHours();
  let amPm = getAmPm(hours);

  // Combine everything with comma and space
  return `${formattedDate}, ${formattedTime} ${amPm}`;
};