Skip to content

Commit

Permalink
Merge pull request #42 from squidit/Feature/SQ-60975
Browse files Browse the repository at this point in the history
Feature/SQ-60975
  • Loading branch information
danielpcs committed Jan 18, 2024
2 parents 273e6ff + 74ad290 commit 5446c89
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 2 deletions.
209 changes: 209 additions & 0 deletions src/helpers/date.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import { formatDate } from '@angular/common'
import { Injectable } from '@angular/core'
import { useMemo } from './memo.helper'
/**
* An utility service for working with dates in Angular applications.
*
* @example
* // Inject the DateHelper service and use its methods:
* constructor(private dateHelper: DateHelper) { }
*
* // Or instance a new class
* const dateHelper = new DateHelper()
*
* // Format a date
* const formattedDate = dateHelper.format(new Date())
*
* // Get the date with the timezone
* const timezoneDate = dateHelper.timezoneDate(new Date(), 'America/Sao_Paulo')
*
* // Get the start of the day
* const startOfDay = dateHelper.startOfDay(new Date())
*
* // Get the end of the day
* const endOfDay = dateHelper.endOfDay(new Date())
*
* // Get an array with all days of the week localized
* const weekdays = dateHelper.weekdays('pt-BR')
**/
@Injectable({
providedIn: 'root',
})
export class DateHelper {

readonly MS_PER_SECOND = 1000
readonly MS_PER_MINUTE = 60 * this.MS_PER_SECOND
readonly MS_PER_HOUR = 60 * this.MS_PER_MINUTE
readonly MS_PER_DAY = 24 * this.MS_PER_HOUR
readonly MS_PER_WEEK = 7 * this.MS_PER_DAY

/**
* Uses Angular's formatDate to format the date using the provided format and timezone
* @param date
* @param format Defaults to yyyy-MM-ddTHH:mm:ssZZZZZ
* @param timezone Optional timezone
* @see {@link https://angular.io/api/common/formatDate}
* @returns String with the formatted date
*/
format(date: Date, format = 'yyyy-MM-ddTHH:mm:ssZZZZZ', timezone?: string, locale = 'en-US'): string {
return formatDate(date, format, locale, timezone)
}

/**
* Returns the Date offset by timezone
* @param date
* @param timezone
* @returns Date offset by timezone
*/
timezoneDate(date: Date, timezone?: string): Date {
return new Date(date.toLocaleString('en-US', { timeZone: timezone }))
}

startOfDay(date: Date, timezone?: string): Date {
const tzDate = new Date(date.getFullYear(), date.getMonth(), date.getDate()).toLocaleString('en-US', {timeZone: timezone})
return new Date(tzDate)
}

endOfDay(date: Date, timezone?: string): Date {
const startOfDay = this.startOfDay(date, timezone)
return new Date(startOfDay.getTime() + (this.MS_PER_DAY - 1))
}

startOfMonth(date: Date, timezone?: string): Date {
const localeDate = this.startOfDay(date, timezone)
return new Date(localeDate.getFullYear(), localeDate.getMonth(), 1)
}

endOfMonth(date: Date, timezone?: string): Date {
const localeDate = this.startOfDay(date, timezone)
const nextMonth = new Date(localeDate.getFullYear(), localeDate.getMonth() + 1, 1)
return new Date(nextMonth.getTime() - 1)
}

/**
* Returns the difference between two dates in the specified unit
* @param unit : 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks'
* @param firstDate: Date
* @param secondDate: Date
* @param timezone: string
* @returns number
*/
diffDate(unit: 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks', firstDate: Date, secondDate: Date, timezone?: string): number {
let unitTime: number
switch(unit){
case 'seconds':
unitTime = this.MS_PER_SECOND
break
case 'minutes':
unitTime = this.MS_PER_MINUTE
break
case 'hours':
unitTime = this.MS_PER_HOUR
break
case 'days':
unitTime = this.MS_PER_DAY
break
case 'weeks':
unitTime = this.MS_PER_WEEK
break
}

firstDate = this.timezoneDate(firstDate, timezone)
secondDate = this.timezoneDate(secondDate, timezone)
const difference = (firstDate.getTime() - secondDate.getTime()) / unitTime
return Math.round(difference)
}

/**
* Returns an array with all days of the week translated to the locale provided
*
* @param locale: string - Locale
* @returns string[]
*/
weekdays = useMemo((locale = 'en-US'): Array<string> => {
const date = new Date()
const daysOfWeek = []

for (let i = 0; i < 7; i++) {
const day = new Date(date)
day.setDate(date.getDate() - date.getDay() + i)
daysOfWeek.push(day.toLocaleDateString(locale, { weekday: 'long' }))
}
return daysOfWeek
})

/**
* Returns a date with the selected week day
* @param day From 0 to 6, where 0 is Sunday and 6 is Saturday. It can be positive for next weeks or negative for previous weeks
* @param date
* @param timezone
* @returns Date with the day of the week
*/
weekday(day: number, date = new Date(), timezone?: string): Date {
date = this.timezoneDate(date, timezone)
const currentDayOfWeek = date.getDay()
const daysUntilTargetDay = (day - currentDayOfWeek)
date.setDate(date.getDate() + daysUntilTargetDay)
return date
}

/**
* Returns a translated string with the date's day of the week.
*
* @param date {Date}
* @param timezone {String}
* @param locale: string - Locale
* @returns string[]
*/
dayOfTheWeek(date: Date, timezone?: string, locale = 'en-US'){
const tzDate = this.timezoneDate(new Date(date), timezone)
return tzDate.toLocaleDateString(locale, { weekday: 'long' })
}

/**
* Adds the specified units to the date provided
* @param value The amount of units to add
* @param unit The unit to add, it can be 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months'
* @param date The date to add the units
* @param timezone The timezone to add the units
* @returns The new date with the units added
*/
addDate(value: number, unit: 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months', date: Date, timezone?: string): Date {
let unitTime: number
switch(unit){
case 'seconds':
unitTime = this.MS_PER_SECOND
break
case 'minutes':
unitTime = this.MS_PER_MINUTE
break
case 'hours':
unitTime = this.MS_PER_HOUR
break
case 'days':
unitTime = this.MS_PER_DAY
break
case 'weeks':
unitTime = this.MS_PER_WEEK
break
case 'months':
return new Date(date.setMonth(date.getMonth() + value))
break
default:
throw new Error('Invalid unit')
}

const tzDate = this.timezoneDate(date, timezone)
return new Date(tzDate.getTime() + (value * unitTime))
}

/**
* Verifies if the date is valid
* @param date
* @returns true if the date is valid, false otherwise
*/
isDateValid(date: Date): boolean {
return date instanceof Date && !isNaN(date.getTime())
}

}
4 changes: 2 additions & 2 deletions src/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@squidit/ngx-css",
"version": "1.2.27",
"version": "1.2.28",
"peerDependencies": {
"@angular/common": ">=15.0.0",
"@angular/core": ">=15.0.0",
Expand Down Expand Up @@ -40,4 +40,4 @@
"esm2022": "esm2022/squidit-ngx-css.mjs",
"fesm2022": "fesm2022/squidit-ngx-css.mjs",
"typings": "index.d.ts"
}
}
1 change: 1 addition & 0 deletions src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export * from './helpers/toast.helper'
export * from './helpers/validator.helper'
export * from './helpers/sleep.helper'
export * from './helpers/formatTime.helper'
export * from './helpers/date.helper'

export * from './interfaces/option.interface'
export * from './interfaces/step.interface'
Expand Down

0 comments on commit 5446c89

Please sign in to comment.