Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date Format Pipe/Service will be more accurate + adjusted unit tests. #11

Merged
merged 1 commit into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ describe("DateFormatPipe", () => {
expect(formattedDate).toBe("4 days and 0 hours ago");
});

it("should transform date to 2 months and 3 days ago", () => {
it("should transform date to 2 months and 2 days ago", () => {
const currentDate = moment();
const date = currentDate
.clone()
.subtract(2, "months")
.subtract(2, "days"); // This is intended
const formattedDate = pipe.transform(date.toDate());
expect(formattedDate).toBe("2 months and 3 days ago");
expect(formattedDate).toBe("2 months and 2 days ago");
});

it("should transform date to 4 years and 6 months ago", () => {
Expand Down Expand Up @@ -92,12 +92,18 @@ describe("DateFormatPipe", () => {
const currentDate = moment();
const date = currentDate.clone().subtract(1, "day").subtract(1, "hour");
const formattedDate = pipe.transform(date.toDate());

expect(formattedDate).toBe("1 day and 1 hour ago");
});

it("should transform date to 1 month and 1 day ago", () => {
const currentDate = moment();
const date = currentDate.clone().subtract(31, "day");
const date = currentDate.clone().subtract(1, "month");

if (date.daysInMonth() === 30) {
date.subtract(1, "day");
}

const formattedDate = pipe.transform(date.toDate());
expect(formattedDate).toBe("1 month and 1 day ago");
});
Expand All @@ -112,6 +118,27 @@ describe("DateFormatPipe", () => {
expect(formattedDate).toBe("1 year and 1 month ago");
});

it("should return just now, if just few miliseconds passes", () => {
const currentDate = moment();
const date = currentDate.clone().subtract(1, "millisecond");
const formattedDate = pipe.transform(date.toDate());
expect(formattedDate).toBe("Just now");
});

it("should return just now, if time is in the future", () => {
const currentDate = moment();
const date = currentDate.clone().add(1, "millisecond");
const formattedDate = pipe.transform(date.toDate());
expect(formattedDate).toBe("Just now");
});

it("should return 1 years and months ago", () => {
const currentDate = moment();
const date = currentDate.clone().subtract(1, "year");
const formattedDate = pipe.transform(date.toDate());
expect(formattedDate).toBe("1 year and 0 months ago");
});

it("should update the view every second", fakeAsync(() => {
const currentDate = moment();
const date = currentDate.clone().subtract(10, "seconds");
Expand Down Expand Up @@ -149,6 +176,4 @@ describe("DateFormatPipe", () => {

expect(spyComplete).toHaveBeenCalled();
});

// Add more test cases for the remaining scenarios
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,49 +15,58 @@ export class DateFormatPipe implements PipeTransform {
const date = moment.tz(dateStr, timezone);
const now = moment.tz(timezone);

const diff = now.diff(date, "milliseconds", true);

const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const months = Math.floor(days / 30);
const years = Math.floor(months / 12);

if (seconds < 60) {
return `${seconds} second${seconds === 1 ? "" : "s"} ago`;
} else if (minutes < 60) {
const remainingSeconds = seconds % 60;
return `${minutes} minute${
minutes === 1 ? "" : "s"
} and ${remainingSeconds} second${
remainingSeconds === 1 ? "" : "s"
} ago`;
} else if (hours < 24) {
const remainingMinutes = minutes % 60;
return `${hours} hour${
hours === 1 ? "" : "s"
} and ${remainingMinutes} minute${
remainingMinutes === 1 ? "" : "s"
} ago`;
} else if (days < 30) {
const remainingHours = hours % 24;
return `${days} day${
days === 1 ? "" : "s"
} and ${remainingHours} hour${remainingHours === 1 ? "" : "s"} ago`;
} else if (months < 12) {
const remainingDays = days % 30;
return `${months} month${
months === 1 ? "" : "s"
} and ${remainingDays} day${remainingDays === 1 ? "" : "s"} ago`;
} else {
const remainingMonths = months % 12;
return `${years} year${
years === 1 ? "" : "s"
} and ${remainingMonths} month${
remainingMonths === 1 ? "" : "s"
} ago`;
const duration = moment.duration(now.diff(date));
const milliseconds = duration.asMilliseconds();

// Handle negative durations (future dates)
if (milliseconds < 0) {
return "Just now";
}

const units: (
| "years"
| "months"
| "days"
| "hours"
| "minutes"
| "seconds"
)[] = ["years", "months", "days", "hours", "minutes", "seconds"];

for (let i = 0; i < units.length; i++) {
const unit = units[i];
const diff = now.diff(date, unit);
if (diff > 0) {
const diffLabel = diff === 1 ? unit.slice(0, -1) : unit;
const nextUnit = units[i + 1];

const durationNumber = duration.as(unit);

if (i < 5) {
let remainingInUnitFloored: number =
duration.as(unit) - Math.floor(duration.as(unit));

if (remainingInUnitFloored === durationNumber) {
remainingInUnitFloored = 0;
}

const remainingInUnit = Math.round(
moment
.duration(remainingInUnitFloored, unit)
.as(nextUnit)
);

const remainingLabel =
remainingInUnit === 1
? nextUnit.slice(0, -1)
: nextUnit;

return `${diff} ${diffLabel} and ${remainingInUnit} ${remainingLabel} ago`;
}

return `${diff} ${diffLabel} ago`;
}
}
return `Just now`;
}

toggleShouldUpdateView() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { TestBed } from "@angular/core/testing";

import { DateService } from "./date.service";

import * as moment from "moment";

describe("DateService", () => {
let service: DateService;

Expand Down Expand Up @@ -75,21 +77,31 @@ describe("DateService", () => {

it("should return months and days ago", () => {
const date = new Date();
date.setMonth(date.getMonth() - 6); // 4 months ago
date.setMonth(date.getMonth() - 4); // 4 months ago

const formattedDate = service.format(date);
expect(formattedDate).toBe("6 months and 0 days ago");
expect(formattedDate).toBe("4 months and 0 days ago");
});

it("should return 1 month and 1 day ago", () => {
const date = new Date();
date.setDate(date.getDate() - 31);
date.setMonth(date.getMonth() - 1);

if (getDaysInMonth(date.getFullYear(), date.getMonth() - 1) === 31) {
date.setDate(date.getDate());
} else {
date.setDate(date.getDate() - 1);
}

const formattedDate = service.format(date);
expect(formattedDate).toBe("1 month and 1 day ago");
});

it("should return 1 years and months ago", () => {
const date = new Date();

date.setFullYear(date.getFullYear() - 1); // 1 year ago

const formattedDate = service.format(date);
expect(formattedDate).toBe("1 year and 0 months ago");
});
Expand All @@ -101,4 +113,22 @@ describe("DateService", () => {
const formattedDate = service.format(date);
expect(formattedDate).toBe("2 years and 1 month ago");
});

it("should return just now, if just few miliseconds passes", () => {
const date = new Date();
date.setMilliseconds(date.getMilliseconds() - 1); // 2 years ago
const formattedDate = service.format(date);
expect(formattedDate).toBe("Just now");
});

it("should return just now, if time is in the future", () => {
const date = new Date();
date.setSeconds(date.getSeconds() + 1); // 2 years ago
const formattedDate = service.format(date);
expect(formattedDate).toBe("Just now");
});

function getDaysInMonth(year: number, month: number) {
return new Date(year, month, 0).getDate();
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,59 @@ export class DateService {
const date = moment.tz(dateStr, timezone);
const now = moment.tz(timezone);

const diff = now.diff(date, "milliseconds", true);

const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const months = Math.floor(days / 30);
const years = Math.floor(months / 12);

if (seconds < 60) {
return `${seconds} second${seconds === 1 ? "" : "s"} ago`;
} else if (minutes < 60) {
const remainingSeconds = seconds % 60;
return `${minutes} minute${
minutes === 1 ? "" : "s"
} and ${remainingSeconds} second${
remainingSeconds === 1 ? "" : "s"
} ago`;
} else if (hours < 24) {
const remainingMinutes = minutes % 60;
return `${hours} hour${
hours === 1 ? "" : "s"
} and ${remainingMinutes} minute${
remainingMinutes === 1 ? "" : "s"
} ago`;
} else if (days < 30) {
const remainingHours = hours % 24;
return `${days} day${
days === 1 ? "" : "s"
} and ${remainingHours} hour${remainingHours === 1 ? "" : "s"} ago`;
} else if (months < 12) {
const remainingDays = days % 30;
return `${months} month${
months === 1 ? "" : "s"
} and ${remainingDays} day${remainingDays === 1 ? "" : "s"} ago`;
} else {
const remainingMonths = months % 12;
return `${years} year${
years === 1 ? "" : "s"
} and ${remainingMonths} month${
remainingMonths === 1 ? "" : "s"
} ago`;
const duration = moment.duration(now.diff(date));
const milliseconds = duration.asMilliseconds();

// Handle negative durations (future dates)
if (milliseconds < 0) {
return "Just now";
}

const units: (
| "years"
| "months"
| "days"
| "hours"
| "minutes"
| "seconds"
)[] = ["years", "months", "days", "hours", "minutes", "seconds"];

for (let i = 0; i < units.length; i++) {
const unit = units[i];
const diff = now.diff(date, unit);
if (diff > 0) {
const diffLabel = diff === 1 ? unit.slice(0, -1) : unit;
const nextUnit = units[i + 1];

const durationNumber = duration.as(unit);

if (i < 5) {
let remainingInUnitFloored: number =
duration.as(unit) - Math.floor(duration.as(unit));

if (remainingInUnitFloored === durationNumber) {
console.log("test: " + dateStr);
console.log("test: " + now.toDate());
remainingInUnitFloored = 0;
}

const remainingInUnit = Math.round(
moment
.duration(remainingInUnitFloored, unit)
.as(nextUnit)
);

const remainingLabel =
remainingInUnit === 1
? nextUnit.slice(0, -1)
: nextUnit;

return `${diff} ${diffLabel} and ${remainingInUnit} ${remainingLabel} ago`;
}

return `${diff} ${diffLabel} ago`;
}
}
return `Just now`;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,14 @@ describe("ThemeService", () => {
"(prefers-color-scheme: dark)"
);
}));

it("should get theme-light, when it is set correctly", fakeAsync(() => {
service.setTheme("theme-light");
expect(service.getTheme()).toBe("theme-light");
}));

it("should get theme-dark, when it is set correctly", fakeAsync(() => {
service.setTheme("theme-dark");
expect(service.getTheme()).toBe("theme-dark");
}));
});
Loading