Skip to content

Commit

Permalink
Added Timezones
Browse files Browse the repository at this point in the history
  • Loading branch information
timothydodd committed Oct 1, 2023
1 parent a483629 commit 00609bd
Show file tree
Hide file tree
Showing 13 changed files with 1,747 additions and 25 deletions.
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@angular/platform-browser": "^16.1.0",
"@angular/platform-browser-dynamic": "^16.1.0",
"@angular/router": "^16.1.0",
"@ng-select/ng-select": "^11.1.1",
"@stedi/prettier-plugin-jsonata": "^2.0.0",
"bootstrap": "^5.2.3",
"js-yaml": "^4.1.0",
Expand Down Expand Up @@ -55,4 +56,4 @@
"style-loader": "^3.3.3",
"typescript": "~5.1.3"
}
}
}
44 changes: 44 additions & 0 deletions src/app/_services/route.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Routes } from "@angular/router";
import { CJsonYamlComponent } from "../converters/c-json-yaml/c-json-yaml.component";
import { FJsonComponent } from "../formatters/f-json/f-json.component";
import { FSqlComponent } from "../formatters/f-sql/f-sql.component";
import { TimeZonesComponent } from "../time/time-zones/time-zones.component";


export class RouteService{


public static getRoutes()
{
const routes: Routes = [];
for (const c of RouteService.routeCategories)
{
for (const route of c.routes)
{
routes.push({ path: route.url.substring(1), pathMatch: 'full', component: route.component });
}
}
return routes;
}
public static routeCategories = [
{
name: 'Formatters',
routes: [
{ name: 'SQL', url: '/format/sql', component: FSqlComponent },
{ name: 'JSON', url: '/format/json', component: FJsonComponent }
]
},
{
name: 'Converters',
routes: [
{ name: 'Json To Yaml', url: '/convert/json-yaml', component: CJsonYamlComponent },
]
},
{
name: 'Time',
routes: [
{ name: 'Time Zones', url: '/time/zones', component: TimeZonesComponent },
]
}
]
}
8 changes: 2 additions & 6 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CJsonYamlComponent } from './converters/c-json-yaml/c-json-yaml.component';
import { FJsonComponent } from './formatters/f-json/f-json.component';
import { FSqlComponent } from './formatters/f-sql/f-sql.component';
import { RouteService } from './_services/route.service';

const routes: Routes = [{ path: 'format/sql', pathMatch: 'full', component: FSqlComponent },
{ path: 'format/json', pathMatch: 'full', component: FJsonComponent },
{ path: 'convert/json-yaml', pathMatch: 'full', component: CJsonYamlComponent }];
const routes: Routes = [...RouteService.getRoutes()];

@NgModule({
imports: [RouterModule.forRoot(routes)],
Expand Down
14 changes: 11 additions & 3 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgSelectModule } from '@ng-select/ng-select';
import { TimepickerModule } from 'ngx-bootstrap/timepicker';
import { MonacoEditorModule } from 'ngx-monaco-editor-v2';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
Expand All @@ -14,6 +16,7 @@ import { FYamlComponent } from './formatters/f-yaml/f-yaml.component';
import { FormatViewComponent } from './formatters/format-view/format-view.component';
import { MonacoEditorConfig } from './monaco/monaco-global-config';
import { SideBarComponent } from './nav/side-bar/side-bar.component';
import { TimeZonesComponent } from './time/time-zones/time-zones.component';

@NgModule({
declarations: [
Expand All @@ -24,12 +27,17 @@ import { SideBarComponent } from './nav/side-bar/side-bar.component';
FJsonComponent,
FYamlComponent,
CJsonYamlComponent,
ConvertViewComponent
ConvertViewComponent,
TimeZonesComponent,

],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
TimepickerModule.forRoot(),
FormsModule,
NgSelectModule,
MonacoEditorModule.forRoot(new MonacoEditorConfig()),
BrowserAnimationsModule
],
Expand Down
1 change: 1 addition & 0 deletions src/app/nav/side-bar/side-bar.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
padding: 24px;
align-items: flex-end;
border-right: 1px solid black;
box-shadow: inset -10px 0 5px -5px rgba(0, 0, 0, 0.08);
}
}

Expand Down
17 changes: 2 additions & 15 deletions src/app/nav/side-bar/side-bar.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { IsActiveMatchOptions, Router } from '@angular/router';
import { RouteService } from 'src/app/_services/route.service';

