Created
November 15, 2020 13:06
Adjusting Dates By Adding Date / Time Parts In Angular 11.0.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 ); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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