8 Date Functions You Can Absolutely Write Without a Library
Published: 2024-06-24 03:04:16

Hi everyone, It's Hudy again

Date is one of the most popular object in Javascript that you're supposed to work with in at least one of your projects. And I'm sure that you also implement these function using the `Date` object for some cases:

- compare two dates
- get the last date of month
- convert date to readable version
- ... many more

So in this post, I'd like to share with you 8 date utilities function that I often use to manipulate the Date object in javascript.

## 1. Convert date to a readable version 

If you have a list of activities and you'd like to display a readable version of date (ex: 2 min ago, 10 hours ago, 2 days ago) for straightforward and understandable when an activity happens. 

Then you could try this.

```c
function toReadableDate(date) {
  const AMIN = 60
  const ADAY = AMIN * 24;

  const minutes = calculateMinuteFromNow(date)
  const isFuture = minutes < 0;
  const absMinutes = Math.abs(minutes)
  const r = n => Math.round(n)

  const addAffix = minStr => {
    if (isFuture) return `in ${minStr}`;
    return `${minStr} ago`;
  }

  if (absMinutes < AMIN) {
    return addAffix(`${minutes} minutes`)
  }

  if (absMinutes < ADAY){
    return addAffix(`${r(absMinutes/AMIN)} hours`)
  }

  if (absMinutes === ADAY && !isFuture) {
    return `yesterday`
  }

  if (absMinutes === ADAY && isFuture) {
    return `tomorrow`
  }

  return addAffix(`${r(absMinutes/ADAY)} days`);
}

function calculateMinuteFromNow(date) {
  const d1 = new Date(date);
  const d2 = new Date();
  const diff = d2.getTime() - d1.getTime();

  return Math.round(diff / (1000 * 60)); // minutes
}

// Test
toReadableDate(new Date(2024, 5, 12)) // '11 days ago'
toReadableDate(new Date(2024, 5, 28)) // 'in 5 days'

```

## 2. Get the first/last date of month

The second function that I often used for getting first/last date in month. You can write it easily as follow.

```c
function getFirstDateOfMonth(date) {
  const d = new Date(date)
  d.setDate(1)
  return d
}

function getLastDateOfMonth(date){
  const d1 = new Date(date)

  d1.setMonth(d1.getMonth() + 1)
  d1.setDate(1)
  d1.setHours(-1)

  return d1.getDate()
}

// Test
getFirstDateOfMonth(new Date())
getLastDateOfMonth(new Date()) 

```

## 3. Compare two dates

There are two case occur in this function. First, you'd like to compare date and the second is you'd like to compare exact date and time. 

```c
function compareDate(dateLeft, dateRight) {
  const d1 = new Date(dateLeft)
  const d2 = new Date(dateRight)

  const d1Str = `${d1.getFullYear()}-${d1.getMonth()}-${d1.getDate()}`
  const d2Str = `${d2.getFullYear()}-${d2.getMonth()}-${d2.getDate()}`

  return d1Str === d2Str
}
```

The above version compares dates only by year, month and day. It doesn't consider hours, minutes and seconds. The following will handle comparisions based on the exact date and time.

```c
function compareExactDate(dateLeft, dateRight){
  return new Date(dateLeft).getTime() === new Date(dateRight).getTime()
}
```

## 4. Calculate the duration between two dates

The fourth function will helps you calculate the number of days/hours/minutes between two dates. 

```c

function getDuration(dateLeft, dateRight){
  const DAY = 24
  const HOUR = 60
  const MIN = 60
  const d1 = new Date(dateLeft);
  const d2 = new Date(dateRight);
  const diff = d2.getTime() - d1.getTime();

  return Math.round(diff / (1000 * MIN * HOUR * DAY));
}

// Test
getDuration(new Date(2024, 5, 11) , new Date(2024, 5, 13))

```

The earlier function only returns the number of days. You can custom the formula to return value in hour, minute as you wish.

## 5. Get list of month/day in alphabet or number

Sometimes, you want to get the list of month or day in alphabet for displaying on a select box or calendar.

```c
function getMonthList(){
  const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']

  return months
}

function getDayList() {
  const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] 
  return days
}

function getCompactDayList() {
  return getDayList().map(d => d.slice(0,3))
}

function getCompactMonthList() {
  return getMonthList().map(m => m.slice(0,3))
}

function getMonthOptions(compact) {
  const options = compact ? getCompactMonthList() : getMonthList()
  return options.map((v, i) => ({title: v, id: i}))
}

function getDayOptions(compact) {
  const options = compact ? getCompactDayList() : getDayList()
  return options.map((v, i) => ({title: v, id: i}))
}

```

## 6. Get the first (monday) and last day (saturday) of week

For those unfamiliar with the `Date` object, keep in mind that `Sunday` is assigned `0` and `Saturday` is assigned `6`.

```c
function getFirstDayOfWeek(date) {
  const d = new Date(date)
  const day = d.getDay()
  const currentDate = d.getDate()
    
  d.setDate(currentDate - (day - 1))
  return d;
}

// Test
getFirstDayOfWeek(new Date(2024, 5, 22))

```

```c
function getLastDayOfWeek(date) {
  const d = new Date(date)
  const day = d.getDay()
  const currentDate = d.getDate()

  d.setDate(currentDate + (6 - day))
  return d;
}

// Test
getLastDayOfWeek(new Date(2024, 5, 16))

```

## 7. Get the list of week by a specified date

I often use this function to generate labels for a week's worth of data, which I then use on the x-axis of my visualizations.

```c
function getListOfWeekByDate(date) {
  const day = date.getDay()
  const week = []
  const weekLen = 7

  let i = 0

  while (i < weekLen) {
    const d = new Date(date.getTime())
    const distance = day - i

    d.setDate(d.getDate() - distance)
    week.push(d)
    i++
  }

  return week
}

// Test
getListOfWeekByDate(new Date(2024, 5, 18))
```

## 8. Get all week of month

The last function will return all weeks of month. I ultilize `getLastDateOfMonth`, `getFirstDateOfMonth` and `getListOfWeekByDate` from the above functions to create this function. 


```c
// 1. we generate the first week of month 
// by using `getFirstDateOfMonth` and `getListOfWeekByDate`
function getFirstWeekOfMonth(d) {
  const firstDateOfMonth = getFirstDateOfMonth(d)
  return getListOfWeekByDate(firstDateOfMonth)
}


function getFullWeekOfMonth(d) {
  const weeks = []
  const month = d.getMonth()
  const lastDateInThisMonth = getLastDateOfMonth(d)

  // 1. get the first week
  const firstWeek = getFirstWeekOfMonth(d)

  weeks[0] = firstWeek

  let going = true

  while (going) {
    const lastWeek = weeks[weeks.length - 1]
    // 5.1 until no week found
    if (!lastWeek) {
      going = false
      break
    }

    // 2. get the last date of the last week
    const lastDate = lastWeek[lastWeek.length - 1]
    const ldate = lastDate.getDate()
    const lmonth = lastDate.getMonth()

    // 5.2 or that last date belongs to next month
    if (lmonth > month || ldate === lastDateInThisMonth) {
      going = false
      break
    }

    // 3. increase the last date to 1
    const nextDate = new Date(lastDate.getTime())
    nextDate.setDate(nextDate.getDate() + 1)
 
    // 4. generate the week by a new date
    // then keep going
    const week = getListOfWeekByDate(nextDate)
    weeks.push(week)
  }

  return weeks
}
```

## Conclusion

So, I hope this post provided you some useful things. If you have a better version of the above functions or want to share yours, go ahead, I'd love to learn from you guys. 

Thanks for reading, see you in the next post.