@Component({
selector: 'app-side-bar',
Expand All @@ -12,21 +13,7 @@ export class SideBarComponent {
router = inject(Router);
constructor() {

this.categories = [
{
name: 'Formatters',
routes: [
{ name: 'SQL', url: '/format/sql' },
{ name: 'JSON', url: '/format/json' }
]
},
{
name: 'Converters',
routes: [
{ name: 'Json To Yaml', url: '/convert/json-yaml' },
]
}
]
this.categories = RouteService.routeCategories;
}
isRouteActive(url: string) {
return this.router.isActive(url, { paths: 'exact', queryParams: 'exact', fragment: 'ignored', matrixParams: 'ignored' } as IsActiveMatchOptions);
Expand Down
22 changes: 22 additions & 0 deletions src/app/time/time-zones/time-zones.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<h1>Time Zone Conversions</h1>
<timepicker [(ngModel)]="selectedTime"></timepicker>
<div class="flex-row">
<button class="btn btn-secondary" (click)="btnSwitch()">Switch</button>
<div class="flex-column grow gap-24">
<div class="flex-column">
<label for="tzFrom">Time Zone From</label>

<ng-select id="tzFrom" [items]="this.zones" bindLabel="text" [(ngModel)]="currentZone"
(change)="timeZoneChanged()"></ng-select>
</div>
<div class="flex-column">
<label for="tzFrom">Time Zone To</label>
<ng-select [items]="this.zones" bindLabel="text" [(ngModel)]="covertToZone"
(change)="timeZoneChanged()"></ng-select>
</div>
</div>

</div>
<div *ngIf="error()" class="error">{{error()}}</div>

{{currentTime()}}
64 changes: 64 additions & 0 deletions src/app/time/time-zones/time-zones.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
:host {
display: flex;
flex-direction: column;
flex-grow: 1;
gap: 24px;

.split-view {
display: flex;
flex-direction: row;
flex-grow: 1;

.editor-wrap {
display: flex;
flex-direction: column;
flex-grow: 1;

gap: 10px;

.sub-wrap {
border: 1px solid var(--border-color);
position: relative;
flex-grow: 1;
}
}
}



.error {
color: red;
max-height: 50px;
text-overflow: ellipsis;
}



ngx-monaco-editor {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
height: 100%;
}
}

.flex-row {
display: flex;
flex-direction: row;
gap: 24px;
}

.flex-column {
display: flex;
flex-direction: column;
gap: 5px;

&.grow {
flex-grow: 1;
}

&.gap-24 {
gap: 24px;
}
}
21 changes: 21 additions & 0 deletions src/app/time/time-zones/time-zones.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { TimeZonesComponent } from './time-zones.component';

describe('TimeZonesComponent', () => {
let component: TimeZonesComponent;
let fixture: ComponentFixture<TimeZonesComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TimeZonesComponent]
});
fixture = TestBed.createComponent(TimeZonesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
93 changes: 93 additions & 0 deletions src/app/time/time-zones/time-zones.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { HttpClient } from '@angular/common/http';
import { Component, inject, signal } from '@angular/core';

@Component({
selector: 'app-time-zones',
templateUrl: './time-zones.component.html',
styleUrls: ['./time-zones.component.scss']
})
export class TimeZonesComponent {
error = signal<string>('');
currentZone :TimeZone | any;
covertToZone :TimeZone | any;
zones: TimeZone[] = [];
selectedTime = new Date();
currentTime = signal<string>('');
httpClient = inject(HttpClient);

ZoneConversions: ZoneConversion[] = [];
constructor() {
this.loadData();
}
loadData()
{
this.httpClient.get<TimeZone[]>('./assets/json/timezones.json').subscribe((res) => {
this.zones = res;
this.currentZone = this.findZone();
this.covertToZone = this.findUTC();
console.log(new Date().toLocaleDateString(undefined, { day: '2-digit', timeZoneName: 'long' }).substring(4));
this.timeZoneChanged();
});
}
findUTC()
{
return this.zones.find((x: TimeZone) => x.value === 'UTC');
}
findZone() {
const myzone = Intl.DateTimeFormat().resolvedOptions().timeZone;
for(const zone of this.zones)
{
if (zone.utc.find((x: string) => x === myzone))
{
return zone;
}
}
return null;
}
timeZoneChanged() {
if (!this.currentZone)
return;
const time = this.selectedTime;

const hour = time.getHours() - this.currentZone.offset;
const today = new Date();

const ndate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), hour, time.getMinutes(), time.getSeconds());


const lDate = time.toLocaleString("en-US", { timeZone: this.currentZone.utc[0], weekday: "long", year: "numeric", month: "2-digit", day: "numeric" });
const lTime = time.toLocaleTimeString("en-US", { timeZone: this.currentZone.utc[0], hour12: false, hour: 'numeric', minute: '2-digit' });


const tDate = ndate.toLocaleString("en-US", { timeZone: this.currentZone.utc[0], weekday: "long", year: "numeric", month: "2-digit", day: "numeric" });
const tTime = ndate.toLocaleTimeString("en-US", { timeZone: this.currentZone.utc[0], hour12: false, hour: 'numeric', minute: '2-digit' });



this.currentTime.set('From :' + lDate + " "+ lTime + " To: " + tDate + " " + tTime);



}
btnSwitch()
{
const temp = this.currentZone;
this.currentZone = this.covertToZone;
this.covertToZone = temp;
this.timeZoneChanged();
}
}

export interface ZoneConversion{
fromZone: TimeZone | any;
toZone: TimeZone | any;
date: Date;
}
export interface TimeZone {
value: string;
abbr: string;
offset: number;
isdst: boolean;
text: string;
utc: string[];
}
Loading

0 comments on commit 00609bd

Please sign in to comment.