Format JavaScript dates without using plugins

If you are looking for custom logic to format JavaScript dates without using any libraries or plugins, look no further.

function formatDate(date, format) {
  let result = format;
  const datePartRegex = /YYYY|YY|MM|M|DD|D|HH|H|mm|m|ss|s/g;
  
  return result.replace(
    datePartRegex,
    part => getDatePart(date, part)
  );
}

function getDatePart(date, part) {
  switch (part) {
    case 'YYYY':
      return date.getFullYear();
    case 'YY':
      return date.getFullYear().toString().substr(-2);
    case 'MM':
      return prefixWithZero(date.getMonth() + 1);
    case 'M':
      return date.getMonth() + 1;
    case 'DD':
      return prefixWithZero(date.getDate());
    case 'D':
      return date.getDate();
    case 'HH':
      return prefixWithZero(date.getHours());
    case 'H':
      return date.getHours();
    case 'mm':
      return prefixWithZero(date.getMinutes());
    case 'm':
      return date.getMinutes();
    case 'ss':
      return prefixWithZero(date.getSeconds());
    case 's':
      return date.getSeconds();
    default:
      return part;
  }
}

function prefixWithZero(n) {
  return n < 10 ? '0' + n : n;
}

There are three functions here:

  • formatDate – a main function that you call with JavaScript Date object and format pattern
  • getDatePart – helper function that contain logic for each part of the date format that you need
  • prefixWithZero – helper function used in case number needs to be prefixed with ‘0’ (3 becomes 03, 10 stays 10)

Examples:

const date = new Date('2020/10/07');

console.log(formatDate(date, 'D.M.YYYY. HH:mm'));
// 7.10.2020. 00:00

console.log(formatDate(date, 'YYYY-MM-DD'));
// 2020-10-07

console.log(formatDate(date, "D. M 'YY"));
// 7. 10 '20

console.log(formatDate(date, 'YYYYMMDD'));
// 20201007

Use this function to format date in MySQL datetime format:

formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss');

If you need to extend or modify this logic to add new date parts, you would first modify datePartRegex in formatDate function to look for new pattern elements and then add logic to switch/case in getDatePart to replace this new pattern.

If you need to add logic for presenting the name of the month, check JavaScript toLocaleString function. Short example:

add MMMM to regex and extend switch/case logic with:

...
case 'MMMM':
  return date.toLocaleString('default', { month: 'long' });
...

Hope this helps you with your projects and gets you creative with JavaScript dates.

Limit text to certain length with three dots at the end

This code snippet checks if your text is longer than a certain character number, in which case it will trim it and add three dots at the end.

function limitText(text, length) {
  if (!text || !length || text.length <= length) {
    return text;
  }
  
  const limitted = text.slice(0, length).trim();
  
  return `${limitted}...`;
}

Here are the examples:

console.log(limitText('lorem ipsum', 20));
// "lorem ipsum"

console.log(limitText('lorem ipsum', 5));
// "lorem..."

console.log(limitText('lorem ipsum', 6));
// "lorem..." Trims white space

console.log(limitText('lorem ipsum', 7));
// "lorem i..."

If you do not want to cut words in the middle as in the last example, you can optimize this function like this:

function limitText(text, length) {
  if (!text || !length || text.length <= length) {
    return text;
  }
  
  let limitted = text.slice(0, length).trim();
  const index = limitted.lastIndexOf(' ');
  if (index !== -1) {
    limitted = limitted.slice(0, index);
  }
 
  
  return `${limitted}...`;
}

Example:

console.log(limitText('Lorem ipsum dolor sit amet', 15));
// "Lorem ipsum..."

Optimize trimming string even more? Pay attention to dot and comma and dots at the end of the strings.

function limitText(text, length) {
  if (!text || !length || text.length <= length) {
    return text;
  }
  
  let limitted = text.slice(0, length).trim();
  const index = limitted.lastIndexOf(' ');
  if (index !== -1) {
    limitted = limitted.slice(0, index);
  }
  limitted = limitted.replace(/[.,]*$/g, '');
 
  
  return `${limitted}...`;
}

Example:


console.log(limitText('lorem, ipsum', 8));
// "lorem..."

console.log(limitText('lorem. ipsum', 8));
// "lorem..."

console.log(limitText('lorem... ipsum', 8));
// "lorem..."

How to safely parse JSON value in JavaScript

function parseJSON(rawValue, defaultValue) {
  try {
    return JSON.parse(rawValue) || defaultValue;
  } catch (e) {
    return defaultValue;
  }
}

In order to safely parse and JavaScript JSON value, use try/catch when you parse JSON values because you will get SyntaxError if you try to parse invalid JSON.

Empty string is also an invalid JSON and if you try to parse it, you will get “SyntaxError: Unexpected end of JSON input” message.

Examples:

console.log(parseJSON("{\"x\":1}", {}));
// { x: 1 }

console.log(parseJSON("\"this is the value\"", ''));
// 'This is the value'

