From ab78265f0f6bd8745a2e88f39bb61e90cfceffa3 Mon Sep 17 00:00:00 2001 From: Daniel Paiva Date: Wed, 17 Jan 2024 12:11:05 -0300 Subject: [PATCH 1/4] =?UTF-8?q?Adi=C3=A7=C3=A3o=20do=20DateHelper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/helpers/date.helper.ts | 212 +++++++++++++++++++++++++++++++++++++ src/public-api.ts | 1 + 2 files changed, 213 insertions(+) create mode 100644 src/helpers/date.helper.ts diff --git a/src/helpers/date.helper.ts b/src/helpers/date.helper.ts new file mode 100644 index 0000000..5c217ee --- /dev/null +++ b/src/helpers/date.helper.ts @@ -0,0 +1,212 @@ +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 { + + MS_PER_SECOND = 1000 + MS_PER_MINUTE = 60 * this.MS_PER_SECOND + MS_PER_HOUR = 60 * this.MS_PER_MINUTE + MS_PER_DAY = 24 * this.MS_PER_HOUR + 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 { + const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second:'2-digit', timeZone: timezone, timeZoneName: 'shortOffset' } + let tzDate = new Date(date).toLocaleString('en-US', options) + tzDate = tzDate.replace(' ', '') + return new Date(tzDate) + } + + startOfDay(date: Date | string, timezone?: string): Date { + const options: Intl.DateTimeFormatOptions = { day: '2-digit', month: '2-digit', year: 'numeric', timeZone: timezone, timeZoneName: 'short' } + const tzDate = new Date(date).toLocaleString('en-US', options) + return new Date(tzDate) + } + + endOfDay(date: Date | string, timezone?: string): Date { + const startOfDay = this.startOfDay(date, timezone) + startOfDay.setDate(startOfDay.getDate() + 1) + return new Date(startOfDay.getTime() - 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.valueOf() - 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 + } + + 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 => { + 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)) + 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()) + } + +} \ No newline at end of file diff --git a/src/public-api.ts b/src/public-api.ts index 1490f79..5142019 100644 --- a/src/public-api.ts +++ b/src/public-api.ts @@ -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' From 6d365e1bcb1fbaaf3628a1cdcd233083b810ce27 Mon Sep 17 00:00:00 2001 From: Daniel Paiva Date: Wed, 17 Jan 2024 22:44:04 -0300 Subject: [PATCH 2/4] Melhorias datehelper --- src/helpers/date.helper.ts | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/helpers/date.helper.ts b/src/helpers/date.helper.ts index 5c217ee..47da8c8 100644 --- a/src/helpers/date.helper.ts +++ b/src/helpers/date.helper.ts @@ -31,11 +31,11 @@ import { useMemo } from './memo.helper' }) export class DateHelper { - MS_PER_SECOND = 1000 - MS_PER_MINUTE = 60 * this.MS_PER_SECOND - MS_PER_HOUR = 60 * this.MS_PER_MINUTE - MS_PER_DAY = 24 * this.MS_PER_HOUR - MS_PER_WEEK = 7 * this.MS_PER_DAY + 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 @@ -56,22 +56,17 @@ export class DateHelper { * @returns Date offset by timezone */ timezoneDate(date: Date, timezone?: string): Date { - const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second:'2-digit', timeZone: timezone, timeZoneName: 'shortOffset' } - let tzDate = new Date(date).toLocaleString('en-US', options) - tzDate = tzDate.replace(' ', '') - return new Date(tzDate) + return new Date(date.toLocaleString('en-US', { timeZone: timezone })) } - startOfDay(date: Date | string, timezone?: string): Date { - const options: Intl.DateTimeFormatOptions = { day: '2-digit', month: '2-digit', year: 'numeric', timeZone: timezone, timeZoneName: 'short' } - const tzDate = new Date(date).toLocaleString('en-US', options) + 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 | string, timezone?: string): Date { + endOfDay(date: Date, timezone?: string): Date { const startOfDay = this.startOfDay(date, timezone) - startOfDay.setDate(startOfDay.getDate() + 1) - return new Date(startOfDay.getTime() - 1) + return new Date(startOfDay.getTime() + (this.MS_PER_DAY - 1)) } startOfMonth(date: Date, timezone?: string): Date { @@ -82,7 +77,7 @@ export class DateHelper { 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.valueOf() - 1) + return new Date(nextMonth.getTime() - 1) } /** @@ -110,6 +105,7 @@ export class DateHelper { break case 'weeks': unitTime = this.MS_PER_WEEK + break } firstDate = this.timezoneDate(firstDate, timezone) @@ -192,7 +188,8 @@ export class DateHelper { break case 'months': return new Date(date.setMonth(date.getMonth() + value)) - default: + break + default: throw new Error('Invalid unit') } From da6be2ea707837b1a7787951adba9011bc331fd1 Mon Sep 17 00:00:00 2001 From: Daniel Paiva Date: Thu, 18 Jan 2024 12:24:55 -0300 Subject: [PATCH 3/4] =?UTF-8?q?Fix=20identa=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/helpers/date.helper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/date.helper.ts b/src/helpers/date.helper.ts index 47da8c8..291fa37 100644 --- a/src/helpers/date.helper.ts +++ b/src/helpers/date.helper.ts @@ -28,7 +28,7 @@ import { useMemo } from './memo.helper' **/ @Injectable({ providedIn: 'root', - }) +}) export class DateHelper { readonly MS_PER_SECOND = 1000 From 74ad290476df8618014df2cbebccaefbc340cf90 Mon Sep 17 00:00:00 2001 From: Daniel Paiva Date: Thu, 18 Jan 2024 14:41:45 -0300 Subject: [PATCH 4/4] =?UTF-8?q?Update=20vers=C3=A3o=20package.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/package.json b/src/package.json index b497ee9..a09b7ce 100644 --- a/src/package.json +++ b/src/package.json @@ -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", @@ -40,4 +40,4 @@ "esm2022": "esm2022/squidit-ngx-css.mjs", "fesm2022": "fesm2022/squidit-ngx-css.mjs", "typings": "index.d.ts" -} \ No newline at end of file +}