Skip to content
Open
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
31 changes: 31 additions & 0 deletions lib/DateTimeUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { DateTimeUtils } from './DateTimeUtils';

describe('DateTimeUtils.UTCDateTimeToString', () => {
it('decodes a DDMMYY date with the ACARS 1-12 month convention', () => {
// 15 February 2026, 12:30 UTC. The ACARS string is DDMMYY = "150226".
const out = DateTimeUtils.UTCDateTimeToString('150226', '1230');
expect(out).toContain('Feb');
expect(out).toContain('15');
expect(out).toContain('2026');
});

it('does not roll the month forward when the system date is later than the target month-end', () => {
// Pin "now" to 31 March 2026 — a 31-day month. Encoding DDMMYY = 280226
// (28 Feb 2026) used to roll forward to March because the order of
// setUTC* calls applied "set day=28" to a Date already at the 31st.
jest.useFakeTimers();
jest.setSystemTime(new Date(Date.UTC(2026, 2, 31, 0, 0, 0)));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why we're setting system time. Can you explain?

try {
const out = DateTimeUtils.UTCDateTimeToString('280226', '1230');
expect(out).toContain('Feb');
expect(out).toContain('28');
} finally {
jest.useRealTimers();
}
});

it('handles a six-digit time with seconds', () => {
const out = DateTimeUtils.UTCDateTimeToString('150226', '123045');
expect(out).toContain('12:30:45');
});
});
33 changes: 14 additions & 19 deletions lib/DateTimeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,20 @@ export class DateTimeUtils {
// Expects a six digit date string and a four digit UTC time string
// (DDMMYY) (HHMM)
public static UTCDateTimeToString(dateString: string, timeString: string) {
let utcDate = new Date();
utcDate.setUTCDate(+dateString.substr(0, 2));
utcDate.setUTCMonth(+dateString.substr(2, 2));
if (dateString.length === 6) {
utcDate.setUTCFullYear(2000 + +dateString.substr(4, 2));
}
if (timeString.length === 6) {
utcDate.setUTCHours(
+timeString.substr(0, 2),
+timeString.substr(2, 2),
+timeString.substr(4, 2),
);
} else {
utcDate.setUTCHours(
+timeString.substr(0, 2),
+timeString.substr(2, 2),
0,
);
}
const day = +dateString.substr(0, 2);
// ACARS month is 1-12; JS Date months are 0-11, so subtract one.
const month = +dateString.substr(2, 2) - 1;
const year =
dateString.length === 6
? 2000 + +dateString.substr(4, 2)
: new Date().getUTCFullYear();
const hours = +timeString.substr(0, 2);
const minutes = +timeString.substr(2, 2);
const seconds = timeString.length === 6 ? +timeString.substr(4, 2) : 0;
// Build the date in one call so an incremental setUTC* on a Date that
// was initialised to "now" can't roll the month forward when the
// current real-world day is later than the last day of the target.
const utcDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds));
return utcDate.toUTCString();
}

Expand Down