console.log(parseJSON('not valid string json', ''));
// ''

console.log(parseJSON('{x: not valid json object}', {}));
// {}

console.log(parseJSON('', ''));
// ''

console.log(parseJSON(''));
// undefined

Have fun!

Check if two JavaScript objects have the same properties and values

This is a method that you can use to check if the properties of one JavaScript object are equal to the properties of another object.

function areObjectsEqual(o1, o2) {
  if (!o1 && !o2) {
    return true;
  }
  if (!o1 || !o2 || Object.keys(o1).length !== Object.keys(o2).length) {
    return false;
  }
  
  return Object.keys(o1).reduce((areEqual, key) => {
    return areEqual && o1[key] === o2[key];
  }, true);
}

Example:

console.log(areObjectsEqual({ x: 1 }, { x: 1 }));
// true

console.log(areObjectsEqual({ x: 1 }, { x: 2 }));
// false

// Params are not in the same order but values are equal
console.log(areObjectsEqual({ x: 1, y: 1 }, { y: 1, x: 1 }));
// true

console.log(areObjectsEqual({ x: 1 }, { x: 1, y: 2 }));
// false

console.log(areObjectsEqual({ x: 1 }, null));
// false

One of alternative ways of checking if two objects have the same properties is:

function areObjectsEqual(o1, o2) {
  return JSON.stringify(o1) === JSON.stringify(o2);
}

But this solution does not work if properties are not in the same order as in the third example.

Get duplicate object fields from collection using Lodash

Lets say we have collection of objects:

var a = [
  {id: 10},
  {id: 20},
  {id: 30},
  {id: 30},
  {id: 20}
];

And if we need to get array with duplicate values of ids from array, one of the ways that we could do that is:


_.filter(
  _.uniq(
    _.map(a, function (item) {
      if (_.filter(a, { id: item.id }).length > 1) {
        return item.id;
      }

      return false;
    })),
  function (value) { return value; });

The result is:

[20, 30]

Organize uploads into Year/Month folder structure

You don’t want all your uploads in one folder? It’s useful to organize them by year and month. Wordrpess, among others, is using this structure for uploads. You can use this PHP code for getting current upload folder path (of current month year) for your upload (and if it doesn’t exists, create it):


function get_upload_folder(){
    $upload_folder = '/uploads/';
    $year_dir = $upload_folder . date("Y");
    $month_dir = $year_dir."/".date("m");
    if ( !is_dir( $year_dir ) ) {
       make_upload_folder( $year_dir );
    }
    if ( !is_dir( $month_dir ) ) {
       make_upload_folder( $month_dir );
    }

    return $month_dir;
}

function make_upload_folder( $dir_name ){
    $oldumask = umask(0);
    mkdir( $dir_name, 0777 ); // read more about this bellow
    umask($oldumask);
}

If you uploading file in February of year 2014, function get_upload_folder will return path : /uploads/2014/02 (and create folders if needed).

Additional info

$upload_folder = '/uploads/'; This is path to your upload folder (You should change this value if needed)
date("Y") Returns four digit representation of current year
date("m") Returns numeric representation of month, with leading zeros (01, 02, 03…)
is_dir() Checks if directory already exists
mkdir( $dir_name, 0777 ) Here you should pay attention to second argument. “0777” might get you some security issues. You may consider to use other value there. You can find some tutorials on file permissions (WordPress article for example). More info on mkdir function you can find here.

Generate WordPress random unique username

If you are making some kind of custom WordPress registration and don’t want users to choose their own names, or for whatever reason you need to generate unique username under wordpress, here is the solution:


function get_random_unique_username( $prefix = '' ){
    $user_exists = 1;
    do {
       $rnd_str = sprintf("%06d", mt_rand(1, 999999));
       $user_exists = username_exists( $prefix . $rnd_str );
   } while( $user_exists > 0 );
   return $prefix . $rnd_str;
}

This function will generate username with prefix that you want followed by six digit number.
You can use this function like this


get_random_unique_username( "user_" );

and you’ll get something like user_231246.

Get wordpress featured image using post ID


function featured_image_by_id( $post_id ){
    return wp_get_attachment_url( get_post_thumbnail_id( $post_id ) );
}

$post_id – ID of post
get_post_thumbnail_id() – returns ID of post’s featured image

You can use this function in code like this :


<img src="<?php echo featured_image_by_id( $post->ID ); ?>">

or if you are in loop maybe someting like this


<img src="<?php echo featured_image_by_id( get_the_ID() ); ?>">

If you need to specify format of image use this function:


function featured_image_by_id( $post_id, $size = 'thumbnail' ){
    $src = wp_get_attachment_image_src( get_post_thumbnail_id( $post_id ), $size );
    return $src[0];
}

Here you don’t have to set second paramether – “Thumbnail” format will be default. You can also use:

  • thumbnail,
  • medium,
  • large,
  • full or
  • 2-item array representing width and height in pixels, e.g. array(32,32)

You can find more info on this function on codex page for function wp_get_attachment_image_src