Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created November 15, 2020 13:06
Adjusting Dates By Adding Date / Time Parts In Angular 11.0.0
<div class="result">
<span class="result__content">
{{ formattedDate }}
</span>
</div>
<div class="slider">
<div class="slider__label">
Year
</div>
<input
#yearRef
type="range"
min="-100"
max="100"
[value]="yearDelta"
(input)="( yearDelta = +yearRef.value )"
class="slider__input"
/>
<div class="slider__value">
{{ yearDelta }}
</div>
</div>
<div class="slider">
<div class="slider__label">
Month
</div>
<input
#monthRef
type="range"
min="-100"
max="100"
[value]="monthDelta"
(input)="( monthDelta = +monthRef.value )"
class="slider__input"
/>
<div class="slider__value">
{{ monthDelta }}
</div>
</div>
<div class="slider">
<div class="slider__label">
Day
</div>
<input
#dayRef
type="range"
min="-100"
max="100"
[value]="dayDelta"
(input)="( dayDelta = +dayRef.value )"
class="slider__input"
/>
<div class="slider__value">
{{ dayDelta }}
</div>
</div>
<div class="slider">
<div class="slider__label">
Hour
</div>
<input
#hourRef
type="range"
min="-100"
max="100"
[value]="hourDelta"
(input)="( hourDelta = +hourRef.value )"
class="slider__input"
/>
<div class="slider__value">
{{ hourDelta }}
</div>
</div>
<div class="slider">
<div class="slider__label">
Minute
</div>
<input
#minuteRef
type="range"
min="-100"
max="100"
[value]="minuteDelta"
(input)="( minuteDelta = +minuteRef.value )"
class="slider__input"
/>
<div class="slider__value">
{{ minuteDelta }}
</div>
</div>
<div class="slider">
<div class="slider__label">
Second
</div>
<input
#secondRef
type="range"
min="-100"
max="100"
[value]="secondDelta"
(input)="( secondDelta = +secondRef.value )"
class="slider__input"
/>
<div class="slider__value">
{{ secondDelta }}
</div>
</div>
<div class="slider">
<div class="slider__label">
Millis
</div>
<input
#millisecondRef
type="range"
min="-100"
max="100"
[value]="millisecondDelta"
(input)="( millisecondDelta = +millisecondRef.value )"
class="slider__input"
/>
<div class="slider__value">
{{ millisecondDelta }}
</div>
</div>
// Import the core angular services.
import { Component } from "@angular/core";
// Import the application components and services.
import { DateHelper } from "./date-helper";
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
@Component({
selector: "app-root",
styleUrls: [ "./app.component.less" ],
templateUrl: "./app.component.html"
})
export class AppComponent {
public baseDate: Date;
public dayDelta: number;
public formattedDate: string;
public hourDelta: number;
public millisecondDelta: number;
public minuteDelta: number;
public monthDelta: number;
public secondDelta: number;
public yearDelta: number;
private dateHelper: DateHelper;
private dateMask: string;
// I initialize the app component.
constructor( dateHelper: DateHelper ) {
this.dateHelper = dateHelper;
this.baseDate = new Date();
this.dayDelta = 0;
this.hourDelta = 0;
this.millisecondDelta = 0;
this.minuteDelta = 0;
this.monthDelta = 0;
this.secondDelta = 0;
this.yearDelta = 0;
this.dateMask = "yyyy-MM-dd HH:mm:ss.SSS";
this.formattedDate = "";
}
// ---
// PUBLIC METHODS.
// ---
// I get called on every digest.
// --
// NOTE: Rather than have an explicit function that has to get called every time a
// date-delta is adjusted, we're just going to hook into the digest since we know
// that a new digest will be triggered on every (input) event.
public ngDoCheck() : void {
var result = this.baseDate;
// The .add() function returns a NEW date each time, so we have to keep saving
// and reusing the result of each call.
result = this.dateHelper.add( "year", this.yearDelta, result );
result = this.dateHelper.add( "month", this.monthDelta, result );
result = this.dateHelper.add( "day", this.dayDelta, result );
result = this.dateHelper.add( "hour", this.hourDelta, result );
result = this.dateHelper.add( "minute", this.minuteDelta, result );
result = this.dateHelper.add( "second", this.secondDelta, result );
result = this.dateHelper.add( "millisecond", this.millisecondDelta, result );
this.formattedDate = this.dateHelper.format( result, this.dateMask );
}
}
// Import the core angular services.
import { formatDate as ngFormatDate } from "@angular/common";
import { Inject } from "@angular/core";
import { Injectable } from "@angular/core";
import { LOCALE_ID } from "@angular/core";
// ----------------------------------------------------------------------------------- //
// ----------------------------------------------------------------------------------- //
// CAUTION: Numbers are implicitly assumed to be milliseconds since epoch and strings are
// implicitly assumed to be valid for the Date() constructor.
export type DateInput = Date | number | string;
// The single-character values here are meant to match the mask placeholders used in the
// native formatDate() function.
export type DatePart =
| "y" | "year" // Year
| "M" | "month" // Month
| "d" | "day" // Day
| "h" | "hour" // Hour
| "m" | "minute" // Minute
| "s" | "second" // Second
| "S" | "millisecond" // Fractional second (millisecond)
;
@Injectable({
providedIn: "root"
})
export class DateHelper {
private localID: string;
// I initialize the date-helper with the given localization token.
constructor( @Inject( LOCALE_ID ) localID: string ) {
this.localID = localID;
}
// ---
// PUBLIC METHODS.
// ---
// I add the given date/time delta to the given date. A new date is returned.
public add( part: DatePart, delta: number, input: DateInput ) : Date {
var result = new Date( input );
switch ( part ) {
case "year":
case "y":
result.setFullYear( result.getFullYear() + delta );
break;
case "month":
case "M":
result.setMonth( result.getMonth() + delta );
break;
case "day":
case "d":
result.setDate( result.getDate() + delta );
break;
case "hour":
case "h":
result.setHours( result.getHours() + delta );
break;
case "minute":
case "m":
result.setMinutes( result.getMinutes() + delta );
break;
case "second":
case "s":
result.setSeconds( result.getSeconds() + delta );
break;
case "millisecond":
case "S":
result.setMilliseconds( result.getMilliseconds() + delta );
break;
}
return( result );
}
// I proxy the native formatDate() function with a partial application of the
// LOCALE_ID that is being used in the application.
public format( value: DateInput, mask: string ) : string {
return( ngFormatDate( value, mask, this.localID ) );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment